refactor(runtime): extract the live object frame
This commit is contained in:
parent
99a3e819c4
commit
4e4aac2c5a
27 changed files with 1217 additions and 371 deletions
|
|
@ -1,4 +1,6 @@
|
|||
using System.Numerics;
|
||||
using AcDream.App.Input;
|
||||
using AcDream.App.Rendering.Vfx;
|
||||
using AcDream.App.Physics;
|
||||
using AcDream.App.World;
|
||||
using AcDream.Core.Physics;
|
||||
|
|
@ -17,41 +19,38 @@ namespace AcDream.App.Rendering;
|
|||
/// </summary>
|
||||
internal sealed class LiveEntityAnimationScheduler
|
||||
{
|
||||
private readonly Func<LiveEntityRuntime?> _liveEntities;
|
||||
private readonly Func<uint> _localPlayerGuid;
|
||||
private readonly LiveEntityRuntime _liveEntities;
|
||||
private readonly ILocalPlayerIdentitySource _localPlayer;
|
||||
private readonly RemotePhysicsUpdater _remotePhysics;
|
||||
private readonly LiveEntityOrdinaryPhysicsUpdater _ordinaryPhysics;
|
||||
private readonly Func<ProjectileController?> _projectiles;
|
||||
private readonly Action<WorldEntity> _publishRootPose;
|
||||
private readonly Action<uint, AnimationSequencer> _captureAnimationHooks;
|
||||
private readonly ProjectileController _projectiles;
|
||||
private readonly IEntityRootPosePublisher _rootPoses;
|
||||
private readonly IAnimationHookCaptureSink _animationHooks;
|
||||
private readonly List<LiveEntityRecord> _rootSnapshot = new();
|
||||
private readonly Dictionary<uint, LiveEntityAnimationSchedule> _schedules = new();
|
||||
private readonly Frame _rootFrameScratch = new();
|
||||
private readonly MotionDeltaFrame _rootDeltaScratch = new();
|
||||
|
||||
public LiveEntityAnimationScheduler(
|
||||
Func<LiveEntityRuntime?> liveEntities,
|
||||
Func<uint> localPlayerGuid,
|
||||
LiveEntityRuntime liveEntities,
|
||||
ILocalPlayerIdentitySource localPlayer,
|
||||
RemotePhysicsUpdater remotePhysics,
|
||||
LiveEntityOrdinaryPhysicsUpdater ordinaryPhysics,
|
||||
Func<ProjectileController?> projectiles,
|
||||
Action<WorldEntity> publishRootPose,
|
||||
Action<uint, AnimationSequencer> captureAnimationHooks)
|
||||
ProjectileController projectiles,
|
||||
IEntityRootPosePublisher rootPoses,
|
||||
IAnimationHookCaptureSink animationHooks)
|
||||
{
|
||||
_liveEntities = liveEntities
|
||||
?? throw new ArgumentNullException(nameof(liveEntities));
|
||||
_localPlayerGuid = localPlayerGuid
|
||||
?? throw new ArgumentNullException(nameof(localPlayerGuid));
|
||||
_localPlayer = localPlayer
|
||||
?? throw new ArgumentNullException(nameof(localPlayer));
|
||||
_remotePhysics = remotePhysics
|
||||
?? throw new ArgumentNullException(nameof(remotePhysics));
|
||||
_ordinaryPhysics = ordinaryPhysics
|
||||
?? throw new ArgumentNullException(nameof(ordinaryPhysics));
|
||||
_projectiles = projectiles
|
||||
?? throw new ArgumentNullException(nameof(projectiles));
|
||||
_publishRootPose = publishRootPose
|
||||
?? throw new ArgumentNullException(nameof(publishRootPose));
|
||||
_captureAnimationHooks = captureAnimationHooks
|
||||
?? throw new ArgumentNullException(nameof(captureAnimationHooks));
|
||||
_projectiles = projectiles ?? throw new ArgumentNullException(nameof(projectiles));
|
||||
_rootPoses = rootPoses ?? throw new ArgumentNullException(nameof(rootPoses));
|
||||
_animationHooks = animationHooks ?? throw new ArgumentNullException(nameof(animationHooks));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -69,9 +68,7 @@ internal sealed class LiveEntityAnimationScheduler
|
|||
Action<LiveEntityRecord, LiveEntityAnimationState>? prepareAnimation = null)
|
||||
{
|
||||
_schedules.Clear();
|
||||
LiveEntityRuntime? runtime = _liveEntities();
|
||||
if (runtime is null)
|
||||
return _schedules;
|
||||
LiveEntityRuntime runtime = _liveEntities;
|
||||
|
||||
runtime.CopySpatialRootObjectRecordsTo(_rootSnapshot);
|
||||
foreach (LiveEntityRecord record in _rootSnapshot)
|
||||
|
|
@ -180,7 +177,7 @@ internal sealed class LiveEntityAnimationScheduler
|
|||
// PlayerMovementController owns this exact record clock and advances
|
||||
// its PartArray before local collision. Consume that prepared pose;
|
||||
// never tick the same clock or sequence a second time here.
|
||||
if (serverGuid == _localPlayerGuid())
|
||||
if (serverGuid == _localPlayer.ServerGuid)
|
||||
{
|
||||
IReadOnlyList<PartTransform>? prepared =
|
||||
animation?.PreparedSequenceFrames;
|
||||
|
|
@ -208,7 +205,7 @@ internal sealed class LiveEntityAnimationScheduler
|
|||
// that are smaller than an admitted object quantum. Publish that
|
||||
// current root independently of PartArray recomposition so local
|
||||
// attached effects and lights never trail the rendered character.
|
||||
_publishRootPose(entity);
|
||||
_rootPoses.UpdateRoot(entity);
|
||||
if (!IsCurrent(
|
||||
runtime,
|
||||
record,
|
||||
|
|
@ -249,7 +246,7 @@ internal sealed class LiveEntityAnimationScheduler
|
|||
IReadOnlyList<PartTransform>? frames = null;
|
||||
float legacyElapsed = 0f;
|
||||
bool completed = true;
|
||||
ProjectileController? projectileController = _projectiles();
|
||||
ProjectileController projectileController = _projectiles;
|
||||
bool projectileHandlesMovement = projectile is not null
|
||||
&& projectileController?.HandlesMovement(serverGuid) == true;
|
||||
float objectScale = animation?.Scale
|
||||
|
|
@ -275,7 +272,7 @@ internal sealed class LiveEntityAnimationScheduler
|
|||
entity,
|
||||
quantum,
|
||||
sequencer?.Manager,
|
||||
_captureAnimationHooks,
|
||||
_animationHooks.Capture,
|
||||
sequencer,
|
||||
runtime,
|
||||
record,
|
||||
|
|
@ -289,7 +286,7 @@ internal sealed class LiveEntityAnimationScheduler
|
|||
{
|
||||
if (sequencer is not null)
|
||||
{
|
||||
_captureAnimationHooks(entity.Id, sequencer);
|
||||
_animationHooks.Capture(entity.Id, sequencer);
|
||||
if (!IsCurrent(
|
||||
runtime,
|
||||
record,
|
||||
|
|
@ -355,7 +352,7 @@ internal sealed class LiveEntityAnimationScheduler
|
|||
rootDelta,
|
||||
liveCenterX,
|
||||
liveCenterY,
|
||||
_captureAnimationHooks,
|
||||
_animationHooks.Capture,
|
||||
runtime,
|
||||
record,
|
||||
objectClockEpoch))
|
||||
|
|
@ -381,7 +378,7 @@ internal sealed class LiveEntityAnimationScheduler
|
|||
liveCenterY,
|
||||
objectClockEpoch,
|
||||
sequencer,
|
||||
_captureAnimationHooks))
|
||||
_animationHooks.Capture))
|
||||
{
|
||||
completed = false;
|
||||
break;
|
||||
|
|
@ -405,7 +402,7 @@ internal sealed class LiveEntityAnimationScheduler
|
|||
out projectileStep) == true;
|
||||
|
||||
if (!ordinaryBodyHandlesMovement && sequencer is not null)
|
||||
_captureAnimationHooks(entity.Id, sequencer);
|
||||
_animationHooks.Capture(entity.Id, sequencer);
|
||||
if (!IsCurrent(runtime, record, entity, animation, remote, projectile, objectClockEpoch))
|
||||
{
|
||||
completed = false;
|
||||
|
|
@ -443,7 +440,7 @@ internal sealed class LiveEntityAnimationScheduler
|
|||
return default;
|
||||
}
|
||||
|
||||
_publishRootPose(entity);
|
||||
_rootPoses.UpdateRoot(entity);
|
||||
if (!IsCurrent(runtime, record, entity, animation, remote, projectile, objectClockEpoch))
|
||||
return default;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue