fix(physics): Slice 1 — delete render-mesh-AABB synthetic collision; DAT-only shape authority
Retail oracle: CPartArray::InitParts@0x00517F40, CGfxObj::Serialize@0x00534970 (physics_bsp gated on serialized-flags bit-0), CPhysicsPart::find_obj_collisions@0x0050D8D0 (returns OK / passable when physics_bsp==null). Render-mesh bounds never enter collision. Changes: - GameWindow.cs: delete the ~200-line VISUAL mesh-bounds collision block (the isPhantomSetup / isPhantomGfxObj locals + the if-block computing worldMin/worldMax AABB + the ShadowObjects.Register call that capped and registered the synthetic cylinder). Also removes dead counter variables scHaveBounds/scRegistered/scNoBounds/ scTooThin; trims the ProbeBuildingEnabled summary line accordingly. - PhysicsDataCache.cs: delete IsPhantomGfxObjSource (the predicate that only existed to fence the mesh-AABB synthesis; the "phantom" concept is now the default — no DAT shape means no registration, verbatim with retail). - PhysicsDataCachePhantomSourceTests.cs: deleted (tested the removed method). - ShadowShapeBuilderShapeSourceTests.cs: new guard test — a Setup with parts but hasPhysicsBsp=false and no CylSpheres/Spheres yields an empty shape list, locking the DAT-only rule in the builder. - retail-divergence-register.md: AP-2 row deleted (divergence retired). Objects with no DAT physics shape (no CylSpheres, no Spheres, no part with a PhysicsBSP) now register no collision shape and are passable, verbatim with retail. Objects with real DAT shapes (BSP parts, CylSpheres) are unaffected. dotnet build green, 22/22 tests passing (ShadowShapeBuilderShapeSourceTests + CellarUpTrajectoryReplay + CornerFlood + Issue147ArwicBuildings replay harnesses). Visual gate pending: walk Holtburg + open world; objects that become passable must match retail (DAT has no physics shape — trees with real CylSpheres still solid). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
4f26067755
commit
79dee342f2
5 changed files with 44 additions and 297 deletions
|
|
@ -384,24 +384,6 @@ public sealed class PhysicsDataCache
|
|||
|
||||
public GfxObjPhysics? GetGfxObj(uint id) => _gfxObj.TryGetValue(id, out var p) ? p : null;
|
||||
|
||||
/// <summary>
|
||||
/// Issue #101 (2026-05-25): retail-faithful phantom check for
|
||||
/// GfxObj-only entity sources. Returns true when the entity's
|
||||
/// <c>SourceGfxObjOrSetupId</c> is a GfxObj (high byte
|
||||
/// <c>0x01</c>) AND has no cached <see cref="GfxObjPhysics"/> —
|
||||
/// meaning the underlying GfxObj had <c>HasPhysics=False</c> or
|
||||
/// a null <c>PhysicsBSP.Root</c>, so <see cref="CacheGfxObj"/>
|
||||
/// 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:6127</c> must do the same.
|
||||
/// </summary>
|
||||
public bool IsPhantomGfxObjSource(uint sourceId)
|
||||
{
|
||||
if ((sourceId & 0xFF000000u) != 0x01000000u) return false;
|
||||
return GetGfxObj(sourceId)?.BSP?.Root is null;
|
||||
}
|
||||
|
||||
public SetupPhysics? GetSetup(uint id) => _setup.TryGetValue(id, out var p) ? p : null;
|
||||
public CellPhysics? GetCellStruct(uint id) => _cellStruct.TryGetValue(id, out var p) ? p : null;
|
||||
public int GfxObjCount => _gfxObj.Count;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue