Reputation: 41
I'm working off of this tutorial from http://ogldev.atspace.co.uk/www/tutorial38/tutorial38.html Unfortunately it doesn't explain how Assimp derives it's bone data. I know the global Inverse transform is a default Matrix value blender uses to set the y value to the z value, and the z value to -y. (or atleast that's what my test md5 models use)
GlobalInverseTransform = aiScene->mRootNode->mTransformation;
I'm trying to understand how Assimp derives the offset Matrices or inverse bind pose from MD5 files. For instance BobLampClean.md5mesh has 32 joints and 32 offset Matrices
aiMesh->mBones[i]->mOffsetMatrix;
From what I have seen online through other samples where they compute the offset matrix it goes something like this...
void ComputeQuatW(glm::quat& quat)
{
float t = 1.0f - (quat.x * quat.x) - (quat.y * quat.y) - (quat.z * quat.z);
if (t < 0.0f)
quat.w = 0.0f;
else
quat.w = -sqrtf(t);
}
glm::mat4 rotation, rotationInv, translationInv, offsetmatrix;
glm::quat MyQuaternion;
//here I chose an arbitrary joint and hard coded its orientation and position
MyQuaternion = glm::quat(glm::quat(-0.535591, -0.462288, -0.534983, 1));
ComputeQuatW(MyQuaternion);
glm::mat4 RotationMatrix = glm::toMat4(MyQuaternion);
rotationInv = glm::transpose(RotationMatrix);
translationInv = glm::translate(translationInv, glm::vec3(-0.014076, -2.592741, -30.241238));
offsetmatrix = rotationInv*translationInv;
I've outputted each of these offset matrices to comapre with Assimp's bone Matrices but to no avail. I'm not quite sure what I am doing wrong...
EDIT UPDATE: ok so I'm doing my operations incorrectly, I'm debugging a working code example that doesn't use Assimp and it can duplicate the same values as Assimp's data. I will update on how to correctly calculate the data.
Upvotes: 2
Views: 1893
Reputation: 41
Answer: To create the bind Pose I used the following code. The math classes and functions were created by the author of this series and this is how he created the offsetMatrices which is how Assimp builds it's bone offset matrices. His math functions can be found here https://www.youtube.com/watch?v=AqavYcdB7tg&t=3474s in the comments section. For each bone you create it by converting a quaternion into a rotation matrix, transposing it, then translate the translation matrix by the inverse of the positions, then combine the two.
"sheath" 0 ( 11.004813 -3.177138 31.702473 ) ( 0.307041 -0.578614 0.354181 )
//Example bone offset matrix.
The Quaternion is the last set of 3 numbers, You compute the W component then perform the operations.
mlQuaternionToMat4(rotation, joint.orientation);
mlTransposeMat4(rotationInv, rotation);
Here you would use the 1st set of 3 numbers for the joint position.
mlTranslationMat4(translationInv, -joint.position[0], -
joint.position[1], -joint.position[2]);
mlMultiplyMat4_2(finalmatrix, rotationInv, translationInv);
//finalMatrix = aiMesh->bone[sheath]->offsetMatrix
Upvotes: 2