Editor helper for drawing barrier poles and hanging strands. Provides Pole to revolve a pole mesh from bottom to top and Strands to create multiple hanging wire strands along a bay shape, skipping broken strands via noise.
using System;
using System.Collections.Generic;
using Sandbox;
namespace Sunless.Architecture;
// Poles and the lines slung between them. The sag belongs to the bay's own resolve and is never re-derived
// here, so the drag preview and the built strand are the same curve.
public static class ArchBarrierCatenary
{
const int PoleSides = 8;
// The conductors hang on the head of the pole, so one height sets both the pole and where the lines sit.
const float HeadBand = 0.25f;
public static void Pole( ArchMesh canvas, ArchBarrierPost post, ArchBarrierSpec spec, ArchBarrierBrushes brushes, float bottom, float top )
{
var radius = MathF.Max( 1.5f, spec.PostSize ) * 0.5f;
var rise = top - bottom;
if ( rise < 1f )
{
return;
}
canvas.Revolve( new Vector3( post.Flat.x, post.Flat.y, bottom ), new List<Vector2>
{
new( radius, 0f ),
new( radius * 0.78f, rise )
}, PoleSides, 1f, 1f, brushes.Post );
}
public static void Strands( ArchMesh canvas, ArchBarrierBayShape bay, ArchBarrierSpec spec, ArchKit kit, ArchBarrierBrushes brushes )
{
var strands = Math.Clamp( spec.Strands, 1, 12 );
var half = ArchBarrierShape.WireHalf( kit );
var band = ArchDivide.Into( MathF.Max( 1f, spec.Height * HeadBand ), strands );
for ( var strand = 0; strand < strands; strand++ )
{
if ( bay.Missing && ArchBarrierShape.Noise( spec.Seed, bay.Index * 31 + strand, 97 ) < spec.Broken )
{
continue;
}
var hang = spec.Height - band.At( strand );
var path = bay.Strand( bay.SeatFrom + hang, bay.SeatTo + hang );
for ( var chord = 0; chord < path.Count - 1; chord++ )
{
canvas.Strut( path[chord], path[chord + 1], half, brushes.Wire );
}
}
}
}