fix(physics): #101 — suppress mesh-aabb-fallback for phantom GfxObj stabs
The 10 stair-step cyls (entities 0x40B5008A..0x40B50095 in Holtburg cells 0xA9B40159/A) are synthesized by the mesh-aabb-fallback path from the visual mesh AABB of GfxObj 0x0100081A — which has HasPhysics=False and no PhysicsBSP. Retail's CPartArray::InitParts emits no collision in this case; acdream now matches that by consulting PhysicsDataCache.IsPhantomGfxObjSource (added in the previous commit) and skipping synthesis when the predicate fires. The actual staircase collision is on entity 0x40B50089 (GfxObj 0x01000C16, hasPhys=True, BSP radius 2.645m) — same staircase BSP that retail uses. After this fix, only that BSP fires; the phantoms are gone. Visual verification pending (next step in plan); the BSP dump from ACDREAM_DUMP_GFXOBJS=0x01000C16 will confirm whether 0x01000C16 has walkable inclined polys for the climb to actually land. If not, a follow-up issue is needed; the cyl phantom is closed either way. Also updates PhysicsDataCache.cs XML doc line reference from 6116 to 6127 (drifted by the 11-line isPhantomGfxObj block inserted above the guarded if). Refs docs/research/2026-05-25-a6-stairs-cyl-retail-investigation.md. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
f6305b1e3c
commit
5240d654df
2 changed files with 13 additions and 1 deletions
|
|
@ -6100,6 +6100,17 @@ public sealed class GameWindow : IDisposable
|
|||
}
|
||||
}
|
||||
|
||||
// Issue #101 (2026-05-25): retail-faithful phantom check for
|
||||
// GfxObj-only entity sources. Retail's CPartArray::InitParts
|
||||
// emits NO collision shapes when the source GfxObj has
|
||||
// HasPhysics=False / null PhysicsBSP.Root. Our mesh-aabb-fallback
|
||||
// below previously synthesized a clamped [0.30, 1.50]m cylinder
|
||||
// from the visual mesh AABB — that's the source of the 10
|
||||
// phantom 0.80m cyls that block the Holtburg upper-floor
|
||||
// staircase (issue #101). Suppress synthesis for these.
|
||||
// Spec: docs/research/2026-05-25-a6-stairs-cyl-retail-investigation.md.
|
||||
bool isPhantomGfxObj = _physicsDataCache.IsPhantomGfxObjSource(entity.SourceGfxObjOrSetupId);
|
||||
|
||||
// VISUAL mesh-bounds collision: for SCENERY entities (IDs with
|
||||
// 0x80000000 bit set, indicating procedurally-placed scenery),
|
||||
// ALWAYS compute a cylinder from the world-space mesh AABB.
|
||||
|
|
@ -6114,6 +6125,7 @@ public sealed class GameWindow : IDisposable
|
|||
// L-fix3: skip entirely when the Setup is phantom — retail
|
||||
// decorative meshes have no collision data on purpose.
|
||||
if (!isPhantomSetup
|
||||
&& !isPhantomGfxObj
|
||||
&& !_isLandblockStab
|
||||
&& (_isOutdoorMesh || (entityBsp == 0 && entityCyl == 0))
|
||||
&& entity.MeshRefs.Count > 0)
|
||||
|
|
|
|||
|
|
@ -370,7 +370,7 @@ public sealed class PhysicsDataCache
|
|||
/// short-circuited at the early-return on line 45/46. Retail's
|
||||
/// <c>CPartArray::InitParts</c> emits NO collision shapes for
|
||||
/// these — acdream's <c>mesh-aabb-fallback</c> synthesis at
|
||||
/// <c>GameWindow.cs:6116</c> must do the same.
|
||||
/// <c>GameWindow.cs:6127</c> must do the same.
|
||||
/// </summary>
|
||||
public bool IsPhantomGfxObjSource(uint sourceId)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue