So I have been working on skeletal animation and skinning for a few weeks, and I hit a road block recently. I am importing the models from the MD5 format, and I have skinning and rendering meshes working.
Everything works fine until I try to animate the model and my inverse bind pose matrices distort the model.
Here is a screenshot of what is happening. The left is what the static model looks like while the right shows what happens after I load the animation and compute the inverse bind pose matrices.
Here is how I compute the bind pose matrices (I call computeBindPose() and traverse the bone hierarchy):
public void computeBindPose() {
computeBindPose(new Matrix4f(), new Matrix4f(), new Matrix4f());
}
private void computeBindPose(Matrix4f base, Matrix4f tmp, Matrix4f tmp2) {
if (bindPose != null)
bindPose.computeMatrix(tmp);
base.mul(tmp, bindPoseMatrix);
bindPoseMatrix.invert(invBindPoseMatrix);
children.forEach(joint -> joint.computeBindPose(bindPoseMatrix, tmp, tmp2));
}
Here is my shader for rendering the meshes:
#version 150 core
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
in vec3 in_Position;
in vec3 in_Normal;
in vec2 in_TextureCoord;
in vec4 in_BoneIndices;
in vec4 in_BoneWeights;
uniform mat4 boneMat[64];
out vec2 pass_TextureCoord;
void main(void) {
vec4 newVertex = vec4(0.0);
vec4 newNormal = vec4(0.0);
mat4 boneTransform = boneMat[int(in_BoneIndices.x)] * in_BoneWeights.x + boneMat[int(in_BoneIndices.y)] * in_BoneWeights.y + boneMat[int(in_BoneIndices.z)] * in_BoneWeights.z + boneMat[int(in_BoneIndices.w)] * in_BoneWeights.w;
newVertex = boneTransform * vec4(in_Position, 1.0);
newNormal = boneTransform * vec4(in_Normal, 0.0);
gl_Position = (projectionMatrix * viewMatrix * modelMatrix) * vec4(newVertex.xyz, 1.0);
pass_TextureCoord = in_TextureCoord;
}