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
82
src/AcDream.App/Physics/EntityPhysicsHostComposition.cs
Normal file
82
src/AcDream.App/Physics/EntityPhysicsHostComposition.cs
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
using System.Numerics;
|
||||
using AcDream.App.World;
|
||||
using AcDream.Core.Physics;
|
||||
using AcDream.Core.Physics.Motion;
|
||||
using AcDream.Runtime.Physics;
|
||||
|
||||
namespace AcDream.App.Physics;
|
||||
|
||||
/// <summary>
|
||||
/// Graphical configuration factory for Runtime's presentation-free
|
||||
/// <see cref="EntityPhysicsHost"/>. Runtime owns exact-incarnation
|
||||
/// installation, stable identity, manager lifetime, and lookup.
|
||||
/// </summary>
|
||||
internal static class EntityPhysicsHostComposition
|
||||
{
|
||||
internal static EntityPhysicsHost InstallOrRebind(
|
||||
LiveEntityRuntime runtime,
|
||||
LiveEntityRecord expectedRecord,
|
||||
EntityPhysicsHost configuration)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(runtime);
|
||||
ArgumentNullException.ThrowIfNull(expectedRecord);
|
||||
ArgumentNullException.ThrowIfNull(configuration);
|
||||
bool ProjectionIsCurrent() =>
|
||||
runtime.TryGetRecord(
|
||||
expectedRecord.ServerGuid,
|
||||
out LiveEntityRecord current)
|
||||
&& ReferenceEquals(current, expectedRecord);
|
||||
return runtime.Physics.InstallOrRebindPhysicsHost(
|
||||
expectedRecord.Canonical,
|
||||
configuration,
|
||||
ProjectionIsCurrent);
|
||||
}
|
||||
|
||||
internal static EntityPhysicsHost SelectStableHostWithoutRebind(
|
||||
LiveEntityRuntime runtime,
|
||||
LiveEntityRecord expectedRecord,
|
||||
EntityPhysicsHost configuration)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(runtime);
|
||||
ArgumentNullException.ThrowIfNull(expectedRecord);
|
||||
ArgumentNullException.ThrowIfNull(configuration);
|
||||
bool ProjectionIsCurrent() =>
|
||||
runtime.TryGetRecord(
|
||||
expectedRecord.ServerGuid,
|
||||
out LiveEntityRecord current)
|
||||
&& ReferenceEquals(current, expectedRecord);
|
||||
return runtime.Physics.SelectStablePhysicsHostWithoutRebind(
|
||||
expectedRecord.Canonical,
|
||||
configuration,
|
||||
ProjectionIsCurrent);
|
||||
}
|
||||
|
||||
internal static EntityPhysicsHost CreateMinimal(
|
||||
LiveEntityRecord record,
|
||||
Func<uint, IPhysicsObjHost?> resolve,
|
||||
Func<double> now)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(record);
|
||||
ArgumentNullException.ThrowIfNull(resolve);
|
||||
ArgumentNullException.ThrowIfNull(now);
|
||||
return new EntityPhysicsHost(
|
||||
record.ServerGuid,
|
||||
getPosition: () => new Position(
|
||||
record.FullCellId,
|
||||
record.WorldEntity?.Position
|
||||
?? record.PhysicsBody?.Position
|
||||
?? Vector3.Zero,
|
||||
record.WorldEntity?.Rotation
|
||||
?? record.PhysicsBody?.Orientation
|
||||
?? Quaternion.Identity),
|
||||
getVelocity: () => record.PhysicsBody?.Velocity ?? Vector3.Zero,
|
||||
getRadius: () => 0f,
|
||||
inContact: () => record.PhysicsBody?.InContact ?? true,
|
||||
minterpMaxSpeed: () => null,
|
||||
curTime: now,
|
||||
physicsTimerTime: now,
|
||||
getObjectA: resolve,
|
||||
handleUpdateTarget: _ => { },
|
||||
interruptCurrentMovement: () => { });
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue