Skip to content

Fix Shadow Corruption from Stale DynaPoly floorPoly Pointers#6616

Open
unreference wants to merge 2 commits into
HarbourMasters:developfrom
unreference:fix/dynapoly-stale-floorpoly-shadow
Open

Fix Shadow Corruption from Stale DynaPoly floorPoly Pointers#6616
unreference wants to merge 2 commits into
HarbourMasters:developfrom
unreference:fix/dynapoly-stale-floorpoly-shadow

Conversation

@unreference
Copy link
Copy Markdown

This fixes #1953.

Actors that cache floorPoly pointers into the DynaPoly polyList buffer can end up holding stale references when DynaPoly_ExpandSRT rebuilds the buffer. The pointer address remains valid, but the data at the address shifts to a different polygon -- often a wall poly with a horizontal normal.

When this happens, the shadow projection matrix is built from the wall normal instead of a floor normal, rotating the shadow 90-degrees onto a vertical plane. Combined with G_CULL_BACK in sSetupDL[0x2C], the shadow flickers in and out depending on camera angle. This bug also exists on original hardware, but likely masked by the constraints.

  • Adds a normal.y > 0 guard so polys that no longer face upward are rejected before the shadow matrix is built. Prevents rendering from any stale wall or ceiling poly.
  • When DYNAPOLY_INVALIDATE_LOOKUP triggers a full rebuild in DynaPoly_Setup, rederive floorPoly via BgCheck_EntityRaycastFloor5 for every actor whose floorBgId references a DynaPoly surface. This only runs on frames where the invalidation flag is set and only touches a small subset of actors on dynamic collision, so there is effectively zero performance cost.

What I couldn't figure out is why this is specifically caused by destroying a crate. The crate itself is not DynaPoly, and nothing in its destruction path calls DynaPoly functions, yet destroying multiple crates continuously flips the shadow. The fix is sound regardless because the bug itself is systemic -- any actor holding a stale floorPoly pointer into the DynaPoly buffer can also experience it -- this specific actor's one-shot BgCheck just makes it easier to trigger.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Kakriko - Worker Shadow

1 participant