An editor stamp tool that builds traffic sign meshes from a box panel on one or two cylinders. Exposes shape, post and panel size properties, and writes the geometry into the MeshKit in Stamp.
namespace AdvancedMappingTools;
public enum SignShape
{
Square,
[Title( "Wide" )] Wide,
[Title( "Tall" )] Tall
}
/// <summary>
/// A traffic sign on one or two posts. The panel is a plain box: paint it with a sign material.
/// </summary>
[ToolCategory( "Street" )]
[Title( "Traffic Sign" ), Icon( "signpost" )]
public sealed class TrafficSignEditor( PrimitiveTool tool ) : StampEditor( tool )
{
[Property, Group( "Sign" ), WideMode]
public SignShape Shape { get; set; } = SignShape.Square;
[Property, Group( "Sign" ), Title( "Post Height" ), Range( 8, 1024, slider: false ), WideMode]
public float PostHeight { get; set; } = 96.0f;
[Property, Group( "Sign" ), Range( 1, 16, slider: false ), WideMode]
public float PostRadius { get; set; } = 2.0f;
[Property, Group( "Sign" ), Title( "Panel Width" ), Range( 4, 512, slider: false ), WideMode]
public float PanelWidth { get; set; } = 48.0f;
[Property, Group( "Sign" ), Title( "Panel Height" ), Range( 4, 512, slider: false ), WideMode]
public float PanelHeight { get; set; } = 48.0f;
[Property, Group( "Sign" ), Title( "Panel Thickness" ), Range( 0.5f, 16, slider: false ), WideMode]
public float PanelThickness { get; set; } = 2.0f;
[Property, Group( "Sign" ), Title( "Two Posts" ), WideMode]
public bool TwoPosts { get; set; } = false;
protected override void Stamp( MeshKit kit, Transform frame, Random random )
{
var height = MathF.Max( PostHeight, 8.0f );
var r = Math.Clamp( PostRadius, 1.0f, 16.0f );
var w = MathF.Max( PanelWidth, 4.0f );
var h = MathF.Max( PanelHeight, 4.0f );
var t = MathF.Max( PanelThickness, 0.5f );
if ( Shape == SignShape.Wide ) w = MathF.Max( w, h * 1.6f );
if ( Shape == SignShape.Tall ) h = MathF.Max( h, w * 1.4f );
if ( TwoPosts ) w = MathF.Max( w, 64.0f );
var half = TwoPosts ? w * 0.35f : 0.0f;
kit.Cylinder( new Vector3( -half, 0.0f, 0.0f ), r, r, 0.0f, height, 10 );
if ( TwoPosts ) kit.Cylinder( new Vector3( half, 0.0f, 0.0f ), r, r, 0.0f, height, 10 );
kit.Material = TrimMaterial;
kit.Box( new Vector3( -w * 0.5f, -t * 0.5f, height - h * 0.5f ), new Vector3( w * 0.5f, t * 0.5f, height + h * 0.5f ) );
}
}