I've looked through a lot of tutorials and many books but I've really been struggeling with this for a while now. I believe all the data is being loaded correctly and I'm just not using the transformations correctly, but I haven't been able to pinpoint exactly what the problem.
What happens to the model is that I can see vertices moving around and rotating, but the mesh is skewed and not translated properly.
I'm using the data provided by Assimp for the animations, so there might be something I'm not aware of. Here is some of the relevant code.
//code in animationfor(unsigned int i = 0; i < mNumChannels; ++i) //each channel affects a single bone{ chan = &mChannels; math::Vec3<float> * posVec = &chan->mPositionKeys[0].mVec; math::Quaternion * quat = &chan->mRotationKeys[0].mQuat; float scale = chan->mScaleKeys[0].mVec.x; //turn into uniform scaling... unsigned int j; for(j = 0; j < chan->mNumPositionKeys; ++j) { if(chan->mPositionKeys[j].mTime >= delta){ posVec = &chan->mPositionKeys[j].mVec; break; } } for(j = 0; j < chan->mNumRotationKeys; ++j) { if(chan->mRotationKeys[j].mTime >= delta){ quat = &chan->mRotationKeys[j].mQuat; break; } } for(j = 0; j < chan->mNumScaleKeys; ++j) { if(chan->mScaleKeys[j].mTime >= delta){ scale = chan->mScaleKeys[j].mVec.x; break; } } SkeletonNode* node = mSkeleton->findNode(chan->mName); //order of transformation is scaling, rotation, translation. math::Matrix4x4 trans; //identity matrix trans.mMatrix[3] = posVec->x; trans.mMatrix[7] = posVec->y; trans.mMatrix[11] = posVec->z; math::Matrix4x4 matscle; //identity matrix matscle.mMatrix[0] = scale; matscle.mMatrix[5] = scale; matscle.mMatrix[10] = scale; math::Matrix4x4 orient; quat->toMatrix4x4(orient); math::Matrix4x4 final; final = orient * trans; //not using scale for testing node->updateTransform(final);}mSkeleton->updateBones()
void SkeletonNode::updateTransform(math::Matrix4x4& transform){ mLocalTransform = transform; return;}
//update bone helper functionvoid Skeleton::updateBonesH(SkeletonNode *node, math::Matrix4x4 transform){ if(!node) return; node->mGlobalTransform = transform * node->mLocalTransform; for(unsigned int i = 0; i < node->mNumChildren; ++i) { updateBonesH(&node->mChildren, node->mGlobalTransform); } if(node->mBone){ math::Matrix4x4 b = node->mBone->mOffsetMatrix; //inverse bind pos math::Matrix4x4 c = node->mGlobalTransform; //current pose math::Matrix4x4 f = b * c; node->mBone->mFinalMatrix = f; }}
And here is my vertex shader...
#version 130in vec4 position;in vec4 boneWeightValue;in vec4 boneWeightIndex;uniform mat4 boneMatrices[32];uniform mat4 perspectiveModelViewMatrix;uniform mat4 modelViewMatrix;void main(){ vec4 pos1 = boneWeightValue.x * (boneMatrices[int(boneWeightIndex.x)] * position); vec4 pos2 = boneWeightValue.y * (boneMatrices[int(boneWeightIndex.y)] * position); vec4 pos3 = boneWeightValue.z * (boneMatrices[int(boneWeightIndex.z)] * position); vec4 pos4 = boneWeightValue.w * (boneMatrices[int(boneWeightIndex.w)] * position); vec4 pos = pos1 + pos2 + pos3 + pos4; gl_Position = perspectiveModelViewMatrix * pos;}
The bone matrices seem to be transferred correctly to the shader, since the initial pose, without any animation, is perfectly fine.
I would really appreciate it if anyone has any experience working with Assimp animations, or can help me in understand what I'm doing wrong.
[Edited by - lmffs on August 30, 2010 3:29:15 PM]