feat(physics): [walk-miss] + [floor-polys] diagnostic emissions
Wires the WalkMissDiagnostic aggregator + flag into the two emission sites per docs/superpowers/specs/2026-05-21-indoor-walk-miss-probe-design.md. - [walk-miss] (per-frame, MISS branch of TryFindIndoorWalkablePlane): foot world+local position, nearest walkable poly with XY-containment flag and vertical gap, and LandCell terrain probe at the same XY. - [floor-polys] (one-shot per cell at cache time): walkable poly id, normal Z, local-XY bbox, plane Z at bbox center. Both gated on ACDREAM_PROBE_WALK_MISS=1. No physics behavior changes. The live capture at the Holtburg cottage doorway + inn 2nd floor + cellar descent disambiguates H1 (multi-cell iteration), H2 (probe distance), H3 (poly absent / walkable_hits_sphere rejection) for ISSUES #83. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
31da57c94c
commit
a2e7a87c25
2 changed files with 63 additions and 0 deletions
|
|
@ -218,6 +218,24 @@ public sealed class PhysicsDataCache
|
|||
Console.WriteLine(System.FormattableString.Invariant(
|
||||
$"[cell-cache] envCellId=0x{envCellId:X8} physicsPolyCount={cellStruct.PhysicsPolygons?.Count ?? 0} resolvedCount={resolved.Count} bspTotalLeafPolys={bspTotalLeafPolys} bspUnmatchedIds={bspUnmatchedIds} {bsStr} portalCount={portals.Count} visibleCells={visibleCellIds.Count} cellBspRoot={(cellStruct.CellBSP?.Root is null ? "null" : "ok")} worldOrigin=({worldOrigin.X:F2},{worldOrigin.Y:F2},{worldOrigin.Z:F2})"));
|
||||
}
|
||||
|
||||
if (PhysicsDiagnostics.ProbeWalkMissEnabled)
|
||||
{
|
||||
int walkableCount = 0;
|
||||
foreach (var entry in WalkMissDiagnostic.EnumerateWalkable(
|
||||
resolved, PhysicsGlobals.FloorZ))
|
||||
walkableCount++;
|
||||
|
||||
Console.Write(System.FormattableString.Invariant(
|
||||
$"[floor-polys] cellId=0x{envCellId:X8} walkableCount={walkableCount}"));
|
||||
foreach (var entry in WalkMissDiagnostic.EnumerateWalkable(
|
||||
resolved, PhysicsGlobals.FloorZ))
|
||||
{
|
||||
Console.Write(System.FormattableString.Invariant(
|
||||
$" [id=0x{entry.PolyId:X4} nz={entry.NormalZ:F3} bbox=({entry.BboxMin.X:F2},{entry.BboxMin.Y:F2})..({entry.BboxMax.X:F2},{entry.BboxMax.Y:F2}) planeZ@center={entry.PlaneZAtBboxCenter:F3}]"));
|
||||
}
|
||||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -1540,6 +1540,51 @@ public sealed class Transition
|
|||
}
|
||||
}
|
||||
|
||||
if (!walkableHit && PhysicsDiagnostics.ProbeWalkMissEnabled)
|
||||
{
|
||||
var agg = WalkMissDiagnostic.AggregateNearestWalkable(
|
||||
cellPhysics.Resolved,
|
||||
footLocal: localCenter,
|
||||
floorZ: PhysicsGlobals.FloorZ);
|
||||
|
||||
// Count walkable polys for the line (cheap re-scan; the
|
||||
// probe is opt-in so cost is bounded to MISS frames).
|
||||
int walkableCount = 0;
|
||||
foreach (var kvp in cellPhysics.Resolved)
|
||||
{
|
||||
if (kvp.Value.Plane.Normal.Z >= PhysicsGlobals.FloorZ
|
||||
&& kvp.Value.Vertices.Length >= 3)
|
||||
walkableCount++;
|
||||
}
|
||||
|
||||
// Outdoor terrain probe at the same world XY — the
|
||||
// "would multi-cell iteration have grounded us?" check.
|
||||
var terrain = engine.SampleTerrainWalkable(footCenter.X, footCenter.Y);
|
||||
string terrainPart;
|
||||
if (terrain is null)
|
||||
{
|
||||
terrainPart = "landcell.hasTerrain=false";
|
||||
}
|
||||
else
|
||||
{
|
||||
var tp = terrain.Value.Plane;
|
||||
float terrainZ = -(tp.D + tp.Normal.X * footCenter.X
|
||||
+ tp.Normal.Y * footCenter.Y)
|
||||
/ tp.Normal.Z;
|
||||
float terrainDz = footCenter.Z - terrainZ;
|
||||
terrainPart = System.FormattableString.Invariant(
|
||||
$"landcell.hasTerrain=true landcell.terrainZ={terrainZ:F3} landcell.dz={terrainDz:+0.000;-0.000;+0.000}");
|
||||
}
|
||||
|
||||
string nearestPart = agg.Found
|
||||
? System.FormattableString.Invariant(
|
||||
$"nearest.polyId=0x{agg.PolyId:X4} nearest.containsFootXY={agg.ContainsFootXY} nearest.dz={agg.Dz:+0.000;-0.000;+0.000} nearest.normalZ={agg.NormalZ:F3}")
|
||||
: "nearest=none";
|
||||
|
||||
Console.WriteLine(System.FormattableString.Invariant(
|
||||
$"[walk-miss] cell=0x{sp.CheckCellId:X8} foot.W=({footCenter.X:F3},{footCenter.Y:F3},{footCenter.Z:F3}) foot.L=({localCenter.X:F3},{localCenter.Y:F3},{localCenter.Z:F3}) floorPolyCount={walkableCount} {nearestPart} {terrainPart}"));
|
||||
}
|
||||
|
||||
if (walkableHit)
|
||||
{
|
||||
return ValidateWalkable(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue