editor/AdvancedMappingTools/Geometry/RoundaboutEditor.cs

An editor tool for AdvancedMappingTools that stamps a roundabout geometry. Draws a circular road plate, a raised curb ring and a flat island using MeshKit cylinders, with radius, island size, road thickness, island height and curb width exposed as properties.

namespace AdvancedMappingTools;

/// <summary>
/// A roundabout: a circular road plate with a raised island and a curb around it.
/// </summary>
[ToolCategory( "Roads & Paths" )]
[Title( "Roundabout" ), Icon( "roundabout_right" )]
public sealed class RoundaboutEditor( PrimitiveTool tool ) : StampEditor( tool )
{
	[Property, Group( "Roundabout" ), Range( 32, 4096, slider: false ), WideMode]
	public float Radius { get; set; } = 256.0f;

	[Property, Group( "Roundabout" ), Title( "Island Radius" ), Range( 8, 2048, slider: false ), WideMode]
	public float IslandRadius { get; set; } = 96.0f;

	[Property, Group( "Roundabout" ), Title( "Road" ), Range( 1, 64, slider: false ), WideMode]
	public float Road { get; set; } = 4.0f;

	[Property, Group( "Roundabout" ), Title( "Island Height" ), Range( 1, 128, slider: false ), WideMode]
	public float IslandHeight { get; set; } = 8.0f;

	[Property, Group( "Roundabout" ), Title( "Curb" ), Range( 0.5f, 32, slider: false ), WideMode]
	public float Curb { get; set; } = 3.0f;

	protected override void Stamp( MeshKit kit, Transform frame, Random random )
	{
		var radius = MathF.Max( Radius, 32.0f );
		var island = Math.Clamp( IslandRadius, 8.0f, radius - 8.0f );
		var road = MathF.Max( Road, 1.0f );
		var height = MathF.Max( IslandHeight, 1.0f );
		var curb = Math.Clamp( Curb, 0.5f, 32.0f );

		kit.Material = SurfaceMaterial;
		kit.Cylinder( Vector3.Zero, radius, radius, 0.0f, road, 32 );

		kit.Material = TrimMaterial;
		kit.Cylinder( Vector3.Zero, island + curb, island + curb, road, road + height, 32 );

		kit.Material = SurfaceMaterial;
		kit.Cylinder( Vector3.Zero, island, island, road + height, road + height + 1.0f, 32 );
	}
}