Calculating Bone transformation in Ogre3d

Anything and everything that's related to OGRE or the wider graphics field that doesn't fit into the other forums.
Post Reply
andreahmed
Kobold
Posts: 38
Joined: Wed Dec 31, 2014 2:26 am
x 2

Calculating Bone transformation in Ogre3d

Post by andreahmed »

I'm using ogreassimp converter that convertes an FBX file and make a skeletal with bones.. but right now I have an animated mesh that does rotation relative to another object.. The first object should rotate independently to the other object.. but what I see is that BOTH objects rotates..

Here is how it's calculated and the comment from the Author

// DefBonePose a matrix that represents the local bone transform (can build from Ogre bone components)
// PoseToKey a matrix representing the keyframe translation
// What assimp stores aiNodeAnim IS the decomposed form of the transform (DefBonePose * PoseToKey)
// To get PoseToKey which is what Ogre needs we'ed have to build the transform from components in
// aiNodeAnim and then DefBonePose.Inverse() * aiNodeAnim(generated transform) will be the right transform


Ogre::Bone* bone = mSkeleton->getBone(boneName);
Ogre::Matrix4 defBonePoseInv;
defBonePoseInv.makeInverseTransform(bone->getPosition(), bone->getScale(), bone->getOrientation());
and for key frame bones animation

KeyframesMap::iterator it = keyframes.begin();
KeyframesMap::iterator it_end = keyframes.end();
for(it; it != it_end; ++it)
{
if(it->first < cutTime) // or should it be <=
{
aiVector3D aiTrans = getTranslate( node_anim, keyframes, it, mTicksPerSecond);

Ogre::Vector3 trans(aiTrans.x, aiTrans.y, aiTrans.z);

aiQuaternion aiRot = getRotate(node_anim, keyframes, it, mTicksPerSecond);
Ogre::Quaternion rot(aiRot.w, aiRot.x, aiRot.y, aiRot.z);
aiVector3D aiScale = getScale(node_anim, keyframes, it, mTicksPerSecond);

Ogre::Vector3 scale(aiScale.x,aiScale.y,aiScale.z); // ignore scale for now

Ogre::Vector3 transCopy = trans;
Ogre::Quaternion rotCopy = rot;
Ogre::Vector3 scaleCopy = scale;

Ogre::Matrix4 fullTransform;
fullTransform.makeTransform(trans, scale, rot);

Ogre::Matrix4 poseTokey = defBonePoseInv * fullTransform;
poseTokey.decomposition(trans, scale, rot);

keyframe = track->createNodeKeyFrame(Ogre::Real(it->first));

// weirdness with the root bone, But this seems to work
if(mSkeleton->getRootBone()->getName() == boneName)
{
trans = transCopy - bone->getPosition();

}

bone->setInheritOrientation(false);
Ogre::Real ret = std::max(scale.x, scale.y);
ret = std::max(ret, scale.z);
scale.x = ret;
scale.y = ret;
scale.z = ret;
keyframe->setTranslate(trans);
keyframe->setRotation(rot);
keyframe->setScale(scale);
}
}

} // if bone exists
Post Reply