Editor tool that generates street lighting geometry along a path. Places poles at a set spacing, adds arms and lamp head boxes on one or both sides, and builds the mesh through MeshKit.
namespace AdvancedMappingTools;
/// <summary>
/// A run of street lights along a path: pole, arm and lamp head on one or both sides.
/// </summary>
[ToolCategory( "Street" )]
[Title( "Street Lighting Run" ), Icon( "light" )]
public sealed class StreetLightingEditor( PrimitiveTool tool ) : PathEditor( tool )
{
protected override int MinPoints => 2;
[Property, Group( "Lights" ), Title( "Spacing" ), Range( 16, 2048, slider: false ), WideMode]
public float Spacing { get; set; } = 256.0f;
[Property, Group( "Lights" ), Range( 16, 1024, slider: false ), WideMode]
public float Height { get; set; } = 192.0f;
[Property, Group( "Lights" ), Title( "Pole Radius" ), Range( 1, 24, slider: false ), WideMode]
public float PoleRadius { get; set; } = 4.0f;
[Property, Group( "Lights" ), Title( "Arm" ), Range( 0, 256, slider: false ), WideMode]
public float Arm { get; set; } = 48.0f;
[Property, Group( "Lights" ), Title( "Both Sides" ), WideMode]
public bool BothSides { get; set; } = false;
[Property, Group( "Lights" ), Title( "Lamp Size" ), Range( 4, 64, slider: false ), WideMode]
public float LampSize { get; set; } = 12.0f;
protected override void BuildMesh( MeshKit kit )
{
var path = SamplePath();
if ( path.Count < 2 ) return;
var height = MathF.Max( Height, 16.0f );
var radius = MathF.Max( PoleRadius, 1.0f );
var arm = MathF.Max( Arm, 0.0f );
var lamp = MathF.Max( LampSize, 4.0f );
foreach ( var (position, direction) in WalkPath( path, Closed, MathF.Max( Spacing, 16.0f ) ) )
{
kit.Material = SurfaceMaterial;
kit.Cylinder( position, radius, radius, 0.0f, height, 8 );
var normal = new Vector3( -direction.y, direction.x, 0.0f ).Normal;
var sides = BothSides ? new[] { 1.0f, -1.0f } : new[] { 1.0f };
kit.Material = TrimMaterial;
foreach ( var side in sides )
{
var tip = position + normal * arm * side + Vector3.Up * height;
if ( arm > 0.0f )
kit.Beam( position + Vector3.Up * height, tip, 3.0f, 3.0f );
kit.Box( tip + new Vector3( -lamp * 0.5f, -lamp * 0.5f, -lamp * 0.5f ), tip + new Vector3( lamp * 0.5f, lamp * 0.5f, lamp * 0.2f ) );
}
}
}
}