fix(physics): validate retail cell containment roots
This commit is contained in:
parent
7716c2ee89
commit
3e0f3b6206
23 changed files with 429 additions and 197 deletions
|
|
@ -172,7 +172,7 @@ public class CellTransitFindCellSetTests
|
|||
// ──────────────────────────────────────────────────────────────────
|
||||
|
||||
[Fact]
|
||||
public void OutdoorSeed_CrossesLandblockBoundary_South()
|
||||
public void OutdoorSeed_CrossesLandblockBoundary_South_AfterDestinationHydrates()
|
||||
{
|
||||
// The #106 acceptance golden: walking south out of A9B4, the outdoor
|
||||
// cell must advance to the southern neighbour block's cell. Origin of
|
||||
|
|
@ -183,14 +183,25 @@ public class CellTransitFindCellSetTests
|
|||
var cache = new PhysicsDataCache();
|
||||
cache.CellGraph.RegisterTerrain(0xA9B40000u, new TerrainSurface(new byte[81], new float[256]), Vector3.Zero);
|
||||
|
||||
uint containing = CellTransit.FindCellSet(
|
||||
uint unavailable = CellTransit.FindCellSet(
|
||||
cache, new Vector3(150f, -0.2f, 0f), sphereRadius: 0.5f,
|
||||
currentCellId: 0xA9B40031u,
|
||||
out var cellSet);
|
||||
|
||||
Assert.Equal(0xA9B30038u, containing);
|
||||
Assert.Equal(0xA9B40031u, unavailable);
|
||||
Assert.Contains(0xA9B30038u, cellSet);
|
||||
Assert.Contains(0xA9B40031u, cellSet); // +Y neighbour still in the set
|
||||
|
||||
cache.CellGraph.RegisterTerrain(
|
||||
0xA9B30000u,
|
||||
new TerrainSurface(new byte[81], new float[256]),
|
||||
new Vector3(0f, -192f, 0f));
|
||||
uint containing = CellTransit.FindCellSet(
|
||||
cache, new Vector3(150f, -0.2f, 0f), sphereRadius: 0.5f,
|
||||
currentCellId: 0xA9B40031u,
|
||||
out _);
|
||||
|
||||
Assert.Equal(0xA9B30038u, containing);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -227,6 +238,10 @@ public class CellTransitFindCellSetTests
|
|||
0xA9B30000u,
|
||||
new TerrainSurface(new byte[81], new float[256]),
|
||||
new Vector3(0f, -192f, 0f));
|
||||
cache.CellGraph.RegisterTerrain(
|
||||
0xA9B40000u,
|
||||
new TerrainSurface(new byte[81], new float[256]),
|
||||
Vector3.Zero);
|
||||
|
||||
uint containing = CellTransit.FindCellSet(
|
||||
cache, new Vector3(150f, 1f, 0f), sphereRadius: 0.5f,
|
||||
|
|
@ -315,27 +330,29 @@ public class CellTransitFindCellSetTests
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void IndoorSeed_LoadedNullRoot_IsUniversallyInside_StaysCurrent()
|
||||
public void FindVisibleChildCell_RootlessContainment_IsUnavailable()
|
||||
{
|
||||
// Retail distinguishes a failed cell lookup from a loaded CellStruct
|
||||
// whose containment root is null. The latter is the BSP query's
|
||||
// universally-inside base case, so the current cell wins immediately.
|
||||
// Bypass production cache validation to pin the traversal boundary:
|
||||
// a rootless fixture cannot claim a point even though the recursive
|
||||
// helper's missing-positive-child base case returns inside.
|
||||
Matrix4x4.Invert(Matrix4x4.Identity, out var inv);
|
||||
var cellNoBsp = new CellPhysics
|
||||
{
|
||||
WorldTransform = Matrix4x4.Identity,
|
||||
InverseWorldTransform = inv,
|
||||
Resolved = new Dictionary<ushort, ResolvedPolygon>(),
|
||||
Portals = [new PortalInfo(0x0101, 0, 0)],
|
||||
};
|
||||
var cache = new PhysicsDataCache();
|
||||
cache.RegisterCellStructForTest(0xA9B40150u, cellNoBsp);
|
||||
|
||||
uint containing = CellTransit.FindCellSet(
|
||||
cache, new Vector3(-10f, 12f, 0f), sphereRadius: 0.5f,
|
||||
currentCellId: 0xA9B40150u,
|
||||
out _);
|
||||
uint containing = CellTransit.FindVisibleChildCell(
|
||||
cache,
|
||||
0xA9B40150u,
|
||||
new Vector3(-10f, 12f, 0f),
|
||||
useStabList: true);
|
||||
|
||||
Assert.Equal(0xA9B40150u, containing);
|
||||
Assert.Equal(0u, containing);
|
||||
}
|
||||
|
||||
// ──────────────────────────────────────────────────────────────────
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue