2
0
Эх сурвалжийг харах

[rmodels] Optimized `UpdateModelAnimationBones()` function (#4602)

- Updating bones only once instead for each mesh.
 - Updating only one `model.meshes[].boneMatrices` and then using deep copy for other meshes instead of calculating for each bone in each mesh.

**Other points:**
 - Makes it a clean base/template/reference for bone updation functions. Because if using this as template then some calculations done in one mesh can affect bones in other mesh in next iteration(doubles the effect in for next mesh).

Signed-off-by: Kirandeep-Singh-Khehra <[email protected]>
Kirandeep-Singh-Khehra 8 сар өмнө
parent
commit
35c2408413
1 өөрчлөгдсөн 49 нэмэгдсэн , 25 устгасан
  1. 49 25
      src/rmodels.c

+ 49 - 25
src/rmodels.c

@@ -2270,38 +2270,62 @@ void UpdateModelAnimationBones(Model model, ModelAnimation anim, int frame)
     {
         if (frame >= anim.frameCount) frame = frame%anim.frameCount;
 
+        // Get first mesh which have bones
+        int firstMeshWithBones = -1;
+
         for (int i = 0; i < model.meshCount; i++)
         {
             if (model.meshes[i].boneMatrices)
             {
                 assert(model.meshes[i].boneCount == anim.boneCount);
+                if (firstMeshWithBones == -1)
+                {
+                    firstMeshWithBones = i;
+                }
+            }
+        }
 
-                for (int boneId = 0; boneId < model.meshes[i].boneCount; boneId++)
+        // Update all bones and boneMatrices of first mesh with bones.
+        for (int boneId = 0; boneId < anim.boneCount; boneId++)
+        {
+            Vector3 inTranslation = model.bindPose[boneId].translation;
+            Quaternion inRotation = model.bindPose[boneId].rotation;
+            Vector3 inScale = model.bindPose[boneId].scale;
+
+            Vector3 outTranslation = anim.framePoses[frame][boneId].translation;
+            Quaternion outRotation = anim.framePoses[frame][boneId].rotation;
+            Vector3 outScale = anim.framePoses[frame][boneId].scale;
+
+            Vector3 invTranslation = Vector3RotateByQuaternion(Vector3Negate(inTranslation), QuaternionInvert(inRotation));
+            Quaternion invRotation = QuaternionInvert(inRotation);
+            Vector3 invScale = Vector3Divide((Vector3){ 1.0f, 1.0f, 1.0f }, inScale);
+
+            Vector3 boneTranslation = Vector3Add(
+                Vector3RotateByQuaternion(Vector3Multiply(outScale, invTranslation),
+                outRotation), outTranslation);
+            Quaternion boneRotation = QuaternionMultiply(outRotation, invRotation);
+            Vector3 boneScale = Vector3Multiply(outScale, invScale);
+
+            Matrix boneMatrix = MatrixMultiply(MatrixMultiply(
+                QuaternionToMatrix(boneRotation),
+                MatrixTranslate(boneTranslation.x, boneTranslation.y, boneTranslation.z)),
+                MatrixScale(boneScale.x, boneScale.y, boneScale.z));
+
+            model.meshes[firstMeshWithBones].boneMatrices[boneId] = boneMatrix;
+        }
+
+        // Update remaining meshes with bones (Use Deep copy because shallow copy results in double free with 'UnloadModel()')
+        if (firstMeshWithBones != -1)
+        {
+            for (int i = firstMeshWithBones + 1; i < model.meshCount; i++)
+            {
+                if (model.meshes[i].boneMatrices)
                 {
-                    Vector3 inTranslation = model.bindPose[boneId].translation;
-                    Quaternion inRotation = model.bindPose[boneId].rotation;
-                    Vector3 inScale = model.bindPose[boneId].scale;
-
-                    Vector3 outTranslation = anim.framePoses[frame][boneId].translation;
-                    Quaternion outRotation = anim.framePoses[frame][boneId].rotation;
-                    Vector3 outScale = anim.framePoses[frame][boneId].scale;
-
-                    Vector3 invTranslation = Vector3RotateByQuaternion(Vector3Negate(inTranslation), QuaternionInvert(inRotation));
-                    Quaternion invRotation = QuaternionInvert(inRotation);
-                    Vector3 invScale = Vector3Divide((Vector3){ 1.0f, 1.0f, 1.0f }, inScale);
-
-                    Vector3 boneTranslation = Vector3Add(
-                        Vector3RotateByQuaternion(Vector3Multiply(outScale, invTranslation),
-                        outRotation), outTranslation);
-                    Quaternion boneRotation = QuaternionMultiply(outRotation, invRotation);
-                    Vector3 boneScale = Vector3Multiply(outScale, invScale);
-
-                    Matrix boneMatrix = MatrixMultiply(MatrixMultiply(
-                        QuaternionToMatrix(boneRotation),
-                        MatrixTranslate(boneTranslation.x, boneTranslation.y, boneTranslation.z)),
-                        MatrixScale(boneScale.x, boneScale.y, boneScale.z));
-
-                    model.meshes[i].boneMatrices[boneId] = boneMatrix;
+                    memcpy(
+                        model.meshes[i].boneMatrices,
+                        model.meshes[firstMeshWithBones].boneMatrices,
+                        model.meshes[i].boneCount * sizeof(model.meshes[i].boneMatrices[0])
+                    );
                 }
             }
         }