Save the inversebindposeMatrix After load a file
while ( iter != MD5Model.joints.end() )
{
const Joint& joint = (*iter);
XMMATRIX boneRotate = XMMatrixRotationQuaternion( XMLoadFloat4(&joint.orientation) );
XMMATRIX boneTranslate = XMMatrixTranslationFromVector( XMLoadFloat3(&joint.pos) );
XMMATRIX boneMatrix = XMMatrixMultiply(boneRotate, boneTranslate);
XMMATRIX inverseBoneMatrix = XMMatrixInverse(&XMVectorSet(0,0,0,0),boneMatrix );
MD5Model.bindPoseMat.push_back( inverseBoneMatrix );//Save inversebindposeMatrices
++iter;
}
and Calculate each InterpolatedBoneMatrix with inversebindposeMatrix
void ModelMD5::UpdateMD5Model(float deltaTime, int animation)
{
animations[animation].currAnimTime += deltaTime; // Update the current animation time
if(animations[animation].currAnimTime > animations[animation].totalAnimTime)
animations[animation].currAnimTime = 0.0f;
// Which frame are we on
float currentFrame = animations[animation].currAnimTime * animations[animation].frameRate;
int frame0 = floorf( currentFrame );
int frame1 = frame0 + 1;
// Make sure we don't go over the number of frames
if(frame0 == animations[animation].numFrames-1)
frame1 = 0;
float interpolation = currentFrame - frame0; // Get the remainder (in time) between frame0 and frame1 to use as interpolation factor
//std::vector<Joint> interpolatedSkeleton; // Create a frame skeleton to store the interpolated skeletons in
// Compute the interpolated skeleton
for( int i = 0; i < animations[animation].numJoints; i++) // numJoints = 31;
{
XMMATRIX finalMatrix=XMMatrixIdentity();
Joint finalJoint = animationskeleton.vector_joint[i];
Joint joint0 = animations[animation].frameSkeleton[frame0].vector_joint[i]; // Get the i'th joint of frame0's skeleton
Joint joint1 = animations[animation].frameSkeleton[frame1].vector_joint[i]; // Get the i'th joint of frame1's skeleton
finalJoint.parentID = joint0.parentID; // Set the tempJoints parent id
// Turn the two quaternions into XMVECTORs for easy computations
XMVECTOR joint0Orient = XMVectorSet(joint0.orientation.x, joint0.orientation.y, joint0.orientation.z, joint0.orientation.w);
XMVECTOR joint1Orient = XMVectorSet(joint1.orientation.x, joint1.orientation.y, joint1.orientation.z, joint1.orientation.w);
// Interpolate positions
finalJoint.pos.x = joint0.pos.x + (interpolation * (joint1.pos.x - joint0.pos.x));
finalJoint.pos.y = joint0.pos.y + (interpolation * (joint1.pos.y - joint0.pos.y));
finalJoint.pos.z = joint0.pos.z + (interpolation * (joint1.pos.z - joint0.pos.z));
// Interpolate orientations using spherical interpolation (Slerp)
XMStoreFloat4(&finalJoint.orientation, XMQuaternionSlerp(joint0Orient, joint1Orient, interpolation));
XMStoreFloat4(&finalJoint.orientation,joint0Orient);
finalMatrix = XMMatrixMultiply(XMMatrixRotationQuaternion(XMLoadFloat4(&finalJoint.orientation)),XMMatrixTranslation(finalJoint.pos.x,finalJoint.pos.y, finalJoint.pos.z ));
XMMATRIX TranslateMat=XMMatrixTranslation( finalJoint.pos.x, finalJoint.pos.y, finalJoint.pos.z );
XMMATRIX RotateMat=XMMatrixRotationQuaternion(XMLoadFloat4(&finalJoint.orientation));
finalAnimMatrix[i] = XMMatrixMultiply(bindPoseMat[i],finalMatrix);
}
}
and Skinning with this Matrices.
http://www.dropbox.com/s/5y6vgwf4wxlz6ai/dx11.jpg?dl=0
The general movement of the mesh is correct but some vertices move with an strange direction / orientation which forces a lot of clipping to occur.
http://www.dropbox.com/s/rbplbhhzumj3u0s/opengl.jpg?dl=0
this is the correct result.