refactor(runtime): own per-session physics simulation
Move the sole PhysicsEngine, production cache, collision admissions, canonical bodies and hosts, remote components, ordinary/remote worksets, simulation, cell commits, and shadow synchronization under RuntimeEntityObjectLifetime. Keep App as the prepared-asset, animation-input, and render-projection adapter while preserving the named-retail update and collision order. Add exact-incarnation, object-clock, callback-reentrancy, GUID-reuse, two-runtime isolation, source ownership, collision publication, and graphical projection coverage. Release build and the complete 8,588-test solution pass. Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
parent
0dc3bfdeff
commit
7e6033d0ad
39 changed files with 3685 additions and 1722 deletions
|
|
@ -2,6 +2,7 @@ using System.Diagnostics;
|
|||
using System.Numerics;
|
||||
using AcDream.Core.Physics;
|
||||
using AcDream.Core.World;
|
||||
using AcDream.Runtime.Physics;
|
||||
using DatReaderWriter.Types;
|
||||
|
||||
namespace AcDream.App.Streaming;
|
||||
|
|
@ -19,7 +20,8 @@ public sealed class LandblockPhysicsPublication
|
|||
Vector3 origin,
|
||||
uint currentCellId,
|
||||
BuildingInfo[] buildings,
|
||||
uint[] priorStaticOwnerIds)
|
||||
uint[] priorStaticOwnerIds,
|
||||
RuntimeCollisionAdmission collisionAdmission)
|
||||
{
|
||||
Owner = owner;
|
||||
Build = build;
|
||||
|
|
@ -27,6 +29,7 @@ public sealed class LandblockPhysicsPublication
|
|||
CurrentCellId = currentCellId;
|
||||
Buildings = buildings;
|
||||
PriorStaticOwnerIds = priorStaticOwnerIds;
|
||||
CollisionAdmission = collisionAdmission;
|
||||
}
|
||||
|
||||
internal object Owner { get; }
|
||||
|
|
@ -34,6 +37,7 @@ public sealed class LandblockPhysicsPublication
|
|||
internal uint CurrentCellId { get; }
|
||||
internal BuildingInfo[] Buildings { get; }
|
||||
internal uint[] PriorStaticOwnerIds { get; }
|
||||
internal RuntimeCollisionAdmission CollisionAdmission { get; }
|
||||
internal SortedSet<uint> GfxObjectIdSet { get; } = new();
|
||||
internal uint[] GfxObjectIds { get; set; } = Array.Empty<uint>();
|
||||
internal int PreparationCursor { get; set; }
|
||||
|
|
@ -102,6 +106,7 @@ public readonly record struct LandblockPhysicsPublisherDiagnostics(
|
|||
public sealed class LandblockPhysicsPublisher
|
||||
{
|
||||
private readonly object _receiptOwner = new();
|
||||
private readonly RuntimePhysicsState _physics;
|
||||
private readonly PhysicsEngine _physicsEngine;
|
||||
private readonly PhysicsDataCache _physicsDataCache;
|
||||
private readonly float[] _heightTable;
|
||||
|
|
@ -121,21 +126,19 @@ public sealed class LandblockPhysicsPublisher
|
|||
private long _fullRemovalCount;
|
||||
|
||||
public LandblockPhysicsPublisher(
|
||||
PhysicsEngine physicsEngine,
|
||||
RuntimePhysicsState physics,
|
||||
float[] heightTable)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(physicsEngine);
|
||||
ArgumentNullException.ThrowIfNull(physics);
|
||||
ArgumentNullException.ThrowIfNull(heightTable);
|
||||
if (heightTable.Length < 256)
|
||||
throw new ArgumentException(
|
||||
"The retail terrain height table must contain at least 256 entries.",
|
||||
nameof(heightTable));
|
||||
|
||||
_physicsEngine = physicsEngine;
|
||||
_physicsDataCache = physicsEngine.DataCache
|
||||
?? throw new ArgumentException(
|
||||
"The physics engine must own its canonical data cache before publication wiring.",
|
||||
nameof(physicsEngine));
|
||||
_physics = physics;
|
||||
_physicsEngine = physics.Engine;
|
||||
_physicsDataCache = physics.DataCache;
|
||||
_heightTable = (float[])heightTable.Clone();
|
||||
}
|
||||
|
||||
|
|
@ -208,6 +211,8 @@ public sealed class LandblockPhysicsPublisher
|
|||
_physicsDataCache.CellGraph.CurrCell?.Id ?? 0u,
|
||||
buildings,
|
||||
_physicsEngine.ShadowObjects.CaptureStaticOwnersForLandblock(
|
||||
build.Landblock.LandblockId),
|
||||
_physics.BeginCollisionAdmission(
|
||||
build.Landblock.LandblockId));
|
||||
publication.SetupObjectIds = build.Collisions is { } collisions
|
||||
? [.. collisions.SetupIds]
|
||||
|
|
@ -332,18 +337,16 @@ public sealed class LandblockPhysicsPublisher
|
|||
}
|
||||
else if (!publication.BaseCommitted)
|
||||
{
|
||||
_physicsEngine.AddLandblock(
|
||||
landblock.LandblockId,
|
||||
publication.TerrainSurface,
|
||||
publication.CellSurfaces,
|
||||
publication.PortalPlanes,
|
||||
origin.X,
|
||||
origin.Y);
|
||||
if ((publication.CurrentCellId & 0xFFFF0000u)
|
||||
== (landblock.LandblockId & 0xFFFF0000u))
|
||||
{
|
||||
_physicsEngine.UpdatePlayerCurrCell(publication.CurrentCellId);
|
||||
}
|
||||
_physics.AdmitCollisionAssets(
|
||||
publication.CollisionAdmission,
|
||||
new RuntimeLandblockCollisionAssets(
|
||||
landblock.LandblockId,
|
||||
publication.TerrainSurface,
|
||||
publication.CellSurfaces.ToArray(),
|
||||
publication.PortalPlanes.ToArray(),
|
||||
origin.X,
|
||||
origin.Y,
|
||||
publication.CurrentCellId));
|
||||
publication.BaseCommitted = true;
|
||||
}
|
||||
else
|
||||
|
|
@ -481,6 +484,8 @@ public sealed class LandblockPhysicsPublisher
|
|||
}
|
||||
else
|
||||
{
|
||||
_physics.CompleteCollisionAdmission(
|
||||
publication.CollisionAdmission);
|
||||
_staticBspOwnerCount += publication.BspOwnerCount;
|
||||
_staticCylinderOwnerCount += publication.CylinderOwnerCount;
|
||||
publication.CompletionCommitted = true;
|
||||
|
|
@ -493,13 +498,13 @@ public sealed class LandblockPhysicsPublisher
|
|||
|
||||
public void DemoteToTerrain(uint landblockId)
|
||||
{
|
||||
_physicsEngine.DemoteLandblockToTerrain(landblockId);
|
||||
_physics.DemoteCollisionToTerrain(landblockId);
|
||||
_demotionCount++;
|
||||
}
|
||||
|
||||
public void RemoveLandblock(uint landblockId)
|
||||
{
|
||||
_physicsEngine.RemoveLandblock(landblockId);
|
||||
_physics.WithdrawCollision(landblockId);
|
||||
_fullRemovalCount++;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue