fix(animation): harden presentation phase handoffs
Own every borrowed PartArray frame across callbacks, version presentation state across appearance rebinding, reject recursive phase consumption, and preserve static MotionDone when only a stale visual pose is discarded.
This commit is contained in:
parent
a2fd61684a
commit
833520253a
10 changed files with 657 additions and 140 deletions
|
|
@ -139,13 +139,18 @@ internal sealed class LiveEntityAnimationScheduler
|
|||
projectile,
|
||||
objectClockEpoch))
|
||||
{
|
||||
IReadOnlyList<PartTransform>? ownedFrames = schedule.SequenceFrames is { } produced
|
||||
? animation.CaptureScheduleFrames(produced)
|
||||
: null;
|
||||
_schedules[entity.Id] = schedule with
|
||||
{
|
||||
SequenceFrames = ownedFrames,
|
||||
Record = record,
|
||||
Entity = entity,
|
||||
Animation = animation,
|
||||
ObjectClockEpoch = objectClockEpoch,
|
||||
ProjectionMutationVersion = record.ProjectionMutationVersion,
|
||||
PresentationRevision = animation.PresentationRevision,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -217,7 +222,9 @@ internal sealed class LiveEntityAnimationScheduler
|
|||
}
|
||||
|
||||
return new LiveEntityAnimationSchedule(
|
||||
prepared ?? (composeHidden ? sequencer?.SampleCurrentPose() : null),
|
||||
prepared ?? (composeHidden && sequencer is not null
|
||||
? animation?.CaptureSequenceFrames(sequencer.SampleCurrentPose())
|
||||
: null),
|
||||
0f,
|
||||
ComposeParts: advanced || composeHidden);
|
||||
}
|
||||
|
|
@ -311,7 +318,9 @@ internal sealed class LiveEntityAnimationScheduler
|
|||
rootFrame.Origin = Vector3.Zero;
|
||||
rootFrame.Orientation = Quaternion.Identity;
|
||||
if (sequencer is not null)
|
||||
frames = sequencer.Advance(quantum, rootFrame);
|
||||
frames = animation?.CaptureSequenceFrames(
|
||||
sequencer.Advance(quantum, rootFrame))
|
||||
?? sequencer.Advance(quantum, rootFrame);
|
||||
else if (animation is not null)
|
||||
legacyElapsed += quantum;
|
||||
|
||||
|
|
@ -441,7 +450,9 @@ internal sealed class LiveEntityAnimationScheduler
|
|||
if (hidden)
|
||||
{
|
||||
return new LiveEntityAnimationSchedule(
|
||||
sequencer?.SampleCurrentPose(),
|
||||
sequencer is not null && animation is not null
|
||||
? animation.CaptureSequenceFrames(sequencer.SampleCurrentPose())
|
||||
: null,
|
||||
0f,
|
||||
ComposeParts: animation is not null);
|
||||
}
|
||||
|
|
@ -531,4 +542,5 @@ internal readonly record struct LiveEntityAnimationSchedule(
|
|||
WorldEntity? Entity = null,
|
||||
LiveEntityAnimationState? Animation = null,
|
||||
ulong ObjectClockEpoch = 0UL,
|
||||
ulong ProjectionMutationVersion = 0UL);
|
||||
ulong ProjectionMutationVersion = 0UL,
|
||||
ulong PresentationRevision = 0UL);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue