Currently i store all bones in world space and load them directly from binary file.
I check this skeleton by placing an "arrow object" with the matrix bone_mat as "modelmatrix". Works as expected.
Variable explanations:
1. bone_mat = world_space bone matrix (loaded from file)
2. bind_pose_mat = relative transformation from parent bone to current bone
3. skinning_mat = final joint transformation matrix
The next step is to calculate the bind pose matrix. The relative bone matrix to its parent.
I do it this way:
/* bone mat * inverse(parent bone mat) */
mesh->anim_data.skeleton[i].bind_pose_mat =
urdMat4MulMat4( mesh->anim_data.skeleton[i].bone_mat, urdMat4Inverse(parent_bone->bone_mat) );
I check this matrix by getting it into world space again like this:
world_space_mat =
urdMat4MulMat4( mesh->anim_data.skeleton[i].bind_pose_mat, parent_bone->bone_mat);
Which results in the same matrix as bone_mat.
Root bones are stored in world space, as they are not relative to any parent
root_bone.bind_pose_mat = bone_mat
so now that im in local space, i though all i needed to do was
/* interpolated vertex = base_vertex * bones[bone_index].bind_pose_mat */
mesh->interpolated[i].vertex = urdMat4MulVec3(skeleton[bone_index].bind_pose_mat , mesh->base[i].vertex);
which results in a distorted mesh.
Edit: After some thoughts, it looks like im not in local space, but in relative space (bind_pose is currently the relative matrix to its parent).
But im stuck with theory there.
Ok, looks like i got it working.
Math Equation is (simplified):
v' = SUM { w * m * v }
where
- w is the weight (all bones have 1.0 weight currently)
- m is the world space bone matrix (animation bone)
- v is the relative vertex position of the bind pose
inv_bone_mat = the inverted world space bone matrix
bone_mat = world space bone matrix
to calculate v:
vec3 v_relative = bind_bones[bone_index].inv_bone_mat * vertex_object_space
now all that was needed is:
vec3 skinned_vertex = frame[current_frame].anim_bones[bone_index].bone_mat * v_relative
ofc this can be extended by multiple bones/weight influences
i hope this helps future readers.