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
|
|
@ -10,46 +10,67 @@ namespace AcDream.Core.Tests.World.Cells;
|
|||
|
||||
public class EnvCellTests
|
||||
{
|
||||
private static EnvCell Make(Vector3 min, Vector3 max, Matrix4x4? transform = null)
|
||||
private static readonly UcgCellPortal[] OnePortal =
|
||||
[new UcgCellPortal(0xA9B4_0175u, 0, 0, 0)];
|
||||
|
||||
private static EnvCell Make(
|
||||
CellBSPNode? root,
|
||||
bool prepared,
|
||||
bool hasPortals,
|
||||
Matrix4x4? transform = null)
|
||||
{
|
||||
var t = transform ?? Matrix4x4.Identity;
|
||||
Matrix4x4.Invert(t, out var inv);
|
||||
return new EnvCell(0xA9B40174u, t, inv, min, max,
|
||||
System.Array.Empty<UcgCellPortal>(), System.Array.Empty<uint>(),
|
||||
seenOutside: false, containmentBsp: null);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PointInCell_NullBsp_Aabb_InsideIsTrue()
|
||||
=> Assert.True(Make(new Vector3(0,0,0), new Vector3(10,10,10)).PointInCell(new Vector3(5,5,5)));
|
||||
|
||||
[Fact]
|
||||
public void PointInCell_NullBsp_Aabb_OutsideIsFalse()
|
||||
=> Assert.False(Make(new Vector3(0,0,0), new Vector3(10,10,10)).PointInCell(new Vector3(20,5,5)));
|
||||
|
||||
[Fact]
|
||||
public void PointInCell_LoadedNullRoot_IsUniversallyInside()
|
||||
{
|
||||
var cell = new EnvCell(
|
||||
0xA9B4_0174u,
|
||||
Matrix4x4.Identity,
|
||||
Matrix4x4.Identity,
|
||||
Vector3.Zero,
|
||||
return new EnvCell(
|
||||
0xA9B40174u,
|
||||
t,
|
||||
inv,
|
||||
-Vector3.One,
|
||||
Vector3.One,
|
||||
Array.Empty<UcgCellPortal>(),
|
||||
hasPortals ? OnePortal : Array.Empty<UcgCellPortal>(),
|
||||
Array.Empty<uint>(),
|
||||
seenOutside: false,
|
||||
containmentBsp: new CellBSPTree { Root = null });
|
||||
containmentBsp: new CellBSPTree { Root = root },
|
||||
flatContainmentBsp: prepared
|
||||
? FlatCollisionAssetBuilder.FlattenCellContainmentBsp(root)
|
||||
: null);
|
||||
}
|
||||
|
||||
Assert.True(cell.PointInCell(new Vector3(10_000f, -10_000f, 500f)));
|
||||
[Theory]
|
||||
[InlineData(false)]
|
||||
[InlineData(true)]
|
||||
public void PointInCell_ZeroPortals_RejectsBeforeContainment(bool prepared)
|
||||
{
|
||||
var root = new CellBSPNode { Type = BSPNodeType.Leaf };
|
||||
|
||||
Assert.False(Make(root, prepared, hasPortals: false).PointInCell(Vector3.Zero));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(false)]
|
||||
[InlineData(true)]
|
||||
public void PointInCell_RootlessContainment_IsRejected(bool prepared)
|
||||
{
|
||||
Assert.False(Make(null, prepared, hasPortals: true).PointInCell(Vector3.Zero));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PointInCell_TransformsWorldToLocalBeforeTesting()
|
||||
{
|
||||
var c = Make(new Vector3(0,0,0), new Vector3(10,10,10), Matrix4x4.CreateTranslation(100,0,0));
|
||||
Assert.True(c.PointInCell(new Vector3(105,5,5)));
|
||||
Assert.False(c.PointInCell(new Vector3(5,5,5)));
|
||||
var root = new CellBSPNode
|
||||
{
|
||||
Type = BSPNodeType.BPIn,
|
||||
SplittingPlane = new Plane(Vector3.UnitX, 0f),
|
||||
PosNode = new CellBSPNode { Type = BSPNodeType.Leaf },
|
||||
};
|
||||
var cell = Make(
|
||||
root,
|
||||
prepared: false,
|
||||
hasPortals: true,
|
||||
transform: Matrix4x4.CreateTranslation(100f, 0f, 0f));
|
||||
|
||||
Assert.True(cell.PointInCell(new Vector3(105f, 0f, 0f)));
|
||||
Assert.False(cell.PointInCell(new Vector3(95f, 0f, 0f)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -74,7 +95,7 @@ public class EnvCellTests
|
|||
Matrix4x4.Identity,
|
||||
-Vector3.One,
|
||||
Vector3.One,
|
||||
Array.Empty<UcgCellPortal>(),
|
||||
OnePortal,
|
||||
Array.Empty<uint>(),
|
||||
seenOutside: false,
|
||||
containmentBsp: new CellBSPTree { Root = graphRoot },
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue