Animation System Overview

Production-grade animation system with skeletal animation, blend trees, state machines, IK, and root motion. Built for performance with zero-allocation hot paths and SIMD-accelerated bone transforms.

Animation Architecture#

The animation system is built on a high-performance ECS architecture with several specialized subsystems:

Core Components#

Animation Registry

Central registry for animation clips with validation, metadata, and O(1) lookup by asset UUID, asset ID, or clip name. Ensures single source of truth for clip metadata.

Bone Registry

Fast bone hierarchy tracking with hash-based lookup for animation bone masking. Enables per-bone animation control (e.g., upper body vs lower body).

Animation State Machine

Race-condition-safe state machine with priority-based transitions, transactional updates, event buffering, and zero-GC hot paths. Pooled instances for entity spawn/despawn.

Blend Tree Evaluator

Zero-allocation evaluator for 1D and 2D blend trees with linear interpolation, barycentric blending, and pre-allocated weight buffers.

Supported Formats#

The animation system supports industry-standard 3D animation formats:

GLTF/GLB Animation#

GLTF 2.0 is the primary format for animated models. The engine automatically extracts:

  • Animation Clips - Keyframe data for skeletal and morph target animation
  • Skinned Meshes - Bone weights and bind matrices
  • Bone Hierarchy - Skeleton structure with parent-child relationships
  • Root Motion - Optional root bone translation/rotation for locomotion
automatic-clip-registration.ts
typescript
import { AnimationRegistry } from '@web-engine-dev/core/animation';
import { AssetLoader } from '@web-engine-dev/core/engine/assets';
// Load GLTF model with animations
const model = await AssetLoader.loadGLTF('characters/hero.glb');
// Clips are automatically registered
const clips = AnimationRegistry.getByAssetUuid(model.uuid);
console.log(`Loaded ${clips.length} animation clips`);
// Find specific clip by name
const walkClip = AnimationRegistry.findClip(model.uuid, 'Walk');

FBX Animation#

FBX files are supported through Three.js FBXLoader with automatic conversion to the engine's format.

Animation Types#

Skeletal Animation#

Skeletal animation deforms meshes based on bone transformations. Each vertex is influenced by 1-4 bones with normalized weights. The engine uses SIMD-accelerated matrix palette skinning for high-performance character rendering.

  • Unlimited bones per skeleton (practical limit ~200 for real-time)
  • Up to 4 bone influences per vertex
  • Automatic bone matrix updates with LOD support
  • GPU skinning via vertex shaders

Morph Target Animation#

Morph targets (blend shapes) blend between vertex positions for facial expressions, lip sync, and corrective shapes. The engine supports:

  • Unlimited morph targets per mesh
  • GPU-accelerated blending
  • Per-mesh morph influence caching

Root Motion#

Root motion extracts translation/rotation from the root bone for natural locomotion. The engine provides full 3D root motion with optional Y-axis (vertical) support for jumps/vaults.

Performance Characteristics#

The animation system is optimized for production workloads with aggressive performance targets:

MetricTargetNotes
State machine update< 0.1msPer entity, zero GC allocations
Bone matrix update< 0.05ms100 bones, SIMD path
Blend tree evaluation< 0.02ms8 clips, pre-allocated buffers
IK solve (two-bone)< 0.01msAnalytic solution
Root motion extraction< 0.005msCurve evaluation

Frame Budget

Total animation budget per entity: < 0.2ms at 60 FPS. Allows 50+ animated characters at full quality. Use LOD and adaptive pooling for larger crowds.

Performance Optimizations#

Zero-Allocation Hot Paths#

All hot path code uses pre-allocated buffers and object pools to avoid GC pressure:

  • Pooled state machine instances (256 pre-allocated)
  • Pre-allocated transition queues (circular buffers)
  • Reused blend weight buffers per blend tree node
  • Event buffering with fixed-size arrays

SIMD Acceleration#

Skeleton matrix updates use WASM SIMD for 4x throughput:

  • WebAssembly SIMD for bone matrix multiplication
  • Automatic fallback to JavaScript on unsupported devices
  • Benchmarked 10x faster than Three.js default skeleton updates

Adaptive Mixer Pool#

Animation mixer pooling with priority-based allocation and quality degradation:

  • Automatic pool resizing based on entity count
  • Priority-based eviction (camera distance, importance)
  • Frame skip and update rate throttling under pressure
  • MMO and small game presets for different workloads

Best Practices#

Clip Management#

  • Register clips once at asset load time
  • Use asset UUID for stable lookups (numeric IDs can change)
  • Validate clips with AnimationRegistry.validateClip()
  • Name clips descriptively (e.g., "Walk_Forward", "Attack_Sword")

State Machine Design#

  • Keep state count under 20 for clarity (use sub-state machines for complex AI)
  • Use priority transitions for interruptions (attacks, reactions)
  • Leverage exit time for natural animation flow
  • Buffer events instead of handling inline to prevent re-entrancy

Blend Tree Usage#

  • 1D blend trees for speed blending (idle → walk → run)
  • 2D blend trees for directional movement (strafe, backpedal)
  • Keep threshold count under 16 for optimal cache usage
  • Use barycentric blending for directional accuracy

Memory Management#

  • Release state machines with AnimationStateMachine.release()
  • Unregister skeletons when entities despawn (BoneRegistry.unregisterSkeleton())
  • Clear animation clip cache when switching scenes
  • Monitor pool stats to detect memory leaks

Mobile Considerations

Mobile GPUs have less VRAM and bandwidth. Reduce bone counts (max 50-75 bones), use animation LOD, disable IK on distant characters, and prefer simpler blend trees (1D over 2D).

Next Steps#

Now that you understand the animation architecture, explore specific topics:

Animation | Web Engine Docs | Web Engine Docs