feat(core+app): Phase 6.4 — per-frame animation playback (breathing/idle cycles)
Phase 6.1-6.3 resolved the right cycle and rendered its first frame as a static pose. Phase 6.4 actually walks the cycle over time so creatures, characters, and props animate their idle motion — the breathing the user noticed was missing after Phase 6.1. MotionResolver gains GetIdleCycle() returning IdleCycle(Animation, LowFrame, HighFrame, Framerate). The existing GetIdleFrame() now shares a private ResolveIdleCycleInternal helper, so the resolution algorithm (motion-table override, stance/command priority, fallback) is identical for both entry points and stays in one place. WorldEntity.MeshRefs becomes a get/set so the per-frame tick can swap in fresh per-part transforms without rebuilding the entity. Static decorations never get touched. GameWindow keeps a Dictionary<entityId, AnimatedEntity> for entities whose motion table resolved to a multi-frame, non-zero-framerate cycle. AnimatedEntity caches a per-part template (gfxObjId + surfaceOverrides + scale) snapshot taken from the hydration pass so the tick doesn't redo AnimPartChange/TextureChange resolution every frame — only the per-part transform matrices are recomputed. OnRender calls TickAnimations(dt) before Draw. The tick advances each entity's CurrFrame by dt*Framerate, wraps it inside [LowFrame, HighFrame], samples the corresponding AnimationFrame, and rebuilds the entity's MeshRefs by composing scale → quaternion rotate → translate per part in the same order SetupMesh.Flatten uses, then baking the entity's ObjScale on top in the same PartTransform * scaleMat order as the hydration path. 160 tests green. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
b96167e066
commit
f0fa067566
3 changed files with 222 additions and 10 deletions
|
|
@ -8,7 +8,13 @@ public sealed class WorldEntity
|
|||
public required uint SourceGfxObjOrSetupId { get; init; }
|
||||
public required Vector3 Position { get; init; }
|
||||
public required Quaternion Rotation { get; init; }
|
||||
public required IReadOnlyList<MeshRef> MeshRefs { get; init; }
|
||||
/// <summary>
|
||||
/// Per-part mesh references with their root-relative transforms.
|
||||
/// Mutable so the animation tick can replace it each frame for
|
||||
/// entities that play a cycle (Phase 6.4); static entities set it
|
||||
/// once at hydration and never touch it again.
|
||||
/// </summary>
|
||||
public required IReadOnlyList<MeshRef> MeshRefs { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Optional per-entity palette override (server-specified base +
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue