test(phys): A6.P4 door inside-out — collision-geometry gap diagnosis
Added diagnostic apparatus that pinpoints the inside-out walkthrough as a collision-geometry GAP, not a collision-detection bug. New tests in DoorBugTrajectoryReplayTests: - InsideOut_Tick3254_WithCottageWalls_ShouldBlock: hypothesis test that registered cottage GfxObj 0x01000A2B and replayed the captured tick. Cottage blocked sphere but with cn=(0,0,1) floor-cap normal, not a wall normal — first signal that cottage geometry near the sphere isn't a wall. - Diagnostic_CottagePolys_NearWalkthroughPosition: dumps cottage polys near sphere XY=(133.655, 17.59) at any Z. Result: ZERO cottage polygons in that area. The cottage GfxObj has no geometry where the sphere walks through. DoorSetupGfxObjInspectionTests.HoltburgCottage_CellPortals_DatInspection extended to dump cell 0xA9B40150's 4 physics polygons in world frame: - floor (Z=94), ceiling (Z=96.5), west wall (X=131.6), east wall (X=133.5) - All walls only span Y=[16.5, 17.1] — the small doorway alcove volume - North of Y=17.1, no wall Captured sphere at (133.655, 17.59) is 0.155 m east of cell east wall AND 0.49 m north of the wall's Y range. No collision geometry exists at that XY past Y=17.1. The collision representation has a gap that the visual cottage covers with a wall. Production capture confirms the diagnosis: cottage GfxObj fires [bsp-test] 425 times during inside-out walking — visibility IS correct post-AddAllOutsideCells fix. Door slab fires 245 times. But the BSP queries find no polygon at (133.655, 17.6+, 94-95.20). The slab's east face blocks WEST motion (cn=(+1,0,0) as captured), sphere free to move +Y past it because no wall is there to block. Three candidates for next-session investigation: 1. Different cottage GfxObj (Holtburg cottages may be multi-piece) 2. Landblock-baked stab static at the cottage exterior wall location 3. Cottage GfxObj's visual polygons wider than physics polygons (dat fact) Cheapest next step: add LandblockStatics_DatInspection test that loads LandBlockInfo 0xA9B4FFFE + iterates StaticObjects + prints every entity at world XY in [131,135] x [16,19]. Reveals what other entities live at the cottage doorway. Full handoff: docs/research/2026-05-25-door-bug-inside-out-geometry-gap.md Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
85a164f4a8
commit
da798b2071
3 changed files with 333 additions and 0 deletions
|
|
@ -314,6 +314,31 @@ public class DoorSetupGfxObjInspectionTests
|
|||
_out.WriteLine($" CellStruct polygons = {cellStruct.Polygons?.Count ?? 0} (visible)");
|
||||
_out.WriteLine($" CellStruct physicsPolys = {cellStruct.PhysicsPolygons?.Count ?? 0}");
|
||||
|
||||
// Dump ALL physics polygons (collision walls/floor) in world frame
|
||||
// so we can see what blocks a sphere at world (133.655, 17.59).
|
||||
_out.WriteLine($" CellStruct PHYSICS polys (world frame):");
|
||||
var cellOrigin = envCell.Position.Origin;
|
||||
var cellRot = envCell.Position.Orientation;
|
||||
for (int pi = 0; pi < cellStruct.PhysicsPolygons.Count; pi++)
|
||||
{
|
||||
var (pid, poly) = (cellStruct.PhysicsPolygons.Keys.ElementAt(pi),
|
||||
cellStruct.PhysicsPolygons.Values.ElementAt(pi));
|
||||
float wxMin = float.MaxValue, wxMax = float.MinValue;
|
||||
float wyMin = float.MaxValue, wyMax = float.MinValue;
|
||||
float wzMin = float.MaxValue, wzMax = float.MinValue;
|
||||
foreach (var vid in poly.VertexIds)
|
||||
{
|
||||
if (!cellStruct.VertexArray.Vertices.TryGetValue((ushort)vid, out var sv)) continue;
|
||||
var rotated = System.Numerics.Vector3.Transform(sv.Origin, cellRot);
|
||||
var world = cellOrigin + rotated;
|
||||
if (world.X < wxMin) wxMin = world.X; if (world.X > wxMax) wxMax = world.X;
|
||||
if (world.Y < wyMin) wyMin = world.Y; if (world.Y > wyMax) wyMax = world.Y;
|
||||
if (world.Z < wzMin) wzMin = world.Z; if (world.Z > wzMax) wzMax = world.Z;
|
||||
}
|
||||
_out.WriteLine($" [{pi}=0x{pid:X4}] sides={poly.SidesType} " +
|
||||
$"X=[{wxMin:F3},{wxMax:F3}] Y=[{wyMin:F3},{wyMax:F3}] Z=[{wzMin:F3},{wzMax:F3}]");
|
||||
}
|
||||
|
||||
// Dump the plane of each portal polygon (the planes
|
||||
// FindTransitCellsSphere tests the sphere center against).
|
||||
for (int i = 0; i < envCell.CellPortals.Count; i++)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue