Core Concepts
Skeleton (Bone Hierarchy)
A hierarchical tree of joints defining character structure. Each joint has:
- Position, rotation, scale transforms
- Parent-child relationships
- Rest/bind pose (default undeformed state)
- Name or index identifier
Structure:
Root → Spine → Chest → Neck → Head
└→ Shoulders → Elbows → Hands
└→ Hips → Knees → Feet
Animation Data
Keyframe information driving skeleton over time:
- Keyframes: Specific poses at specific times
- Tracks: Per-joint animation channels
- Duration: Total animation length
- Interpolation: Computing poses between keyframes
Sampling (Pose Extraction)
Evaluating animation at specific time to produce pose:
- Find keyframes before/after current time
- Interpolate between keyframes
- Output local-space transforms (relative to parent)
Hierarchy Evaluation
Converting local-space to world/model-space:
- Start at root joint
- Multiply local transform by parent's world transform
- Recursively process children
- Output: 4x4 matrices in model space
Animation Blending
Combining multiple animations with weights:
- Linear Blend: Weighted average of transforms
- Additive Blend: Base animation + weighted deltas
- Partial Blend: Per-joint weight masks for body regions
System Architecture
Pipeline:
Animation Data → Sampling → Local Transforms
↓
Blending (optional) → Blended Locals
↓
IK/Procedural (optional) → Adjusted Transforms
↓
Hierarchy Evaluation → World Matrices
↓
Rendering/Skinning
Key Use Cases
1. Basic Playback
Play single animation in loop. Update time, sample animation, evaluate hierarchy, render.
2. Multi-Animation Blending
Smooth transitions between animations. Sample each animation, blend with weights, evaluate hierarchy.
Example: Walk (weight=0.7) + Run (weight=0.3) = Walk-to-run transition
3. Additive Layers
Layer subtle variations without replacing base animation.
Example: Walking (base) + Breathing (additive) + Hand gesture (additive)
4. Partial Blending
Different animations on different skeleton parts.
Example: Legs = Walk animation, Arms = Aim animation
5. Two-Bone Inverse Kinematics (IK)
Procedurally adjust joint chains to reach targets.
Components:
- Start, middle, end joints (shoulder-elbow-hand)
- Target position/rotation
- Pole vector (controls bend direction)
- Weight (0=animation, 1=full IK)
Use: Hand reaching objects, foot placement on terrain
6. Look-At/Aim Constraints
Make joints point toward targets.
Parameters:
- Target position
- Forward/up vectors
- Weight for blending
Use: Head tracking, turret aiming
7. Mesh Skinning
Deform mesh based on skeleton:
skinning_matrix = world_transform × inverse_bind_pose
final_vertex = sum(weight[i] × skinning_matrix[i] × vertex)
Data: Bind pose, joint weights per vertex, joint indices
8. Root Motion
Separate character movement from animation:
- Extraction: Remove root translation/rotation, create motion tracks
- Playback: Apply motion tracks to character transform
9. Custom Property Tracks
Animate non-transform data (events, values):
- Sampling: Get current value at time
- Triggering: Detect state changes for events (footsteps, effects)
10. Multi-Threading
Process multiple characters in parallel:
- Divide characters into tasks
- Distribute across thread pool
- Grain size: 32-128 characters per task
Standard Workflows
Workflow 1: Basic Animation
Setup (once):
- Load skeleton and animation
- Allocate buffers (local and world transforms)
- Create sampling context
Update (per frame):
- Update time (time += delta_time)
- Sample animation → local transforms
- Evaluate hierarchy → world matrices
- Render
Workflow 2: Blending
- Sample multiple animations → separate local buffers
- Setup blend layers with weights
- Blend → single local buffer
- Evaluate hierarchy → world matrices
- Render
Workflow 3: IK + Animation
- Sample animation → local transforms
- Evaluate hierarchy → world matrices
- Apply IK → calculate corrections
- Apply corrections to world matrices
- Render
Workflow 4: Skinned Mesh
- Animate skeleton → world matrices
- Compute skinning matrices
- Upload to GPU shader
- Shader deforms vertices
- Render mesh
Performance Optimization
Memory Layout
- Structure of Arrays (SoA): Store similar data together for SIMD vectorization
- Pre-allocate buffers, reuse every frame
- Avoid dynamic allocations in update loop
Sampling
- Reuse sampling context between frames (caches keyframe indices)
- Invalidate only when switching animations
Blending
- Use weight threshold to skip low-influence joints (threshold ~0.01)
- Minimize layer count (2-3 usually sufficient)
- Per-joint weights are expensive, use sparingly
IK
- Apply only to necessary joints
- Skip when target hasn't moved
- Use weight for gradual enable/disable
Multi-Threading
- Thread count = CPU cores
- Tune grain size (balance overhead vs parallelism)
- Independent data per character (no shared state)
Skinning
- GPU skinning: compute matrices on CPU, deform on GPU
- Joint remapping: process only joints affecting mesh
- Pre-compute inverse bind poses offline
Best Practices
Initialization
1. Load skeleton and animation assets
2. Validate compatibility
3. Allocate transform buffers
4. Initialize sampling context
Update Loop
1. Update animation time
2. Sample animation(s)
3. Blend (if needed)
4. Apply IK/procedural (if needed)
5. Evaluate hierarchy
6. Render
Error Handling
- Validate animation tracks match skeleton
- Check buffer sizes
- Handle asset loading failures
- Verify joint indices within bounds
Joint Lookup
- By Name: Search joint names (cache results)
- By Index: Fastest access (validate bounds)
- Hierarchical: Find by parent relationships
Essential API Patterns
Skeleton
joint_count(),joint_names(),parent_indices(),rest_poses()
Animation
duration(),track_count()
Sampling Operation
- Input: Animation, time/ratio, context
- Output: Local transforms
Hierarchy Evaluation
- Input: Skeleton, local transforms
- Output: World matrices
Blending Operation
- Input: Multiple transform sets, weights per layer, optional joint masks
- Output: Blended local transforms
IK Two-Bone
- Input: Start/mid/end joints, target, pole vector, weight
- Output: Correction rotations
Aim/Look-At
- Input: Joint, target, forward/up vectors, weight
- Output: Correction rotation
Glossary
- Joint/Bone: Single skeleton element
- Skeleton: Hierarchical joint structure
- Keyframe: Pose at specific time
- Sampling: Extracting pose at time
- Local Space: Relative to parent
- World Space: Absolute position
- Blending: Combining animations with weights
- Additive: Delta animation added to base
- IK: Procedural adjustment to reach targets
- Skinning: Mesh deformation from skeleton
- Root Motion: Character translation/rotation
- Bind Pose: Original mesh-skeleton relationship
- Track: Animation channel (transform or custom)
- SoA: Structure of Arrays (SIMD-optimized layout)
- Pole Vector: IK bend direction control
Quick Reference
Minimal System:
```
Setup:
1. Load skeleton, animation
2. Allocate buffers (size = joint_count)
3. Create context
Update:
1. time = (current / duration) % 1.0
2. Sample(animation, time) → locals
3. EvaluateHierarchy(skeleton, locals) → worlds
4. Render(worlds)
Comments 0
Please sign in to leave a comment.
No comments yet. Be the first to share your thoughts!