Reputation: 59
Trying to implement rigging:
<visual_scene id="Scene" name="Scene">
<node id="Armature" name="Armature" type="NODE">
<matrix sid="transform">1 0 0 0 0 0 1 0 0 -1 0 0 0 0 0 1</matrix>
<node id="Armature_Bone" name="Bone" sid="Bone" type="JOINT">
<matrix sid="transform">0.3299372 0.944003 -1.78814e-7 0 -4.76837e-7 0 -1 0 -0.944003 0.3299374 3.8743e-7 0 0 0 0 1</matrix>
<node id="Armature_Bone_001" name="Bone.001" sid="Bone_001" type="JOINT">
<matrix sid="transform">0.886344 -0.4630275 3.31894e-7 2.98023e-8 0.4630274 0.886344 -1.86307e-7 1.239941 -2.07907e-7 3.18808e-7 1 -2.84217e-14 0 0 0 1</matrix>
<node id="Armature_Bone_002" name="Bone.002" sid="Bone_002" type="JOINT">
<matrix sid="transform">0.9669114 0.2551119 -1.83038e-7 -1.19209e-7 -0.2551119 0.9669115 1.29195e-7 1.219687 2.09941e-7 -7.82246e-8 1 0 0 0 0 1</matrix>
<node id="Armature_Bone_003" name="Bone.003" sid="Bone_003" type="JOINT">
<matrix sid="transform">0.8538353 0.5205433 1.0139e-7 -1.19209e-7 -0.5205433 0.8538353 2.4693e-7 1.815649 4.19671e-8 -2.63615e-7 1 5.68434e-14 0 0 0 1</matrix>
Now if I set each bone's matrix to glm::mat4(1), I get this:
But if I try to multiply by a joints parent transform, like in the Thin Matrix rigging tutorial, I get very weird results:
void SkelManager::setTposeTransforms(std::vector<Joint>& _reference)
{
for (int child = 0; child < _reference.size(); child++)
{
if (_reference[child].parent == -1)
{
//_reference[child].tPose = glm::mat4(1);
_reference[child].tPose = _reference[child].transform;
}
for (int parent = 0; parent < _reference.size(); parent++)
if (_reference[child].parent == parent)
{
//_reference[child].tPose = glm::mat4(1);
_reference[child].tPose = _reference[parent].tPose * _reference[child].transform;
}
}
}
Please help, I've been stuck on this for a couple weeks and I've had no success, and no matter how hard I search the web I can't find anything that works, any ideas on what I could be doing wrong?
Upvotes: 3
Views: 877
Reputation: 393
I use glm::make_mat4(tmpFloatArray), and then I transpose it, not sure if this is the correct way):
See COLLADA spec's about matrix:
Matrices in COLLADA are column matrices in the mathematical sense. These matrices are written in row- major order to aid the human reader. See the example.
so yes, you need to transpose it.
It is not so hard to load COLLADA's skeleton animations. Follow these steps:
Importer side:
Render side:
Prepare all joint transforms for each frame if needed. Multiply joint transforms with their parents
Create this matrix for each joints:
FinalJointTrans4x4 = JointTransform * InvBindPose * BindShapeMatrix
JointTransform is the transform that multiplied with parents...
InvBindPose (or InvBindMatrix) is the transform you read from skin->joints->INV_BIND_MATRIX for each joints
BindShapeMatrix is the transform that you read from skin->bind_shape_matrix
Send these FinalJointTrans4x4 matrices and weights to shader (a uniform buffer would be good to store matrices)
Use these information in the shader, render it.
Maybe (from http://github.com/recp/gk):
...
mat4 skinMat;
skinMat = uJoints[JOINTS.x] * WEIGHTS.x
+ uJoints[JOINTS.y] * WEIGHTS.y
+ uJoints[JOINTS.z] * WEIGHTS.z
+ uJoints[JOINTS.w] * WEIGHTS.w;
pos4 = skinMat * pos4;
norm4 = skinMat * norm4;
...
#ifdef JOINT_COUNT
gl_Position = VP * pos4;
#else
gl_Position = MVP * pos4;
#endif
...
There may other details that I may forgot to mention (I may edit the answer later) but this must help a lot.
PS: There is a library called AssetKit (http://github.com/recp/assetkit) you can use it to load COLLADA files if you like.
Upvotes: 2