浏览代码

[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 <kirandeepsinghkhehra@gmail.com>
pull/4615/head
Kirandeep-Singh-Khehra 6 个月前
committed by GitHub
父节点
当前提交
35c2408413
找不到此签名对应的密钥 GPG 密钥 ID: B5690EEEBB952194
共有 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; 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++) for (int i = 0; i < model.meshCount; i++)
{ {
if (model.meshes[i].boneMatrices) if (model.meshes[i].boneMatrices)
{ {
assert(model.meshes[i].boneCount == anim.boneCount); 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])
);
} }
} }
} }

正在加载...
取消
保存