using System;
namespace IslaApocalypse.Tools
{
///
/// Shape helpers for the island mask, ported from the reference's
/// Tools/Scripts/IslandFalloff.cs.
///
/// ⚠ ONLY THE PASS-1 PARTS ARE HERE. The reference file also carries the submarine COAST SHELF
/// (SHELF_STRENGTH / SHELF_SCALE_M / CoastShelf) and the OFFSHORE ISLET layer (OffshoreBlob,
/// OffshoreZoneWeight, CalibrateThreshold, and their constants). Both are DEFERRED to Phase 2 —
/// they act on below-sea height and are judged once water renders. They will port into THIS
/// file, which is why it keeps the reference's name and shape.
///
/// This type is pure math and engine-free. It sits in Tools/ rather than Core/ so the pass-1
/// port stays auditable as one unit against one reference file, and so the deferred Phase-2
/// halves land beside their siblings rather than in a second location.
///
public static class IslandFalloff
{
///
/// The rounding width of the spine crest, in normalized axis-distance units.
/// READ from the reference: IslandFalloff.CREST_EPSILON = 0.03f (~:34).
///
public const float CREST_EPSILON = 0.03f;
///
/// A smooth absolute value: zero AT zero, with zero slope there, converging to |d| away from it.
/// READ from the reference (~:42-46), verbatim:
/// a = |d|; return a*a / sqrt(a*a + eps*eps);
///
/// ═══ WHY IT EXISTS — do not "simplify" it back to Abs ═══
///
/// The spine's ridge axis is the line x = centre, and a plain 1 - |x - cx| peaks there
/// with a SLOPE DISCONTINUITY. On real terrain that put the four columns at the centre axis
/// in the top four slope-step locations out of 5,999 — a visible crease running the whole
/// height of the island, measured at ~170x the off-axis controls. It was blamed on the
/// falloff blend for a long time; transect measurement ruled that out and found this.
///
/// SmoothAbs(0) = 0, so the crest keeps its FULL HEIGHT — it rounds without dropping.
/// Measured on the reference: the 1-px kink fell 99.3%, the centre column dropped from
/// rank 1 of 5,999 to rank 1,364, and nothing anywhere was lowered.
/// → `Design - Terrain - Mountain Spine.md`.
///
public static float SmoothAbs(float d, float epsilon)
{
float a = Math.Abs(d);
return a * a / MathF.Sqrt(a * a + epsilon * epsilon);
}
}
}