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>
This commit is contained in:
parent
f47895cc73
commit
0ee328a824
2 changed files with 30 additions and 54 deletions
|
|
@ -7139,7 +7139,21 @@ public sealed class GameWindow : IDisposable
|
|||
// Step 4: portal visibility — compute BEFORE the UBO upload so
|
||||
// the indoor flag drives the sun's intensity to zero for
|
||||
// dungeons (r13 §13.7).
|
||||
var visibility = _cellVisibility.ComputeVisibility(camPos);
|
||||
// Phase U.4c (2026-05-31): root indoor visibility at the PLAYER's cell, not the
|
||||
// camera EYE. Retail's CellManager::ChangePosition (0x004559B0) tracks curr_cell by
|
||||
// the player/physics position. The 3rd-person chase EYE drifts out of the player's
|
||||
// cell (through interior walls into AABB gaps); FindCameraCell then can't place the
|
||||
// eye and returns the STALE previous cell for its 3 grace frames, from which the
|
||||
// doorway portal is "behind" the eye → culled → the exit cell + terrain + shells
|
||||
// flap off. ACDREAM_PROBE_FLAP capture (2026-05-31): every flap frame is
|
||||
// res=Grace eyeInRoot=n terrain=Skip; every good frame is eyeInRoot=Y. The eye is
|
||||
// still used for the per-frame PROJECTION (envCellViewProj) — only the cell ROOT +
|
||||
// portal-side test track the player. This mirrors the playerInsideCell lighting
|
||||
// decision below, which already roots at the player for exactly this reason.
|
||||
var visRootPos = (_playerMode && _playerController is not null)
|
||||
? _playerController.Position
|
||||
: camPos;
|
||||
var visibility = _cellVisibility.ComputeVisibility(visRootPos);
|
||||
bool cameraInsideCell = visibility?.CameraCell is not null;
|
||||
|
||||
// Phase U.4 (2026-05-30): the [vis] probe moved DOWN to the unified
|
||||
|
|
@ -7285,9 +7299,12 @@ public sealed class GameWindow : IDisposable
|
|||
HashSet<uint>? envCellShellFilter = null; // drawable visible cells (cellIdToSlot keys)
|
||||
if (clipRoot is not null)
|
||||
{
|
||||
// Phase U.4c: side test + distance ordering use the PLAYER position (visRootPos,
|
||||
// stable inside the cell); projection uses the eye's envCellViewProj (the screen
|
||||
// view). See the visRootPos rationale at the ComputeVisibility call above.
|
||||
var pvFrame = PortalVisibilityBuilder.Build(
|
||||
clipRoot,
|
||||
camPos,
|
||||
visRootPos,
|
||||
id => _cellVisibility.TryGetCell(id, out var c) ? c : null,
|
||||
envCellViewProj);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue