154 lines
5.3 KiB
C#
154 lines
5.3 KiB
C#
using System;
|
|
using System.Numerics;
|
|
using AcDream.Core.Physics;
|
|
using AcDream.Core.World.Cells;
|
|
using Xunit;
|
|
|
|
namespace AcDream.Core.Tests.Physics;
|
|
|
|
public class PhysicsEngineResidencyTests
|
|
{
|
|
[Fact]
|
|
public void IsLandblockTerrainResident_trueOnlyAfterAddLandblock()
|
|
{
|
|
var eng = new PhysicsEngine();
|
|
uint canonical = 0xA9B4FFFFu; // canonical (streaming) form
|
|
uint lbId = canonical & 0xFFFF0000u; // AddLandblock id
|
|
|
|
Assert.False(eng.IsLandblockTerrainResident(canonical));
|
|
|
|
eng.AddLandblock(lbId, terrain: null!, cells: Array.Empty<CellSurface>(),
|
|
portals: Array.Empty<PortalPlane>(), worldOffsetX: 0f, worldOffsetY: 0f);
|
|
|
|
Assert.True(eng.IsLandblockTerrainResident(canonical));
|
|
}
|
|
|
|
[Fact]
|
|
public void IsLandblockTerrainResident_matchesOnHigh16_acceptsCellResolvedId()
|
|
{
|
|
var eng = new PhysicsEngine();
|
|
eng.AddLandblock(0xA9B40000u, null!, Array.Empty<CellSurface>(),
|
|
Array.Empty<PortalPlane>(), 0f, 0f);
|
|
Assert.True(eng.IsLandblockTerrainResident(0xA9B40019u)); // cell-resolved id, same LB
|
|
Assert.False(eng.IsLandblockTerrainResident(0xC6A90019u)); // different LB
|
|
}
|
|
|
|
[Fact]
|
|
public void DemoteLandblockToTerrain_RemovesEnvCellsButPreservesTerrainResidency()
|
|
{
|
|
const uint landblockId = 0xA9B4FFFFu;
|
|
var cache = new PhysicsDataCache();
|
|
var engine = new PhysicsEngine { DataCache = cache };
|
|
engine.AddLandblock(
|
|
landblockId,
|
|
new TerrainSurface(new byte[81], new float[256]),
|
|
Array.Empty<CellSurface>(),
|
|
Array.Empty<PortalPlane>(),
|
|
0f,
|
|
0f);
|
|
cache.CellGraph.Add(new EnvCell(
|
|
0xA9B40174u,
|
|
Matrix4x4.Identity,
|
|
Matrix4x4.Identity,
|
|
Vector3.Zero,
|
|
Vector3.One,
|
|
Array.Empty<CellPortal>(),
|
|
Array.Empty<uint>(),
|
|
false,
|
|
null));
|
|
|
|
engine.DemoteLandblockToTerrain(landblockId);
|
|
|
|
Assert.True(engine.IsLandblockTerrainResident(landblockId));
|
|
Assert.Null(cache.CellGraph.GetVisible(0xA9B40174u));
|
|
Assert.IsType<LandCell>(cache.CellGraph.GetVisible(0xA9B40001u));
|
|
}
|
|
|
|
[Fact]
|
|
public void DemoteLandblockToTerrain_DeregistersCrossBoundaryStaticButRetainsDynamic()
|
|
{
|
|
const uint landblockId = 0xA9B4FFFFu;
|
|
const uint adjacentCell = 0xAAB40001u;
|
|
const uint staticId = 100u;
|
|
const uint dynamicId = 200u;
|
|
var engine = new PhysicsEngine();
|
|
engine.AddLandblock(
|
|
landblockId,
|
|
new TerrainSurface(new byte[81], new float[256]),
|
|
Array.Empty<CellSurface>(),
|
|
Array.Empty<PortalPlane>(),
|
|
0f,
|
|
0f);
|
|
var seamPosition = new Vector3(191.5f, 12f, 1f);
|
|
engine.ShadowObjects.Register(
|
|
staticId,
|
|
0x01000001u,
|
|
seamPosition,
|
|
Quaternion.Identity,
|
|
2f,
|
|
0f,
|
|
0f,
|
|
landblockId,
|
|
isStatic: true);
|
|
engine.ShadowObjects.Register(
|
|
dynamicId,
|
|
0x01000002u,
|
|
seamPosition,
|
|
Quaternion.Identity,
|
|
2f,
|
|
0f,
|
|
0f,
|
|
landblockId,
|
|
isStatic: false);
|
|
Assert.Contains(
|
|
engine.ShadowObjects.GetObjectsInCell(adjacentCell),
|
|
entry => entry.EntityId == staticId);
|
|
Assert.Contains(
|
|
engine.ShadowObjects.GetObjectsInCell(adjacentCell),
|
|
entry => entry.EntityId == dynamicId);
|
|
|
|
engine.DemoteLandblockToTerrain(landblockId);
|
|
|
|
Assert.DoesNotContain(
|
|
engine.ShadowObjects.AllEntriesForDebug(),
|
|
entry => entry.EntityId == staticId);
|
|
Assert.Contains(
|
|
engine.ShadowObjects.GetObjectsInCell(adjacentCell),
|
|
entry => entry.EntityId == dynamicId);
|
|
Assert.Equal(1, engine.ShadowObjects.RetainedRegistrationCount);
|
|
}
|
|
|
|
[Fact]
|
|
public void RemoveLandblock_DeregistersCrossBoundaryStaticButRetainsDynamic()
|
|
{
|
|
const uint landblockId = 0xA9B4FFFFu;
|
|
const uint adjacentCell = 0xAAB40001u;
|
|
const uint staticId = 300u;
|
|
const uint dynamicId = 400u;
|
|
var engine = new PhysicsEngine();
|
|
engine.AddLandblock(
|
|
landblockId,
|
|
new TerrainSurface(new byte[81], new float[256]),
|
|
Array.Empty<CellSurface>(),
|
|
Array.Empty<PortalPlane>(),
|
|
0f,
|
|
0f);
|
|
var seamPosition = new Vector3(191.5f, 12f, 1f);
|
|
engine.ShadowObjects.Register(
|
|
staticId, 0x01000003u, seamPosition, Quaternion.Identity, 2f,
|
|
0f, 0f, landblockId, isStatic: true);
|
|
engine.ShadowObjects.Register(
|
|
dynamicId, 0x01000004u, seamPosition, Quaternion.Identity, 2f,
|
|
0f, 0f, landblockId, isStatic: false);
|
|
|
|
engine.RemoveLandblock(landblockId);
|
|
|
|
Assert.DoesNotContain(
|
|
engine.ShadowObjects.AllEntriesForDebug(),
|
|
entry => entry.EntityId == staticId);
|
|
Assert.Contains(
|
|
engine.ShadowObjects.GetObjectsInCell(adjacentCell),
|
|
entry => entry.EntityId == dynamicId);
|
|
Assert.Equal(1, engine.ShadowObjects.RetainedRegistrationCount);
|
|
}
|
|
}
|