fix(#186): render side-cull mis-sided thin connectors — use dat PortalSide bit, not AABB centroid
The indoor GREY flap at a top-floor connecting room. The render portal side-cull reconstructed each doorway's "interior side" (PortalClipPlane.InsideSide) from the cell's AABB CENTROID. For a THIN connector cell (0xF6820118, 5 render polys), the bounding-box center falls on the WRONG side of the 0118->0116 doorway, so the eye read as a back-portal and the forward room 0116 was culled -> the aperture showed the fog clear color = grey. Retail's PView::InitCell (0x005a4b70) and acdream's own PHYSICS path (CellTransit.cs:190) both read the explicit dat PortalSide bit ((Flags&2)==0) instead of guessing from geometry. Port the render path (GameWindow.BuildLoadedCell) to the same bit. Proven by a live retail cdb trace (retail draws 0116 from the 0118 root at the grey pose; tools/cdb/issue186-connector-decider.cdb) + an offline dat diagnostic (Issue186...PortalSide_CentroidVsDatBit_AtGreyEye): the dat bit matches the old centroid on every portal of these cells EXCEPT the one #186 breaks, so the switch is surgical. Full regression green (App 741 / Core 2631); the CornerFlood + Issue113 dat-loading helpers updated to the same bit confirm every real Holtburg/tower/hall cell floods identically. Touches neither PortalSideEpsilon nor the deleted EyeInsidePortalOpening rescue (the two DO-NOT-RETRY traps). Live-gated: user-confirmed no grey at any camera angle; probe shows 216 root=0118 frames, 0 still grey (0118->0116 now TRV, vis=4). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
9d35a9786f
commit
8257b9ba10
6 changed files with 164 additions and 13 deletions
|
|
@ -88,7 +88,6 @@ public class CornerFloodReplayTests
|
|||
var portals = new List<CellPortalInfo>();
|
||||
var clipPlanes = new List<PortalClipPlane>();
|
||||
var portalPolygons = new List<Vector3[]>();
|
||||
var centroid = (boundsMin + boundsMax) * 0.5f;
|
||||
|
||||
foreach (var portal in envCell.CellPortals)
|
||||
{
|
||||
|
|
@ -106,10 +105,13 @@ public class CornerFloodReplayTests
|
|||
var p2 = new Vector3(v2.Origin.X, v2.Origin.Y, v2.Origin.Z);
|
||||
var normal = Vector3.Normalize(Vector3.Cross(p1 - p0, p2 - p0));
|
||||
float d = -Vector3.Dot(normal, p0);
|
||||
float centroidDot = Vector3.Dot(normal, centroid) + d;
|
||||
// InsideSide from the dat PortalSide bit — mirrors the production fix
|
||||
// (GameWindow.BuildLoadedCell): retail InitCell (0x005a4b70) + physics
|
||||
// CellTransit use the dat bit; the old AABB-centroid guess mis-sided thin
|
||||
// connectors (#186). Kept identical here so this replay stays a faithful mirror.
|
||||
clipPlanes.Add(new PortalClipPlane
|
||||
{
|
||||
Normal = normal, D = d, InsideSide = centroidDot >= 0 ? 0 : 1,
|
||||
Normal = normal, D = d, InsideSide = ((ushort)portal.Flags & 0x2) == 0 ? 1 : 0,
|
||||
});
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -77,7 +77,6 @@ public class Issue113MeetingHallFloodTests
|
|||
var portals = new List<CellPortalInfo>();
|
||||
var clipPlanes = new List<PortalClipPlane>();
|
||||
var portalPolygons = new List<Vector3[]>();
|
||||
var centroid = (boundsMin + boundsMax) * 0.5f;
|
||||
|
||||
foreach (var portal in envCell.CellPortals)
|
||||
{
|
||||
|
|
@ -95,10 +94,13 @@ public class Issue113MeetingHallFloodTests
|
|||
var p2 = new Vector3(v2.Origin.X, v2.Origin.Y, v2.Origin.Z);
|
||||
var normal = Vector3.Normalize(Vector3.Cross(p1 - p0, p2 - p0));
|
||||
float d = -Vector3.Dot(normal, p0);
|
||||
float centroidDot = Vector3.Dot(normal, centroid) + d;
|
||||
// InsideSide from the dat PortalSide bit — mirrors the production fix
|
||||
// (GameWindow.BuildLoadedCell): retail InitCell (0x005a4b70) + physics
|
||||
// CellTransit use the dat bit; the old AABB-centroid guess mis-sided thin
|
||||
// connectors (#186). Kept identical here so this replay stays a faithful mirror.
|
||||
clipPlanes.Add(new PortalClipPlane
|
||||
{
|
||||
Normal = normal, D = d, InsideSide = centroidDot >= 0 ? 0 : 1,
|
||||
Normal = normal, D = d, InsideSide = ((ushort)portal.Flags & 0x2) == 0 ? 1 : 0,
|
||||
});
|
||||
}
|
||||
else
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue