WARNING: BREAKING: REDESIGNED: **Animation System** #4606

REVIEWED: Reorganized structures for a clearer distinction between "skeleton", "skin" and "skinning" data
ADDED: New structures: `ModelSkeleton`, `ModelAnimPose` (alias `Transform*`)
ADDED: Runtime data `currentPose` and `boneMatrices` to `Model` structure
ADDED: Support animation frames-blending, for timing control
ADDED: Support animations blending, between two animations
REVIEWED: All models animation loading functions
ADDED: `UpdateModelAnimationEx()` for two animations blending
REMOVED: `UpdateModelAnimationBones*()`, simplified API
REVIEWED: Shader attributes/uniforms names for animations, for consistency
REVIEWED: Multiple tweaks on animations loading for consistency between formats
ADDED: example: `models_animation_timing`
ADDED: example: `models_animation_blending`
REVIEWED: example: `models_animation_gpu_skinning`
REVIEWED: example: `models_animation_blend_custom`
REVIEWED: All animated models loading examples
This commit is contained in:
Ray
2026-02-24 01:18:57 +01:00
parent bee3dc6673
commit d4dc038e2e
26 changed files with 1052 additions and 807 deletions

View File

@ -42,15 +42,17 @@ int main(void)
camera.fovy = 45.0f; // Camera field-of-view Y
camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
// Load gltf model
// Load model
Model model = LoadModel("resources/models/gltf/robot.glb");
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model world position
// Load gltf model animations
int animsCount = 0;
unsigned int animIndex = 0;
unsigned int animCurrentFrame = 0;
ModelAnimation *modelAnimations = LoadModelAnimations("resources/models/gltf/robot.glb", &animsCount);
// Load model animations
int animCount = 0;
ModelAnimation *anims = LoadModelAnimations("resources/models/gltf/robot.glb", &animCount);
// Animation playing variables
unsigned int animIndex = 0; // Current animation playing
unsigned int animCurrentFrame = 0; // Current animation frame
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
@ -63,13 +65,12 @@ int main(void)
UpdateCamera(&camera, CAMERA_ORBITAL);
// Select current animation
if (IsMouseButtonPressed(MOUSE_BUTTON_RIGHT)) animIndex = (animIndex + 1)%animsCount;
else if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) animIndex = (animIndex + animsCount - 1)%animsCount;
if (IsKeyPressed(KEY_RIGHT)) animIndex = (animIndex + 1)%animCount;
else if (IsKeyPressed(KEY_LEFT)) animIndex = (animIndex + animCount - 1)%animCount;
// Update model animation
ModelAnimation anim = modelAnimations[animIndex];
animCurrentFrame = (animCurrentFrame + 1)%anim.frameCount;
UpdateModelAnimation(model, anim, animCurrentFrame);
animCurrentFrame = (animCurrentFrame + 1)%anims[animIndex].keyframeCount;
UpdateModelAnimation(model, anims[animIndex], (float)animCurrentFrame);
//----------------------------------------------------------------------------------
// Draw
@ -79,12 +80,15 @@ int main(void)
ClearBackground(RAYWHITE);
BeginMode3D(camera);
DrawModel(model, position, 1.0f, WHITE); // Draw animated model
DrawModel(model, position, 1.0f, WHITE);
DrawGrid(10, 1.0f);
EndMode3D();
DrawText("Use the LEFT/RIGHT mouse buttons to switch animation", 10, 10, 20, GRAY);
DrawText(TextFormat("Animation: %s", anim.name), 10, GetScreenHeight() - 20, 10, DARKGRAY);
DrawText(TextFormat("Current animation: %s", anims[animIndex].name), 10, 40, 20, MAROON);
DrawText("Use the LEFT/RIGHT keys to switch animation", 10, 10, 20, GRAY);
EndDrawing();
//----------------------------------------------------------------------------------
@ -92,7 +96,8 @@ int main(void)
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadModel(model); // Unload model and meshes/material
UnloadModelAnimations(anims, animCount); // Unload model animations data
UnloadModel(model); // Unload model
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------