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
|
|
@ -21,6 +21,7 @@ public sealed class LandblockPhysicsPublication : IDisposable
|
|||
uint currentCellId,
|
||||
BuildingInfo[] buildings,
|
||||
uint[] priorStaticOwnerIds,
|
||||
RuntimePhysicsState physics,
|
||||
RuntimeCollisionAdmission collisionAdmission,
|
||||
PreparedLandblockCollisionGeneration preparedGeneration)
|
||||
{
|
||||
|
|
@ -30,6 +31,7 @@ public sealed class LandblockPhysicsPublication : IDisposable
|
|||
CurrentCellId = currentCellId;
|
||||
Buildings = buildings;
|
||||
PriorStaticOwnerIds = priorStaticOwnerIds;
|
||||
Physics = physics;
|
||||
CollisionAdmission = collisionAdmission;
|
||||
PreparedGeneration = preparedGeneration;
|
||||
}
|
||||
|
|
@ -39,6 +41,7 @@ public sealed class LandblockPhysicsPublication : IDisposable
|
|||
internal uint CurrentCellId { get; }
|
||||
internal BuildingInfo[] Buildings { get; }
|
||||
internal uint[] PriorStaticOwnerIds { get; }
|
||||
internal RuntimePhysicsState Physics { get; }
|
||||
internal RuntimeCollisionAdmission CollisionAdmission { get; }
|
||||
internal PreparedLandblockCollisionGeneration PreparedGeneration { get; }
|
||||
internal PhysicsDataCache StagingCache => PreparedGeneration.DataCache;
|
||||
|
|
@ -63,16 +66,19 @@ public sealed class LandblockPhysicsPublication : IDisposable
|
|||
internal int CylinderOwnerCount { get; set; }
|
||||
internal int NoCollisionCount { get; set; }
|
||||
internal int SceneryTried { get; set; }
|
||||
internal uint[]? RefloodOwnerIds { get; set; }
|
||||
internal IReadOnlyList<uint>? RefloodOwnerIds { get; set; }
|
||||
internal int RefloodCursor { get; set; }
|
||||
internal bool RefloodCommitted { get; set; }
|
||||
internal bool SealCommitted { get; set; }
|
||||
internal bool BeginCommitted { get; set; }
|
||||
internal bool CompletionCommitted { get; set; }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (!CompletionCommitted)
|
||||
PreparedGeneration.Dispose();
|
||||
Physics.CancelCollisionGeneration(
|
||||
CollisionAdmission,
|
||||
PreparedGeneration);
|
||||
}
|
||||
|
||||
public uint LandblockId => Build.Landblock.LandblockId;
|
||||
|
|
@ -217,23 +223,34 @@ public sealed class LandblockPhysicsPublisher
|
|||
?? Array.Empty<BuildingInfo>();
|
||||
RuntimeCollisionAdmission collisionAdmission =
|
||||
_physics.BeginCollisionAdmission(build.Landblock.LandblockId);
|
||||
var publication = new LandblockPhysicsPublication(
|
||||
_receiptOwner,
|
||||
build,
|
||||
origin,
|
||||
_physicsDataCache.CellGraph.CurrCell?.Id ?? 0u,
|
||||
buildings,
|
||||
_physicsEngine.ShadowObjects.CaptureStaticOwnersForLandblock(
|
||||
build.Landblock.LandblockId),
|
||||
collisionAdmission,
|
||||
_physics.PrepareCollisionGeneration(collisionAdmission));
|
||||
publication.SetupObjectIds = build.Collisions is { } collisions
|
||||
? [.. collisions.SetupIds]
|
||||
: datBundle.Setups.Keys.Order().ToArray();
|
||||
publication.PreparedGeneration.SetAssetClosure(
|
||||
publication.GfxObjectIds,
|
||||
publication.SetupObjectIds);
|
||||
return publication;
|
||||
PreparedLandblockCollisionGeneration? prepared = null;
|
||||
try
|
||||
{
|
||||
prepared = _physics.PrepareCollisionGeneration(collisionAdmission);
|
||||
var publication = new LandblockPhysicsPublication(
|
||||
_receiptOwner,
|
||||
build,
|
||||
origin,
|
||||
_physicsDataCache.CellGraph.CurrCell?.Id ?? 0u,
|
||||
buildings,
|
||||
_physicsEngine.ShadowObjects.CaptureStaticOwnersForLandblock(
|
||||
build.Landblock.LandblockId),
|
||||
_physics,
|
||||
collisionAdmission,
|
||||
prepared);
|
||||
publication.SetupObjectIds = build.Collisions is { } collisions
|
||||
? [.. collisions.SetupIds]
|
||||
: datBundle.Setups.Keys.Order().ToArray();
|
||||
publication.PreparedGeneration.SetAssetClosure(
|
||||
publication.GfxObjectIds,
|
||||
publication.SetupObjectIds);
|
||||
return publication;
|
||||
}
|
||||
catch
|
||||
{
|
||||
_physics.CancelCollisionGeneration(collisionAdmission, prepared);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -481,15 +498,20 @@ public sealed class LandblockPhysicsPublisher
|
|||
}
|
||||
else if (publication.RefloodOwnerIds is null)
|
||||
{
|
||||
publication.RefloodOwnerIds =
|
||||
_physics.CaptureCollisionDynamicOwners(
|
||||
RuntimeCollisionOwnerCaptureStep capture =
|
||||
_physics.AdvanceCollisionRetainedOwnerCapture(
|
||||
publication.CollisionAdmission,
|
||||
publication.PreparedGeneration);
|
||||
if (capture.Completed)
|
||||
{
|
||||
publication.RefloodOwnerIds =
|
||||
publication.PreparedGeneration.RetainedOwnerIds;
|
||||
}
|
||||
}
|
||||
else if (publication.RefloodCursor
|
||||
< publication.RefloodOwnerIds.Length)
|
||||
< publication.RefloodOwnerIds.Count)
|
||||
{
|
||||
_physics.RefreshCollisionDynamicOwner(
|
||||
_physics.RefreshCollisionRetainedOwner(
|
||||
publication.CollisionAdmission,
|
||||
publication.PreparedGeneration,
|
||||
publication.RefloodOwnerIds[publication.RefloodCursor]);
|
||||
|
|
@ -507,6 +529,25 @@ public sealed class LandblockPhysicsPublisher
|
|||
LogMissingSceneryBounds(landblock, publication.StagingCache);
|
||||
publication.RefloodCommitted = true;
|
||||
}
|
||||
else if (!publication.SealCommitted)
|
||||
{
|
||||
RuntimeCollisionSealStep seal =
|
||||
_physics.AdvanceCollisionGenerationSeal(
|
||||
publication.CollisionAdmission,
|
||||
publication.PreparedGeneration);
|
||||
if (seal.WorkUnits > 1)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Collision seal exceeded its one-unit publication budget.");
|
||||
}
|
||||
publication.SealCommitted = seal.Completed;
|
||||
if (seal.Restarted)
|
||||
{
|
||||
publication.RefloodOwnerIds = null;
|
||||
publication.RefloodCursor = 0;
|
||||
publication.RefloodCommitted = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RuntimeCollisionGenerationCommit commit =
|
||||
|
|
@ -515,9 +556,13 @@ public sealed class LandblockPhysicsPublisher
|
|||
publication.PreparedGeneration);
|
||||
if (!commit.Committed)
|
||||
{
|
||||
publication.RefloodOwnerIds = commit.DirtyDynamicOwnerIds;
|
||||
_physics.RestartCollisionRetainedOwnerCapture(
|
||||
publication.CollisionAdmission,
|
||||
publication.PreparedGeneration);
|
||||
publication.RefloodOwnerIds = null;
|
||||
publication.RefloodCursor = 0;
|
||||
publication.RefloodCommitted = false;
|
||||
publication.SealCommitted = false;
|
||||
_completePublishTicks += Stopwatch.GetTimestamp() - started;
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1011,5 +1056,11 @@ public sealed class LandblockPhysicsPublisher
|
|||
"The physics publication receipt belongs to another publisher.",
|
||||
nameof(publication));
|
||||
}
|
||||
if (!publication.CompletionCommitted)
|
||||
{
|
||||
ObjectDisposedException.ThrowIf(
|
||||
publication.PreparedGeneration.IsDisposed,
|
||||
publication);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -731,13 +731,15 @@ public sealed class LandblockPresentationPipeline
|
|||
< transaction.Build.Landblock.Entities.Count
|
||||
? 1
|
||||
: transaction.PhysicsPublication
|
||||
.RefloodOwnerIds is not null
|
||||
&& transaction.PhysicsPublication
|
||||
.RefloodOwnerIds is null
|
||||
|| transaction.PhysicsPublication
|
||||
.RefloodCursor
|
||||
< transaction.PhysicsPublication
|
||||
.RefloodOwnerIds.Length
|
||||
? 1
|
||||
: 0;
|
||||
.RefloodOwnerIds.Count
|
||||
|| !transaction.PhysicsPublication
|
||||
.SealCommitted
|
||||
? 1
|
||||
: 0;
|
||||
if (!TryRun(
|
||||
new StreamingWorkCost(
|
||||
EntityOperations: entityOperations),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue