Editor/InteriorLayoutBuilder/RoomLayoutGeometryBuilder.CorridorCorners.cs
using System;
using System.Collections.Generic;
using Sandbox;
namespace ReusableRoomLayout;
public sealed partial class RoomLayoutGeometryBuilder
{
private static void BuildCorridorBoundaryCorners(
ICollection<RoomLayoutSolidSlab> solidSlabs,
RoomLayoutSettings settings,
int corridorId,
int firstCornerIndex,
bool[,] cells,
IReadOnlyList<float> xs,
IReadOnlyList<float> ys,
DoorPoint start,
DoorPoint end,
float width,
string outerWallMaterialPath,
string innerWallMaterialPath,
string capMaterialPath,
string baseboardMaterialPath,
float outerWallMaterialScale,
float innerWallMaterialScale,
float capMaterialScale,
float baseboardMaterialScale )
{
var cornerIndex = firstCornerIndex;
var baseboardInset = settings.BaseboardDepth * 0.5f - TrimEmbedForDepth( settings.BaseboardDepth );
for ( var x = 0; x < xs.Count; x++ )
{
for ( var y = 0; y < ys.Count; y++ )
{
var sw = IsCorridorCellCovered( cells, x - 1, y - 1 );
var se = IsCorridorCellCovered( cells, x, y - 1 );
var nw = IsCorridorCellCovered( cells, x - 1, y );
var ne = IsCorridorCellCovered( cells, x, y );
var count = (sw ? 1 : 0) + (se ? 1 : 0) + (nw ? 1 : 0) + (ne ? 1 : 0);
if ( count != 1 )
{
continue;
}
var point = new Vector2( xs[x], ys[y] );
if ( IsCorridorDoorOpeningCorner( point, start, width ) ||
IsCorridorDoorOpeningCorner( point, end, width ) )
{
continue;
}
var offsetX = sw || nw ? 1.0f : -1.0f;
var offsetY = sw || se ? 1.0f : -1.0f;
var northInner = nw || ne;
var southInner = sw || se;
var eastInner = se || ne;
var westInner = sw || nw;
BuildCorridorBoundaryCorner(
solidSlabs,
settings,
corridorId,
cornerIndex++,
new Vector2(
point.x + offsetX * settings.WallThickness * 0.5f,
point.y + offsetY * settings.WallThickness * 0.5f ),
new Vector2(
point.x - offsetX * baseboardInset,
point.y - offsetY * baseboardInset ),
northInner,
southInner,
eastInner,
westInner,
outerWallMaterialPath,
innerWallMaterialPath,
capMaterialPath,
baseboardMaterialPath,
outerWallMaterialScale,
innerWallMaterialScale,
capMaterialScale,
baseboardMaterialScale );
}
}
}
private static bool IsCorridorDoorOpeningCorner( Vector2 point, DoorPoint door, float width )
{
var halfWidth = width * 0.5f;
if ( MathF.Abs( door.Normal.y ) > MathF.Abs( door.Normal.x ) )
{
return point.y.AlmostEqual( door.Point.y ) &&
point.x >= door.Point.x - halfWidth - 0.5f &&
point.x <= door.Point.x + halfWidth + 0.5f;
}
return point.x.AlmostEqual( door.Point.x ) &&
point.y >= door.Point.y - halfWidth - 0.5f &&
point.y <= door.Point.y + halfWidth + 0.5f;
}
private static void BuildCorridorBoundaryCorner(
ICollection<RoomLayoutSolidSlab> solidSlabs,
RoomLayoutSettings settings,
int corridorId,
int cornerIndex,
Vector2 center,
Vector2 baseboardCenter,
bool northInner,
bool southInner,
bool eastInner,
bool westInner,
string outerWallMaterialPath,
string innerWallMaterialPath,
string capMaterialPath,
string baseboardMaterialPath,
float outerWallMaterialScale,
float innerWallMaterialScale,
float capMaterialScale,
float baseboardMaterialScale )
{
var footprint = new Vector3( settings.WallThickness, settings.WallThickness, settings.WallHeight );
var cap = new Vector3( settings.WallThickness, settings.WallThickness, settings.WallCapHeight );
var name = $"Corridor {corridorId:00} Boundary Corner {cornerIndex:00}";
AddSolidSlab(
solidSlabs,
name,
new Vector3( center.x, center.y, settings.WallHeight * 0.5f ),
footprint,
RoomLayoutSurface.Wall,
materialPath: outerWallMaterialPath,
textureWorldSize: outerWallMaterialScale,
northMaterialPath: northInner ? innerWallMaterialPath : outerWallMaterialPath,
southMaterialPath: southInner ? innerWallMaterialPath : outerWallMaterialPath,
eastMaterialPath: eastInner ? innerWallMaterialPath : outerWallMaterialPath,
westMaterialPath: westInner ? innerWallMaterialPath : outerWallMaterialPath,
northTextureWorldSize: northInner ? innerWallMaterialScale : outerWallMaterialScale,
southTextureWorldSize: southInner ? innerWallMaterialScale : outerWallMaterialScale,
eastTextureWorldSize: eastInner ? innerWallMaterialScale : outerWallMaterialScale,
westTextureWorldSize: westInner ? innerWallMaterialScale : outerWallMaterialScale );
AddSolidSlab(
solidSlabs,
$"{name} Cap",
new Vector3( center.x, center.y, settings.WallHeight + settings.WallCapHeight * 0.5f ),
cap,
RoomLayoutSurface.Cap,
materialPath: capMaterialPath,
textureWorldSize: capMaterialScale );
BuildBaseboardCorner(
solidSlabs,
settings,
$"{name} Baseboard",
baseboardCenter,
baseboardMaterialPath,
baseboardMaterialScale );
}
}