fix(render): branch inside/outside on is_player_outside, not the camera cell (PARTIAL)

Retail SmartBox::RenderNormalMode (0x453aa0:92665) branches DrawInside vs the
outdoor LScape::draw on is_player_outside (the PLAYER's cell, 0x451e80), then
roots DrawInside at the VIEWER cell. acdream keyed the whole branch off the
camera cell (clipRoot = visibility.CameraCell), so a 3rd-person chase camera
lagging in a doorway AFTER the player stepped outside took the DrawInside path
rooted at the threshold cell, where the exit-portal flood degenerates: grey
world + entities-through-walls. Now ShouldRenderIndoor(playerCellId,
viewerCellResolved) gates the branch on the player; the DrawInside root stays
the viewer cell (handoff invariant preserved).

SCOPE / HONESTY: this REDUCES the player-OUTSIDE doorway grey (visual-confirmed
reduced a lot) but does NOT fix the deeper symptom: when the player is in one
interior cell (cellar 0174) and the camera is in another (room 0171), the flood
roots at the camera cell and does NOT seal the player's cell, so the cellar
floor / interior walls drop to grey. That is the KNOWN R1-completion problem
(2026-06-05 Residual A handoff + 2026-06-02 design doc section 3: a
SHELL-SEALING / wrong-flood-root bug), not this branch.

Tests: Core 1331p / 4f (documented) / 1s, App 187p, build green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-06-05 17:02:09 +02:00
parent d2212cfaea
commit 2b7f5a16c6
3 changed files with 81 additions and 1 deletions

View file

@ -7319,7 +7319,19 @@ public sealed class GameWindow : IDisposable
// (mesh SSBO) + binding=2 (terrain UBO); each renderer re-binds its
// binding=2 defensively from the ids we hand it.
_clipFrame ??= ClipFrame.NoClip();
var clipRoot = visibility?.CameraCell;
// Retail RenderNormalMode (0x453aa0:92665) branches inside/outside on is_player_outside
// — the PLAYER's cell (0x451e80), NOT the camera cell — then roots DrawInside at the
// VIEWER cell (this->viewer_cell) when inside. The 3rd-person chase camera LAGS the
// player, so keying the branch off the camera (the old `visibility?.CameraCell`) made
// the camera lingering in a doorway AFTER the player had stepped outside take the
// DrawInside path rooted at the threshold cell, where the exit-portal flood degenerates
// → terrain Skipped + sparse shells → grey world with only entities showing through.
// Branch on the player; keep the viewer cell as the indoor root (handoff invariant).
uint playerCellId = _physicsEngine.DataCache?.CellGraph.CurrCell?.Id ?? 0u;
var clipRoot = AcDream.Core.Rendering.RenderingDiagnostics.ShouldRenderIndoor(
playerCellId, visibility?.CameraCell is not null)
? visibility!.CameraCell
: null;
ClipFrameAssembly? clipAssembly = null;
PortalVisibilityFrame? pvFrame = null; // R1: hoisted so the binary decision below reads OrderedVisibleCells
var terrainClipMode = TerrainClipMode.Planes; // overwritten below for indoor root