diag(render): [pv-trace] sidechk — pin back-portal traversal (B1 bypass vs B2 side-test) for R-A2b

Logs camInterior/eyeIn/D per portal under the existing PortalBuildTrace so the 0173->0171 back-portal traversal can be attributed to B1 (EyeInsidePortalOpening bypass) or B2 (CameraOnInteriorSide convention). Throwaway; stripped in Phase 4.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-06-09 12:46:14 +02:00
parent 7b8a490da9
commit 89a2032c8e

View file

@ -200,6 +200,20 @@ public static class PortalVisibilityBuilder
bool dx = pvDump && cell.Portals[i].OtherCellId == 0xFFFF;
bool eyeInsideOpening = EyeInsidePortalOpening(poly, cell.WorldTransform, cameraPos);
// (R-A2b Phase 1 pin, throwaway) Log the side-test inputs for EVERY portal so a back-portal
// traversal (cell=0x..0173 p->0x0171) can be attributed to B1 (eyeInsideOpening bypasses the
// side-cull) vs B2 (CameraOnInteriorSide returns interior where retail's InitCell culls).
// |D|<=1.75 means eyeInsideOpening is in range. Strip with the rest of the [pv-trace] apparatus.
if (trace != null)
{
bool camInterior = i >= cell.ClipPlanes.Count || CameraOnInteriorSide(cell, i, cameraPos);
float sideD = (i < cell.ClipPlanes.Count && cell.ClipPlanes[i].Normal.LengthSquared() >= 1e-8f)
? Vector3.Dot(cell.ClipPlanes[i].Normal, Vector3.Transform(cameraPos, cell.InverseWorldTransform)) + cell.ClipPlanes[i].D
: float.NaN;
trace.Add($"sidechk cell=0x{cell.CellId:X8} p{i}->0x{portal.OtherCellId:X4} camInterior={camInterior} eyeIn={eyeInsideOpening} D={(float.IsNaN(sideD) ? "na" : sideD.ToString("F2"))}");
}
bool sideAllowed = true;
// Portal-side test: only traverse a portal the camera is on the interior side of