Procházet zdrojové kódy

[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 před 10 měsíci
odevzdal GitHub
rodič
revize
35c2408413
V databázi nebyl nalezen žádný známý klíč pro tento podpis ID GPG klíče: B5690EEEBB952194
1 změnil soubory, kde provedl 49 přidání a 25 odebrání
  1. +49
    -25
      src/rmodels.c

+ 49
- 25
src/rmodels.c Zobrazit soubor

@ -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])
);
}
}
}

Načítá se…
Zrušit
Uložit