Editor/InteriorLayoutBuilder/RoomLayoutTool.Corridors.cs
using System;
using System.Linq;
namespace ReusableRoomLayout;
public sealed partial class RoomLayoutTool
{
private RoomLayoutCorridor SelectedCorridor()
{
return selectedCorridorId == 0
? null
: document.Corridors.FirstOrDefault( corridor => corridor.Id == selectedCorridorId );
}
private float CorridorClearWidth( RoomLayoutCorridor corridor )
{
var requested = corridor.Width <= 0.0f
? document.Settings.DefaultCorridorWidth
: corridor.Width;
return CorridorWidthForDoors( corridor.StartDoorId, corridor.EndDoorId, requested );
}
private void SetCorridorWidth( RoomLayoutCorridor corridor, float width )
{
var next = Math.Clamp( width, MathF.Max( 16.0f, document.Settings.WallThickness * 2.0f ), MaxCorridorWidth( corridor ) );
corridor.Width = SnapWidth( next );
ExpandDoorForCorridor( corridor.StartDoorId, corridor.Width );
ExpandDoorForCorridor( corridor.EndDoorId, corridor.Width );
}
private float CorridorWidthForDoors( int startDoorId, int endDoorId )
{
return CorridorWidthForDoors( startDoorId, endDoorId, document.Settings.DefaultCorridorWidth );
}
private float CorridorWidthForDoors( int startDoorId, int endDoorId, float requestedWidth )
{
var width = MathF.Max( 1.0f, requestedWidth );
var startDoor = document.FindDoor( startDoorId );
var endDoor = document.FindDoor( endDoorId );
if ( startDoor is not null && startDoor.Width > 0.0f )
{
width = MathF.Min( width, startDoor.Width );
}
if ( endDoor is not null && endDoor.Width > 0.0f )
{
width = MathF.Min( width, endDoor.Width );
}
return width;
}
private float CorridorWidthStep()
{
return MathF.Max( 8.0f, document.Settings.GridSize * 0.25f );
}
private float SnapWidth( float width )
{
var step = CorridorWidthStep();
return MathF.Round( width / step ) * step;
}
private float MaxCorridorWidth( RoomLayoutCorridor corridor )
{
var maxWidth = 512.0f;
maxWidth = MathF.Min( maxWidth, MaxDoorWidth( corridor.StartDoorId ) );
maxWidth = MathF.Min( maxWidth, MaxDoorWidth( corridor.EndDoorId ) );
return MathF.Max( MathF.Max( 16.0f, document.Settings.WallThickness * 2.0f ), maxWidth );
}
private float MaxDoorWidth( int doorId )
{
var door = document.FindDoor( doorId );
var room = door is null ? null : document.FindRoom( door.RoomId );
if ( door is null || room is null )
{
return 512.0f;
}
return door.Side is RoomLayoutWallSide.North or RoomLayoutWallSide.South
? room.Bounds.Width
: room.Bounds.Height;
}
private void ExpandDoorForCorridor( int doorId, float width )
{
var door = document.FindDoor( doorId );
var room = door is null ? null : document.FindRoom( door.RoomId );
if ( door is null || room is null || door.Width >= width )
{
return;
}
var wallLength = door.Side is RoomLayoutWallSide.North or RoomLayoutWallSide.South
? room.Bounds.Width
: room.Bounds.Height;
var nextWidth = Math.Clamp( width, MathF.Max( 16.0f, document.Settings.WallThickness * 2.0f ), wallLength );
var halfWidth = nextWidth * 0.5f;
door.Width = nextWidth;
door.Offset = Math.Clamp( door.Offset, halfWidth, MathF.Max( halfWidth, wallLength - halfWidth ) );
}
}