Commit graph

11 commits

Author SHA1 Message Date
Erik
d6aa526dd3 diag(render/physics): flap root-caused to physics rest µm-jitter; refute prior diagnoses
Apparatus + handoff for the indoor flap. Confirmed (primary evidence): the flap is the
portal-flood clip being µm-sensitive at the threshold, driven by a ~1-8µm jitter in the
player RenderPosition (physics resting position not bit-stable; Lerp surfaces it). REFUTES
the 2026-06-07 see-through/EnvCell/outdoor-node diagnosis (ModelId GfxObj 0x01000A2B IS the
solid exterior) AND an enqueue-once attempt (retail propagates late slices via AddToCell;
the existing PropagatesNewSlicesToExit test caught it; reverted). Adds: Build determinism
test, A8CellAudit gfxobj dump, [pv-input] 6dp probe + [render-sig] outRoot/bshell fields.
No functional fix shipped. Next: higher-precision physics rest trace -> port retail
kill_velocity/contact rest-stability. Canonical: docs/research/2026-06-08-flap-rootcause-physics-rest-handoff.md

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 09:16:12 +02:00
Erik
1405dd8e90 feat(render): indoor render WORKS — terminating portal flood + every-cell seal + look-in FPS
Checkpoint of the unified retail-faithful indoor render. The two-week HANG/grey is fixed and the
interior seals (live-verified by the user). Commits the session render-rewrite foundation together
with the fixes that made it functional.

- HANG fix: PortalVisibilityBuilder.Build portal flood did not terminate (the faithful ProjectToClip
  near-side clip drifts per round, defeating the CellView dedup; the BFS had no bound after U.2a removed
  MaxReprocessPerCell). Fix = drift-tolerant snapped/canonical CellView.Add dedup (PortalView.cs) plus
  restored MaxReprocessPerCell=16 bounded re-enqueue (PortalVisibilityBuilder.cs). Re-enqueue is kept
  (load-bearing for late-slice propagation, Build_ViewGrowthAfterDoneCell_PropagatesNewSlicesToExit);
  only its count is capped. CellViewDedupTests added.
- Seal (DrawCells Task 2): RetailPViewRenderer.DrawEnvCellShells draws EVERY visible cell via
  IndoorDrawPlan.ShellPass (was gated on the ClipFrameAssembler slot filter, leaving slot-less cells grey).
- Look-in FPS: GameWindow exterior look-in candidates limited to the player landblock +-1 (was all ~81
  loaded LBs iterated every outdoor frame). No behaviour change (far cells were >48m, already culled).

