using System.Numerics; using AcDream.App.World; using AcDream.Core.Physics; using AcDream.Core.Physics.Motion; using AcDream.Core.World; using DatReaderWriter.DBObjs; using DatReaderWriter.Types; namespace AcDream.App.Rendering; /// /// Incarnation-owned live CPartArray presentation state. Time, root /// motion, and hooks remain owned by ; /// this component retains the final part-presentation channels only. /// internal sealed class LiveEntityAnimationState : ILiveEntityAnimationRuntime { public required WorldEntity Entity; WorldEntity ILiveEntityAnimationRuntime.Entity => Entity; uint ILiveEntityAnimationRuntime.CurrentMotion => Sequencer?.CurrentMotion ?? 0u; public required Setup Setup; public required Animation Animation; public required int LowFrame; public required int HighFrame; public required float Framerate; public required float Scale; public required IReadOnlyList PartTemplate; public required IReadOnlyList PartAvailability; public float CurrFrame; public AnimationSequencer? Sequencer; public IReadOnlyList? PreparedSequenceFrames; public bool SequenceAdvancedBeforeAnimationPass; public readonly Frame RootMotionScratch = new(); public readonly MotionDeltaFrame RootMotionDeltaScratch = new(); public readonly List SequenceFramesScratch = new(); public readonly List ScheduleFramesScratch = new(); /// Reusable compact drawable channel, consumed before draw. public readonly List MeshRefsScratch = new(); /// Reusable indexed rigid/effect channel. public readonly List EffectPartPosesScratch = new(); /// /// Indexed visible transforms retained separately from the rigid channel /// because Setup DefaultScale affects geometry but not attachments. /// public readonly List VisualPartPosesScratch = new(); public bool PresentationPosesInitialized; public ulong PresentationRevision { get; private set; } = 1UL; public double LastSequenceDiagnosticTime; public double LastPartDiagnosticTime; public void InvalidatePresentationPoses() { PresentationRevision++; if (PresentationRevision == 0UL) PresentationRevision++; PresentationPosesInitialized = false; VisualPartPosesScratch.Clear(); EffectPartPosesScratch.Clear(); } public IReadOnlyList CaptureSequenceFrames( IReadOnlyList source) { ArgumentNullException.ThrowIfNull(source); SequenceFramesScratch.Clear(); for (int i = 0; i < source.Count; i++) SequenceFramesScratch.Add(source[i]); return SequenceFramesScratch; } public IReadOnlyList CaptureScheduleFrames( IReadOnlyList source) { ArgumentNullException.ThrowIfNull(source); ScheduleFramesScratch.Clear(); for (int i = 0; i < source.Count; i++) ScheduleFramesScratch.Add(source[i]); return ScheduleFramesScratch; } } internal readonly record struct LiveAnimationPartTemplate( uint GfxObjId, IReadOnlyDictionary? SurfaceOverrides, bool IsDrawable);