11/*******************************************************************************************
22*
3- * raylib [models] example - animation bone blending
3+ * raylib [models] example - animation blend custom
44*
55* Example complexity rating: [★★★★] 4/4
66*
@@ -53,7 +53,7 @@ int main(void)
5353 const int screenWidth = 800 ;
5454 const int screenHeight = 450 ;
5555
56- InitWindow (screenWidth , screenHeight , "raylib [models] example - animation bone blending " );
56+ InitWindow (screenWidth , screenHeight , "raylib [models] example - animation blend custom " );
5757
5858 // Define the camera to look into our 3d world
5959 Camera camera = { 0 };
@@ -80,7 +80,7 @@ int main(void)
8080 TraceLog (LOG_INFO , "Found %d animations:" , animsCount );
8181 for (int i = 0 ; i < animsCount ; i ++ )
8282 {
83- TraceLog (LOG_INFO , " Animation %d: %s (%d frames)" , i , modelAnimations [i ].name , modelAnimations [i ].frameCount );
83+ TraceLog (LOG_INFO , " Animation %d: %s (%d frames)" , i , modelAnimations [i ].name , modelAnimations [i ].keyframeCount );
8484 }
8585
8686 // Use specific indices: walk/move = 2, attack = 3
@@ -118,8 +118,8 @@ int main(void)
118118 ModelAnimation anim1 = modelAnimations [animIndex1 ];
119119 ModelAnimation anim2 = modelAnimations [animIndex2 ];
120120
121- animCurrentFrame1 = (animCurrentFrame1 + 1 )%anim1 .frameCount ;
122- animCurrentFrame2 = (animCurrentFrame2 + 1 )%anim2 .frameCount ;
121+ animCurrentFrame1 = (animCurrentFrame1 + 1 )%anim1 .keyframeCount ;
122+ animCurrentFrame2 = (animCurrentFrame2 + 1 )%anim2 .keyframeCount ;
123123
124124 // Blend the two animations
125125 characterModel .transform = MatrixTranslate (position .x , position .y , position .z );
@@ -203,9 +203,9 @@ static void BlendModelAnimationsBones(Model *model, ModelAnimation *anim1, int f
203203 ModelAnimation * anim2 , int frame2 , float blendFactor , bool upperBodyBlend )
204204{
205205 // Validate inputs
206- if (anim1 -> boneCount == 0 || anim1 -> framePoses == NULL ||
207- anim2 -> boneCount == 0 || anim2 -> framePoses == NULL ||
208- model -> boneCount == 0 || model -> bindPose == NULL )
206+ if (anim1 -> boneCount == 0 || anim1 -> keyframePoses == NULL ||
207+ anim2 -> boneCount == 0 || anim2 -> keyframePoses == NULL ||
208+ model -> skeleton . boneCount == 0 || model -> skeleton . bindPose == NULL )
209209 {
210210 return ;
211211 }
@@ -214,26 +214,13 @@ static void BlendModelAnimationsBones(Model *model, ModelAnimation *anim1, int f
214214 blendFactor = fminf (1.0f , fmaxf (0.0f , blendFactor ));
215215
216216 // Ensure frame indices are valid
217- if (frame1 >= anim1 -> frameCount ) frame1 = anim1 -> frameCount - 1 ;
218- if (frame2 >= anim2 -> frameCount ) frame2 = anim2 -> frameCount - 1 ;
217+ if (frame1 >= anim1 -> keyframeCount ) frame1 = anim1 -> keyframeCount - 1 ;
218+ if (frame2 >= anim2 -> keyframeCount ) frame2 = anim2 -> keyframeCount - 1 ;
219219 if (frame1 < 0 ) frame1 = 0 ;
220220 if (frame2 < 0 ) frame2 = 0 ;
221221
222- // Find first mesh with bones
223- int firstMeshWithBones = -1 ;
224- for (int i = 0 ; i < model -> meshCount ; i ++ )
225- {
226- if (model -> meshes [i ].boneMatrices )
227- {
228- firstMeshWithBones = i ;
229- break ;
230- }
231- }
232-
233- if (firstMeshWithBones == -1 ) return ;
234-
235222 // Get bone count (use minimum of all to be safe)
236- int boneCount = model -> boneCount ;
223+ int boneCount = model -> skeleton . boneCount ;
237224 if (anim1 -> boneCount < boneCount ) boneCount = anim1 -> boneCount ;
238225 if (anim2 -> boneCount < boneCount ) boneCount = anim2 -> boneCount ;
239226
@@ -246,7 +233,7 @@ static void BlendModelAnimationsBones(Model *model, ModelAnimation *anim1, int f
246233 // If upper body blending is enabled, use different blend factors for upper vs lower body
247234 if (upperBodyBlend )
248235 {
249- const char * boneName = model -> bones [boneId ].name ;
236+ const char * boneName = model -> skeleton . bones [boneId ].name ;
250237 bool isUpperBody = IsUpperBodyBone (boneName );
251238
252239 // Upper body: use anim2 (attack), Lower body: use anim1 (walk)
@@ -256,12 +243,12 @@ static void BlendModelAnimationsBones(Model *model, ModelAnimation *anim1, int f
256243 }
257244
258245 // Get transforms from both animations
259- Transform * bindTransform = & model -> bindPose [boneId ];
260- Transform * anim1Transform = & anim1 -> framePoses [frame1 ][boneId ];
261- Transform * anim2Transform = & anim2 -> framePoses [frame2 ][boneId ];
246+ Transform * bindTransform = & model -> skeleton . bindPose [boneId ];
247+ Transform * anim1Transform = & anim1 -> keyframePoses [frame1 ][boneId ];
248+ Transform * anim2Transform = & anim2 -> keyframePoses [frame2 ][boneId ];
262249
263250 // Blend the transforms
264- Transform blended ;
251+ Transform blended = { 0 } ;
265252 blended .translation = Vector3Lerp (anim1Transform -> translation , anim2Transform -> translation , boneBlendFactor );
266253 blended .rotation = QuaternionSlerp (anim1Transform -> rotation , anim2Transform -> rotation , boneBlendFactor );
267254 blended .scale = Vector3Lerp (anim1Transform -> scale , anim2Transform -> scale , boneBlendFactor );
@@ -279,18 +266,7 @@ static void BlendModelAnimationsBones(Model *model, ModelAnimation *anim1, int f
279266 MatrixTranslate (blended .translation .x , blended .translation .y , blended .translation .z ));
280267
281268 // Calculate final bone matrix (similar to UpdateModelAnimationBones)
282- model -> meshes [firstMeshWithBones ].boneMatrices [boneId ] = MatrixMultiply (MatrixInvert (bindMatrix ), blendedMatrix );
283- }
284-
285- // Copy bone matrices to remaining meshes
286- for (int i = firstMeshWithBones + 1 ; i < model -> meshCount ; i ++ )
287- {
288- if (model -> meshes [i ].boneMatrices )
289- {
290- memcpy (model -> meshes [i ].boneMatrices ,
291- model -> meshes [firstMeshWithBones ].boneMatrices ,
292- model -> meshes [i ].boneCount * sizeof (model -> meshes [i ].boneMatrices [0 ]));
293- }
269+ model -> boneMatrices [boneId ] = MatrixMultiply (MatrixInvert (bindMatrix ), blendedMatrix );
294270 }
295271}
296272
0 commit comments