fix(physics): seal collision generations before activation
This commit is contained in:
parent
be94bc9b06
commit
d94145e6b8
15 changed files with 1556 additions and 410 deletions
|
|
@ -12,6 +12,7 @@ using AcDream.Headless.Platform;
|
|||
using AcDream.Runtime;
|
||||
using AcDream.Runtime.Entities;
|
||||
using AcDream.Runtime.Gameplay;
|
||||
using AcDream.Runtime.Physics;
|
||||
using AcDream.Runtime.Session;
|
||||
using AcDream.Runtime.World;
|
||||
|
||||
|
|
@ -373,6 +374,72 @@ public sealed class HeadlessSessionHostTests
|
|||
Assert.Equal(2, collision.CenterCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CollisionTransactionCancelsPostAdmissionFaultWithoutWithdrawingActiveWorld()
|
||||
{
|
||||
using var lifetime = new RuntimeEntityObjectLifetime();
|
||||
RuntimePhysicsState physics = lifetime.Physics;
|
||||
const uint landblockId = 0xA9B4FFFFu;
|
||||
_ = HeadlessCollisionGenerationTransaction.Execute(
|
||||
physics,
|
||||
landblockId,
|
||||
afterAdmission: null,
|
||||
(admission, prepared) =>
|
||||
physics.StageCollisionAssets(
|
||||
admission,
|
||||
prepared,
|
||||
CollisionAssets(landblockId, 10f)));
|
||||
|
||||
Assert.Throws<FixtureCollisionPublicationException>(() =>
|
||||
HeadlessCollisionGenerationTransaction.Execute(
|
||||
physics,
|
||||
landblockId,
|
||||
_ => throw new FixtureCollisionPublicationException(),
|
||||
(_, _) => throw new InvalidOperationException(
|
||||
"Staging must not run after the injected admission fault.")));
|
||||
|
||||
Assert.Equal(10f, physics.Engine.SampleTerrainZ(1f, 1f));
|
||||
RuntimePhysicsOwnershipSnapshot ownership = physics.CaptureOwnership();
|
||||
Assert.Equal(1, ownership.LandblockCount);
|
||||
Assert.Equal(0, ownership.CollisionAdmissionCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CollisionTransactionCancelsStagingFaultWithoutWithdrawingActiveWorld()
|
||||
{
|
||||
using var lifetime = new RuntimeEntityObjectLifetime();
|
||||
RuntimePhysicsState physics = lifetime.Physics;
|
||||
const uint landblockId = 0xA9B4FFFFu;
|
||||
_ = HeadlessCollisionGenerationTransaction.Execute(
|
||||
physics,
|
||||
landblockId,
|
||||
afterAdmission: null,
|
||||
(admission, prepared) =>
|
||||
physics.StageCollisionAssets(
|
||||
admission,
|
||||
prepared,
|
||||
CollisionAssets(landblockId, 10f)));
|
||||
|
||||
Assert.Throws<FixtureCollisionPublicationException>(() =>
|
||||
HeadlessCollisionGenerationTransaction.Execute(
|
||||
physics,
|
||||
landblockId,
|
||||
afterAdmission: null,
|
||||
(admission, prepared) =>
|
||||
{
|
||||
physics.StageCollisionAssets(
|
||||
admission,
|
||||
prepared,
|
||||
CollisionAssets(landblockId, 25f));
|
||||
throw new FixtureCollisionPublicationException();
|
||||
}));
|
||||
|
||||
Assert.Equal(10f, physics.Engine.SampleTerrainZ(1f, 1f));
|
||||
RuntimePhysicsOwnershipSnapshot ownership = physics.CaptureOwnership();
|
||||
Assert.Equal(1, ownership.LandblockCount);
|
||||
Assert.Equal(0, ownership.CollisionAdmissionCount);
|
||||
}
|
||||
|
||||
private static HeadlessSessionDescriptor Descriptor(
|
||||
HeadlessCredentialProviderKind provider =
|
||||
HeadlessCredentialProviderKind.Environment,
|
||||
|
|
@ -422,6 +489,25 @@ public sealed class HeadlessSessionHostTests
|
|||
runtime.MovementOwner.Controller = controller;
|
||||
}
|
||||
|
||||
private static RuntimeLandblockCollisionAssets CollisionAssets(
|
||||
uint landblockId,
|
||||
float terrainHeight)
|
||||
{
|
||||
var heights = new byte[81];
|
||||
var table = new float[256];
|
||||
table[0] = terrainHeight;
|
||||
return new RuntimeLandblockCollisionAssets(
|
||||
landblockId,
|
||||
new TerrainSurface(heights, table),
|
||||
Array.Empty<CellSurface>(),
|
||||
Array.Empty<PortalPlane>(),
|
||||
0f,
|
||||
0f,
|
||||
0u);
|
||||
}
|
||||
|
||||
private sealed class FixtureCollisionPublicationException : Exception;
|
||||
|
||||
private static void AddFlatLandblock(PhysicsEngine engine)
|
||||
{
|
||||
var heights = new byte[81];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue