Editor/Barriers/ArchBarrierCatenary.cs
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 );
}
}
}
}