Remaining dominant issue = the FLAP at transitions: viewer-cell metastability (render roots at the
camera-eye cell, which oscillates outdoor-indoor as the 3rd-person boom drifts across the doorway,
confirmed in render-sig). SEPARATE fix, NOT the DrawCells port. Full handoff + flap fix plan + tracked
follow-ups (#78 terrain, look-in-from-inside, look-in FPS, L-spotlight):
docs/research/2026-06-07-indoor-render-session-handoff.md.

Baselines: build 0 err; App.Tests 210/210; Core.Tests 1331 pass / 4 fail (pre-existing) / 1 skip.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 10:14:43 +02:00
Erik
9f95252d20 fix(render): flood the neighbour when the eye stands in an interior portal
When the chase camera roots in a thin doorway cell and the eye stands in an interior portal opening (live capture: vestibule->room portal D=0.16m, proj=0), the 2D projection degenerates and the neighbour was culled (cells=1) -> only the thin cell drew -> bluish void / transparent ceiling. Retail's 3D clip imposes no constraint for a portal the eye is inside, so the neighbour is fully visible. When the clipped region is empty but the eye stands in the opening (EyeInsidePortalOpening: within 0.5m of the portal plane AND point-in-opening), flood the neighbour with the current view. Guarded so an off-screen degenerate portal stays culled (no #95 blowup; over-include is mesh-frustum-culled at draw). Visual-verified: cellar ceiling now solid.

Band-aid for thin-cell-root coverage; likely superseded by the boom-stability + viewer-cell dead-zone + w=0 near-plane clip fix next session (reassess / maybe revert). 2 RED->GREEN tests; cyclic/hub termination guards unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 15:27:39 +02:00
Erik
a8b831c23b test(render): Phase W Stage 4/5 — assembler OutsideView AABB + PView BFS + entity-clip tests
ClipFrameAssemblerTests (3 new):
- Assemble_OutsideViewWithExitPortal_HasOutsideViewTrue_AabbMatchesBounds
- Assemble_OutsideViewMultiPolygon_ScissorMode_HasOutsideViewTrue_AabbValid
- Assemble_EmptyOutsideView_HasOutsideViewFalse_AabbZero

PortalVisibilityBuilderTests (3 new):
- Build_ExitPortalVisible_OutsideViewNonEmpty
- Build_NoExitPortal_OutsideViewEmpty
- Build_RootCellAlwaysFirstInOrderedVisibleCells

EntityClipTests (new file, 5 tests):
- EntityClip_ParentInVisibleSet_Included
- EntityClip_ParentNotInVisibleSet_Excluded
- EntityClip_NullVisibleSet_IncludesAll
- EntityClip_NullParentCell_NullVisibleSet_Included
- EntityClip_NullParentCell_NonNullVisibleSet_Included

WbDrawDispatcher.EntityPassesVisibleCellGate changed private → internal static
(AcDream.App already has InternalsVisibleTo AcDream.App.Tests; no new seam needed).

160 → 171 tests, all green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 16:21:08 +02:00
Erik
0ee328a824 fix(render): Phase U.4c — root indoor visibility at the player's cell (the flap)
The visibility root + portal-side test now use the PLAYER position (visRootPos) in
player mode instead of the camera EYE; the eye still drives the per-frame projection
(envCellViewProj). Live ACDREAM_PROBE_FLAP evidence: the flap was the 3rd-person eye
drifting out of the player's cell -> FindCameraCell returning the STALE cell for its
grace frames -> the doorway portal culled as behind-the-eye -> exit cell + terrain +
shells dropped (res=Grace eyeInRoot=n terrain=Skip on every flap frame). Retail's
CellManager::ChangePosition (0x004559B0) tracks curr_cell by the player; acdream
already roots lighting at the player (GameWindow:7152) for the same chase-cam reason
— visibility was the lone holdout on the eye. Removed the earlier synthetic builder
flap test, which modeled a disproven (side-test) hypothesis; the fix is integration-
level, validated by the visual gate + [flap] probe. App tests 151/151.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 14:35:21 +02:00
Erik
cd3ffe3b02 test(render): Phase U.4c — reproduce the doorway flap (RED apparatus)
Synthetic C0->C1->C2(exit) chain; two camera poses straddle the C0->C1
side-test boundary by a few cm. Pre-fix, pose B hard-culls C0->C1 and the
exit cell drops -> OutsideView empties (the flap). Gates the U.4c fix.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 09:57:44 +02:00
Erik
65781f5768 fix(render): Phase U.2b — resolve reciprocal portal by other_portal_id (retail 433557)
Code review caught a CRITICAL under-inclusion: ApplyReciprocalClip scanned for the
first OtherCellId match, so a cell with two portals to the same neighbour clipped both
near-side openings against the FIRST reciprocal polygon — hiding geometry through the
second opening (real on Holtburg cellar cells 0x148<->0x149). Plumb the dat's
OtherPortalId back-link through CellPortalInfo + BuildLoadedCell and index the reciprocal
directly (retail arg2->other_portal_id, 433557). Skip (degrade to over-include) when the
index is unresolvable — never clip against a guessed polygon. Adds a disjoint two-back-
portal regression test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 16:56:00 +02:00
Erik
3916b2b23e feat(render): Phase U.2b — reciprocal OtherPortalClip (retail 433524)
Clip the portal opening against the neighbour's matching back-portal polygon
before propagating, so a cell's clip region is the intersection of the opening
seen from both sides. Closes the M-4 stub in ISSUES #102. Can only tighten,
never under-include; degrades to prior behavior when no back-portal is found.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 16:37:14 +02:00
Erik
d8807755ce feat(render): Phase U.2a — portal BFS ordering + fixpoint termination
PortalVisibilityFrame gains OrderedVisibleCells (closest-first). Replace the FIFO +
MaxReprocessPerCell cap with a distance-priority queue and a grow-watermark fixpoint
(retail InsCellTodoList 433183 / AddViewToPortals 433446) so cyclic dungeon graphs
converge without duplicate-cell blow-up.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 16:22:06 +02:00
Erik
270c21f263 refactor(render): Phase A8.F — Task 4 review follow-up (honest cap comment, cycle guard test, file fixpoint fast-follow)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 12:16:11 +02:00
Erik
0ed462cb62 feat(render): Phase A8.F — PortalVisibilityBuilder recursive portal-clip BFS
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 12:03:50 +02:00