Editor/InteriorLayoutBuilder/RoomLayoutGeometryBuilder.CorridorBoundaries.cs
using System.Collections.Generic;
using Sandbox;
namespace ReusableRoomLayout;
public sealed partial class RoomLayoutGeometryBuilder
{
private static void BuildCorridorBoundaryWalls(
Scene scene,
GameObject frameParent,
RoomLayoutDocument document,
ICollection<RoomLayoutSolidSlab> solidSlabs,
RoomLayoutSettings settings,
RoomLayoutCorridor corridor,
IReadOnlyList<Vector2> points,
IReadOnlyCollection<RoomLayoutRect> footprintRects,
DoorPoint start,
DoorPoint end,
float width,
string outerWallMaterialPath,
string innerWallMaterialPath,
string capMaterialPath,
string baseboardMaterialPath,
float outerWallMaterialScale,
float innerWallMaterialScale,
float capMaterialScale,
float baseboardMaterialScale )
{
if ( footprintRects.Count == 0 )
{
return;
}
var xs = new List<float>();
var ys = new List<float>();
foreach ( var rect in footprintRects )
{
AddUniqueCoordinate( xs, rect.X );
AddUniqueCoordinate( xs, rect.X + rect.Width );
AddUniqueCoordinate( ys, rect.Y );
AddUniqueCoordinate( ys, rect.Y + rect.Height );
}
xs.Sort();
ys.Sort();
var cells = CorridorFootprintCells( footprintRects, xs, ys );
var wallIndex = 0;
for ( var x = 0; x < xs.Count - 1; x++ )
{
for ( var y = 0; y < ys.Count - 1; y++ )
{
if ( !cells[x, y] )
{
continue;
}
var minX = xs[x];
var maxX = xs[x + 1];
var minY = ys[y];
var maxY = ys[y + 1];
if ( y == 0 || !cells[x, y - 1] )
{
wallIndex = BuildCorridorBoundaryWall(
solidSlabs,
document,
settings,
corridor,
points,
wallIndex,
new CorridorBoundaryEdge( minX, maxX, minY, true, -1 ),
start,
end,
width,
outerWallMaterialPath,
innerWallMaterialPath,
capMaterialPath,
baseboardMaterialPath,
outerWallMaterialScale,
innerWallMaterialScale,
capMaterialScale,
baseboardMaterialScale );
}
if ( y == ys.Count - 2 || !cells[x, y + 1] )
{
wallIndex = BuildCorridorBoundaryWall(
solidSlabs,
document,
settings,
corridor,
points,
wallIndex,
new CorridorBoundaryEdge( minX, maxX, maxY, true, 1 ),
start,
end,
width,
outerWallMaterialPath,
innerWallMaterialPath,
capMaterialPath,
baseboardMaterialPath,
outerWallMaterialScale,
innerWallMaterialScale,
capMaterialScale,
baseboardMaterialScale );
}
if ( x == 0 || !cells[x - 1, y] )
{
wallIndex = BuildCorridorBoundaryWall(
solidSlabs,
document,
settings,
corridor,
points,
wallIndex,
new CorridorBoundaryEdge( minY, maxY, minX, false, -1 ),
start,
end,
width,
outerWallMaterialPath,
innerWallMaterialPath,
capMaterialPath,
baseboardMaterialPath,
outerWallMaterialScale,
innerWallMaterialScale,
capMaterialScale,
baseboardMaterialScale );
}
if ( x == xs.Count - 2 || !cells[x + 1, y] )
{
wallIndex = BuildCorridorBoundaryWall(
solidSlabs,
document,
settings,
corridor,
points,
wallIndex,
new CorridorBoundaryEdge( minY, maxY, maxX, false, 1 ),
start,
end,
width,
outerWallMaterialPath,
innerWallMaterialPath,
capMaterialPath,
baseboardMaterialPath,
outerWallMaterialScale,
innerWallMaterialScale,
capMaterialScale,
baseboardMaterialScale );
}
}
}
BuildCorridorBoundaryCorners(
solidSlabs,
settings,
corridor.Id,
wallIndex,
cells,
xs,
ys,
start,
end,
width,
outerWallMaterialPath,
innerWallMaterialPath,
capMaterialPath,
baseboardMaterialPath,
outerWallMaterialScale,
innerWallMaterialScale,
capMaterialScale,
baseboardMaterialScale );
BuildCorridorOpeningFrames( scene, frameParent, settings, document, corridor, points, width );
}
private static bool[,] CorridorFootprintCells(
IReadOnlyCollection<RoomLayoutRect> footprintRects,
IReadOnlyList<float> xs,
IReadOnlyList<float> ys )
{
var cells = new bool[xs.Count - 1, ys.Count - 1];
for ( var x = 0; x < xs.Count - 1; x++ )
{
for ( var y = 0; y < ys.Count - 1; y++ )
{
var center = new Vector2( (xs[x] + xs[x + 1]) * 0.5f, (ys[y] + ys[y + 1]) * 0.5f );
cells[x, y] = CorridorFootprintContains( footprintRects, center );
}
}
return cells;
}
private static bool CorridorFootprintContains( IReadOnlyCollection<RoomLayoutRect> footprintRects, Vector2 point )
{
foreach ( var rect in footprintRects )
{
if ( point.x >= rect.X && point.x <= rect.X + rect.Width &&
point.y >= rect.Y && point.y <= rect.Y + rect.Height )
{
return true;
}
}
return false;
}
private static bool IsCorridorCellCovered( bool[,] cells, int x, int y )
{
return x >= 0 &&
y >= 0 &&
x < cells.GetLength( 0 ) &&
y < cells.GetLength( 1 ) &&
cells[x, y];
}
}