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);