From 0bc4ede7abf6e2ddfc4f6eb11b1e86018f452da1 Mon Sep 17 00:00:00 2001 From: Jett <30197659+JettMonstersGoBoom@users.noreply.github.com> Date: Sat, 21 Dec 2024 19:06:07 -0500 Subject: [PATCH] Removed memory duplication and memcpy with animations previously the bonematrix array was stored per mesh even though this is duplicated. now points back to the model. this saves memory and removes a memcpy. --- src/raylib.h | 4 ++- src/rmodels.c | 79 +++++++++++---------------------------------------- 2 files changed, 20 insertions(+), 63 deletions(-) diff --git a/src/raylib.h b/src/raylib.h index 7e1a1f8380a9..18a6796aa44e 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -360,8 +360,9 @@ typedef struct Mesh { float *animNormals; // Animated normals (after bones transformations) unsigned char *boneIds; // Vertex bone ids, max 255 bone ids, up to 4 bones influence by vertex (skinning) (shader-location = 6) float *boneWeights; // Vertex bone weight, up to 4 bones influence by vertex (skinning) (shader-location = 7) - Matrix *boneMatrices; // Bones animated transformation matrices int boneCount; // Number of bones + Matrix *boneMatricesPtr; // POINTER to Models bones transformation matrices + // DO NOT FREE THIS // OpenGL identifiers unsigned int vaoId; // OpenGL Vertex Array Object id @@ -414,6 +415,7 @@ typedef struct Model { // Animation data int boneCount; // Number of bones BoneInfo *bones; // Bones information (skeleton) + Matrix *boneMatrices; // Bones animated transformation matrices, moved these here to boost perf a little and remove wasted memory duplication Transform *bindPose; // Bones base transformation (pose) } Model; diff --git a/src/rmodels.c b/src/rmodels.c index d69c9035cac5..3c8af16370a3 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -1209,7 +1209,7 @@ void UnloadModel(Model model) // Unload animation data RL_FREE(model.bones); RL_FREE(model.bindPose); - + RL_FREE(model.boneMatrices); TRACELOG(LOG_INFO, "MODEL: Unloaded model (and meshes) from RAM and VRAM"); } @@ -1508,9 +1508,9 @@ void DrawMesh(Mesh mesh, Material material, Matrix transform) #ifdef RL_SUPPORT_MESH_GPU_SKINNING // Upload Bone Transforms - if ((material.shader.locs[SHADER_LOC_BONE_MATRICES] != -1) && mesh.boneMatrices) + if ((material.shader.locs[SHADER_LOC_BONE_MATRICES] != -1) && mesh.boneMatricesPtr) { - rlSetUniformMatrices(material.shader.locs[SHADER_LOC_BONE_MATRICES], mesh.boneMatrices, mesh.boneCount); + rlSetUniformMatrices(material.shader.locs[SHADER_LOC_BONE_MATRICES], mesh.boneMatricesPtr, mesh.boneCount); } #endif //----------------------------------------------------- @@ -1754,9 +1754,9 @@ void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, i #ifdef RL_SUPPORT_MESH_GPU_SKINNING // Upload Bone Transforms - if ((material.shader.locs[SHADER_LOC_BONE_MATRICES] != -1) && mesh.boneMatrices) + if ((material.shader.locs[SHADER_LOC_BONE_MATRICES] != -1) && mesh.boneMatricesPtr) { - rlSetUniformMatrices(material.shader.locs[SHADER_LOC_BONE_MATRICES], mesh.boneMatrices, mesh.boneCount); + rlSetUniformMatrices(material.shader.locs[SHADER_LOC_BONE_MATRICES], mesh.boneMatricesPtr, mesh.boneCount); } #endif @@ -1932,7 +1932,6 @@ void UnloadMesh(Mesh mesh) RL_FREE(mesh.animNormals); RL_FREE(mesh.boneWeights); RL_FREE(mesh.boneIds); - RL_FREE(mesh.boneMatrices); } // Export mesh data to file @@ -2270,22 +2269,6 @@ 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; - break; - } - } - } - // Update all bones and boneMatrices of first mesh with bones. for (int boneId = 0; boneId < anim.boneCount; boneId++) { @@ -2312,22 +2295,7 @@ void UpdateModelAnimationBones(Model model, ModelAnimation anim, int frame) 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 - // NOTE: Using 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) - { - memcpy(model.meshes[i].boneMatrices, - model.meshes[firstMeshWithBones].boneMatrices, - model.meshes[i].boneCount * sizeof(model.meshes[i].boneMatrices[0])); - } - } + model.boneMatrices[boneId] = boneMatrix; } } } @@ -2372,7 +2340,7 @@ void UpdateModelAnimation(Model model, ModelAnimation anim, int frame) // Early stop when no transformation will be applied if (boneWeight == 0.0f) continue; animVertex = (Vector3){ mesh.vertices[vCounter], mesh.vertices[vCounter + 1], mesh.vertices[vCounter + 2] }; - animVertex = Vector3Transform(animVertex,model.meshes[m].boneMatrices[boneId]); + animVertex = Vector3Transform(animVertex,model.boneMatrices[boneId]); mesh.animVertices[vCounter] += animVertex.x*boneWeight; mesh.animVertices[vCounter+1] += animVertex.y*boneWeight; mesh.animVertices[vCounter+2] += animVertex.z*boneWeight; @@ -2383,7 +2351,7 @@ void UpdateModelAnimation(Model model, ModelAnimation anim, int frame) if (mesh.normals != NULL) { animNormal = (Vector3){ mesh.normals[vCounter], mesh.normals[vCounter + 1], mesh.normals[vCounter + 2] }; - animNormal = Vector3Transform(animNormal,model.meshes[m].boneMatrices[boneId]); + animNormal = Vector3Transform(animNormal,model.boneMatrices[boneId]); mesh.animNormals[vCounter] += animNormal.x*boneWeight; mesh.animNormals[vCounter + 1] += animNormal.y*boneWeight; mesh.animNormals[vCounter + 2] += animNormal.z*boneWeight; @@ -4807,16 +4775,10 @@ static Model LoadIQM(const char *fileName) } BuildPoseFromParentJoints(model.bones, model.boneCount, model.bindPose); - - for (int i = 0; i < model.meshCount; i++) + model.boneMatrices = RL_CALLOC(model.boneCount,sizeof(Matrix)); + for (int j = 0; j < model.boneCount; j++) { - model.meshes[i].boneCount = model.boneCount; - model.meshes[i].boneMatrices = RL_CALLOC(model.meshes[i].boneCount, sizeof(Matrix)); - - for (int j = 0; j < model.meshes[i].boneCount; j++) - { - model.meshes[i].boneMatrices[j] = MatrixIdentity(); - } + model.boneMatrices[j] = MatrixIdentity(); } UnloadFileData(fileData); @@ -5907,14 +5869,10 @@ static Model LoadGLTF(const char *fileName) } // Bone Transform Matrices - model.meshes[meshIndex].boneCount = model.boneCount; - model.meshes[meshIndex].boneMatrices = RL_CALLOC(model.meshes[meshIndex].boneCount, sizeof(Matrix)); - - for (int j = 0; j < model.meshes[meshIndex].boneCount; j++) - { - model.meshes[meshIndex].boneMatrices[j] = MatrixIdentity(); - } + if (model.boneMatrices==NULL) + model.boneMatrices = RL_CALLOC(model.boneCount, sizeof(Matrix)); + model.meshes[meshIndex].boneMatricesPtr = model.boneMatrices; meshIndex++; // Move to next mesh } @@ -6687,12 +6645,9 @@ static Model LoadM3D(const char *fileName) memcpy(model.meshes[i].animVertices, model.meshes[i].vertices, model.meshes[i].vertexCount*3*sizeof(float)); memcpy(model.meshes[i].animNormals, model.meshes[i].normals, model.meshes[i].vertexCount*3*sizeof(float)); - model.meshes[i].boneCount = model.boneCount; - model.meshes[i].boneMatrices = RL_CALLOC(model.meshes[i].boneCount, sizeof(Matrix)); - for (j = 0; j < model.meshes[i].boneCount; j++) - { - model.meshes[i].boneMatrices[j] = MatrixIdentity(); - } + if (model.boneMatrices==NULL) + model.boneMatrices = RL_CALLOC(model.boneCount, sizeof(Matrix)); + model.meshes[i].boneMatricesPtr = model.boneMatrices; } }