feat(physics): add differential flat BSP traversal

Port every current containment, overlap, walkable, and six-path moving-collision query to immutable integer-indexed assets behind a graph-authoritative referee. Exact synthetic, installed-DAT, complete-resolver, and zero-allocation gates prove bit-identical behavior before connected dual publication.

Co-authored-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
Erik 2026-07-25 15:47:58 +02:00
parent 9cd42417a8
commit f7ff9f4eea
13 changed files with 3907 additions and 46 deletions

View file

@ -96,7 +96,7 @@ public static class BSPQuery
///
/// <para>ACE: Polygon.cs polygon_hits_sphere_precise.</para>
/// </summary>
private static bool PolygonHitsSpherePrecise(
internal static bool PolygonHitsSpherePrecise(
in Plane polyPlane,
ReadOnlySpan<Vector3> verts,
Vector3 sphereCenter,
@ -2339,6 +2339,31 @@ public static class BSPQuery
ref hitPolyId, ref hitNormal);
}
/// <summary>
/// Allocation-free graph-oracle seam used by the Slice I flat traversal
/// differential harness.
/// </summary>
internal static bool SphereIntersectsPoly(
PhysicsBSPNode? node,
Dictionary<ushort, ResolvedPolygon> resolved,
Vector3 sphereCenter,
float sphereRadius,
out ushort hitPolyId,
out Vector3 hitNormal)
{
hitPolyId = 0;
hitNormal = Vector3.Zero;
if (node is null) return false;
return SphereIntersectsPolyStaticRecurse(
node,
resolved,
sphereCenter,
sphereRadius,
ref hitPolyId,
ref hitNormal);
}
private static bool SphereIntersectsPolyStaticRecurse(
PhysicsBSPNode? node,
Dictionary<ushort, ResolvedPolygon> resolved,
@ -2431,6 +2456,38 @@ public static class BSPQuery
return hitTime < float.MaxValue;
}
/// <summary>
/// Allocation-free graph-oracle seam used by the Slice I flat traversal
/// differential harness.
/// </summary>
internal static bool SphereIntersectsPolyWithTime(
PhysicsBSPNode? node,
Dictionary<ushort, ResolvedPolygon> resolved,
Vector3 sphereCenter,
float sphereRadius,
Vector3 movement,
out ushort hitPolyId,
out Vector3 hitNormal,
out float hitTime)
{
hitPolyId = 0;
hitNormal = Vector3.Zero;
hitTime = float.MaxValue;
if (node is null) return false;
SphereIntersectsPolyWithTimeRecurse(
node,
resolved,
sphereCenter,
sphereRadius,
movement,
ref hitPolyId,
ref hitNormal,
ref hitTime);
return hitTime < float.MaxValue;
}
private static void SphereIntersectsPolyWithTimeRecurse(
PhysicsBSPNode? node,
Dictionary<ushort, ResolvedPolygon> resolved,