From fe2c2c0086d3c1f8e0a687076130b5bee8621d30 Mon Sep 17 00:00:00 2001 From: fyl2xp1 <97300304+fyl2xp1@users.noreply.github.com> Date: Fri, 1 May 2026 21:43:29 -0500 Subject: [PATCH] add "UpdateModelPose" to api --- src/raylib.h | 1 + src/rmodels.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/raylib.h b/src/raylib.h index e8164073f..7c7c0bf9c 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -1642,6 +1642,7 @@ RLAPI void SetModelMeshMaterial(Model *model, int meshId, int materialId); // Model animations loading/unloading functions RLAPI ModelAnimation *LoadModelAnimations(const char *fileName, int *animCount); // Load model animations from file +RLAPI void UpdateModelPose(Model model); // Update model current pose (vertex buffers and bone matrices) RLAPI void UpdateModelAnimation(Model model, ModelAnimation anim, float frame); // Update model animation pose (vertex buffers and bone matrices) RLAPI void UpdateModelAnimationEx(Model model, ModelAnimation animA, float frameA, ModelAnimation animB, float frameB, float blend); // Update model animation pose, blending two animations RLAPI void UnloadModelAnimations(ModelAnimation *animations, int animCount); // Unload animation array data diff --git a/src/rmodels.c b/src/rmodels.c index eb7f30cb8..ea39eae5c 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -2293,6 +2293,35 @@ ModelAnimation *LoadModelAnimations(const char *fileName, int *animCount) return animations; } +// Update model current pose (vertex buffers and bone matrices) +void UpdateModelPose(Model model) +{ + if ((model.boneMatrices == NULL) || (model.currentPose == NULL) || (model.skeleton.bindPose == NULL) || (model.skeleton.boneCount < 1)) return; + + Matrix bindPoseMatrix = { 0 }; + Matrix currentPoseMatrix = { 0 }; + + // Compute bone matrix from model current pose + for (int boneIndex = 0; boneIndex < model.skeleton.boneCount; boneIndex++) + { + Transform *bindPoseTransform = &model.skeleton.bindPose[boneIndex]; + bindPoseMatrix = MatrixMultiply( + MatrixMultiply(MatrixScale(bindPoseTransform->scale.x, bindPoseTransform->scale.y, bindPoseTransform->scale.z), + QuaternionToMatrix(bindPoseTransform->rotation)), + MatrixTranslate(bindPoseTransform->translation.x, bindPoseTransform->translation.y, bindPoseTransform->translation.z)); + + Transform *currentPoseTransform = &model.currentPose[boneIndex]; + currentPoseMatrix = MatrixMultiply( + MatrixMultiply(MatrixScale(currentPoseTransform->scale.x, currentPoseTransform->scale.y, currentPoseTransform->scale.z), + QuaternionToMatrix(currentPoseTransform->rotation)), + MatrixTranslate(currentPoseTransform->translation.x, currentPoseTransform->translation.y, currentPoseTransform->translation.z)); + + model.boneMatrices[boneIndex] = MatrixMultiply(MatrixInvert(bindPoseMatrix), currentPoseMatrix); + } + + UpdateModelAnimationVertexBuffers(model); +} + // Update model animation data (vertex buffers / bone matrices) for a specific pose // NOTE 1: Request frame could be fractional, using a lerp interpolation between two frames // NOTE 2: Updated vertex animation data is uploaded to GPU in case of CPU skinning,