fix(render): FW4 slice 5 - straddling cell statics'' particles emit pre-clear

The cathedral falls'' true identity, pinned by the emitter/owner dumps
and the owner''s retail-vs-ACE oracle (retail renders them perfectly):
they are EnvCell STAB-LIST statics (interior-cell dat objects, ids
minted by InteriorEntityIdAllocator) whose geometry hangs out over the
lake. Our cell-statics route submitted every interior flood cell''s
static particle owners POST-clear ("walls own depth") - true for
content that stays inside, but a straddler''s outside half meets
seal/cleared depth and splats across the vista.

Retail''s mechanism is the outdoor shadow-cell draw: an object
overlapping outdoor landcells draws during LScape::draw (DrawBlock
pc:430056-430064, once per overlapped shadow cell), so its particles
submit in the landscape scope and drain at the pre-clear boundary
flush over true terrain depth; the cell''s own turn skips them
(drawn-once). This slice ports that rule for particles: after Collect,
the interior flood cells'' static records are classified by the shared
exit-plane straddle test (extracted as SphereStraddlesExitPlane from
the #118 dynamic split); straddlers'' owners submit in the pre-clear
closure and the post-replay cell-owners union subtracts them, so every
owner emits exactly once. Also adds the [walk-emit] probe dump that
falsified the unattached-route theory.

Hermetic 6,762/0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-08-30 19:58:04 +02:00
parent f3a03efc81
commit 0d6cd5c06e
3 changed files with 108 additions and 0 deletions

View file

@ -119,6 +119,14 @@ public sealed class WalkPView
flags.InView = true; // portal polygon faces the viewer
}
}
if (AcDream.Core.Rendering.RenderingDiagnostics.WalkPortalProbeThisFrame)
{
Console.WriteLine(
$"[walk-portal] init cell={cell.CellId:x8} i={i} "
+ $"dest={cell.Portals[i].OtherCellId:x8} d={d:F3} "
+ $"pside={cell.Portals[i].PortalSide} "
+ $"inview={(flags.InView ? 1 : 0)}");
}
}
if (flags.InView)
@ -201,6 +209,12 @@ public sealed class WalkPView
cell, portal.PortalSide,
cell.PortalPolygons[portal.PolygonIndex],
doClip: true, ctx, _clipScratch);
if (AcDream.Core.Rendering.RenderingDiagnostics.WalkPortalProbeThisFrame)
{
Console.WriteLine(
$"[walk-portal] clip cell={cell.CellId:x8} view={i} j={j} "
+ $"dest={portal.OtherCellId:x8} n={n}");
}
if (n == 0) continue;
if (portal.OtherCellId == 0xFFFFFFFFu)