Editor provider that measures the 2D footprint and vertical extent of an "approach" arch piece. It handles spline and straight approaches, sampling spline frames or computing resolved ramp/foot/wall positions and returns an ArchExtent covering the polygon and height range.
using System;
using System.Collections.Generic;
using Sandbox;
namespace Sunless.Architecture;
public sealed class ArchApproachExtentProvider : IArchExtentProvider
{
public ArchKind Kind => ArchKind.Approach;
// Reads the resolved run: a drive clamped to the verge would otherwise read as overshoot.
public ArchExtent Measure( object payload, ArchExtentContext context )
{
if ( payload is not ArchApproachPart approach || context.Room is null )
{
return new ArchExtent();
}
var room = context.Room;
var building = context.Building;
var kit = context.Kit;
var plan = context.Plan;
if ( approach.IsSpline )
{
var curved = new ArchExtent();
foreach ( var frame in ArchApproachGen.SplineCurve( approach, kit ).Walk( MathF.Max( 8f, kit.GridSize * 0.5f ) ) )
{
var half = MathF.Max( 12f, approach.Width * frame.WidthScale ) * 0.5f;
curved.Add( frame.Side( -half ) );
curved.Add( frame.Side( half ) );
}
return curved.Grown( 8f );
}
var rise = ArchApproachGen.Rise( room, building, kit, plan );
var across = ArchApproachAxes.Across( approach ) * ArchApproachAxes.HalfWidth( approach );
var resolved = ArchApproachGen.Resolved( approach, room, building, kit, plan, out var ramp );
var wall = resolved ? ramp.Wall : approach.Origin;
var foot = resolved
? ramp.Foot
: approach.Origin + ArchApproachAxes.Outward( approach ) * (approach.Run > 1f
? approach.Run
: rise / MathF.Max( 0.02f, kit.StepRise / MathF.Max( 1f, kit.StepGoing ) ));
var extent = new ArchExtent();
extent.Add(
new List<Vector2> { wall + across, foot + across, foot - across, wall - across },
room.BaseHeight - rise - 8f,
room.BaseHeight + 48f );
return extent;
}
}