[OGRE/HAVOK] Copying the pose of an animated skeleton from Havok to Ogre

Started by
6 comments, last by Matias Goldberg 13 years, 4 months ago
Using: Ogre, Havok, 3dsMax.

I'm trying to get Havok Animation running underneath Ogre's graphics, and while I seem to be really close, I've hit an obstacle. My problem is that the animation is definitely recognizable, but extremely distorted. The skinning appears to be intact, and the transformations appear to correspond with the correct bone, but the animation is represented chaotically. For one animation, the character stayed in its figure pose and I turned its head to look to the left. This resulted in the character's head coming out forward and to the left; The rest of the character's body was still a total mess. The mesh, when no Havok animation is attempted, will appear as it should.

Here is the code that I'm using to translate the pose. Any help that can be offered would be greatly appreciated, and if I'm not giving enough info, please let me know.

void OgreHavok::ApplyHavokPoseToOgreSkeleton(Ogre::Skeleton* ogreskeleton, hkaAnimatedSkeleton* havokskeleton, std::vector<hkaBone*> havokbones){			hkaPose pose(havokskeleton->getSkeleton());					havokskeleton->sampleAndCombineAnimations(pose.accessUnsyncedPoseLocalSpace().begin(), pose.getFloatSlotValues().begin());							int i = 0;	for(i; i < havokbones.size(); i++)	{		if(havokbones.at(i) != HK_NULL)		{															hkQsTransform transform = pose.getBoneLocalSpace(i);					ogreskeleton->getBone(i)->setOrientation(ConvertToOQuaternion(transform.getRotation()));						ogreskeleton->getBone(i)->setPosition(ConvertToOVector3(transform.getTranslation()));		}					}}


And my Quaternion conversion, just in case:

Ogre::Quaternion OgreHavok::ConvertToOQuaternion(const hkQuaternion &quaternion){	hkQuaternion newRotation = quaternion;	hkVector4 vec = newRotation.m_vec;	Ogre::Quaternion newOgRot( vec(3), vec(0), vec(1), vec(2) );		return newOgRot;}
Advertisement
Are you sure havokbones.at(i) and ogreskeleton->getBone(i) point at the same bone?
Because that's a stupid bug related with the exporters and would totally explain it.
Try using naming conventions and see if they match up.

Cheers
Dark Sylinc
Before I pasted that code, I removed two lines of code that returned the bone names of havokbones.at(i) and ogreskeleton->getBone(i), and they match up throughout. Plus, despite the transformations being completely out of whack, they do seem to be applying to the correct bones (if I rotate an eyeball 90 degrees in Max, the eyeball will leave the skull and fan out 90 degrees in the game).

And just to clarify, havokbones is a vector in the same order as the Ogre bone indexes, with each element pointing to the corresponding Havok bone (safety measure despite the fact that both skeletons seem to be in the same order regardless). It is, of course, set up in another method.
Although Havok is convention agnostic as it can get, sometimes it assumes facing forward is Unit_X, while Ogre assumes forward is Unit_Z

Try multiplying the quaternions by:

Ogre::Quaternion( Ogre::Degree(90.0f), Ogre::Vector3::NEGATIVE_UNIT_Y );//or in havok code:static const hkVector4 hkNEG_UNIT_Y( 0, -1, 0 );quat.mul( hkQuaternion( hkNEG_UNIT_Y, Ogre::Degree(90.0f).valueRadians() ) );


See how that goes.
I don't think that's the problem since you say the resting pose is correct but it's worth a try.
By the way all your Ogre bones are tagged as manually controlled and you don't have any animation state turned on, do you?
I'll try your Quaternion code as soon as I get home, but just to ask while I can't test it myself, will this most likely result in the entire model being rotated while still keeping the same local transformations, or could that actually result in the bones being in new angles relative to each other?

The bones are definitely set to manual control (I set it to false to test whether or not it made a difference). Left-over Ogre animation code is possible, so I'll be sure to check that as well; Does an un-animated Ogre mesh rest in its model-me pose, or in the first keyframe of its animation?
Just checking in to say the problem's still active. No animations are playing on the mesh, and the Quaternion mod didn't fix anything. I tried using a default transformation on the Havok exporter (before I had it transform so that it would match my Ogre meshes coordinate system-wise), and now the model shows up correctly (in the wrong direction), or at least VERY close to correct, when left or even "animated" in its figure pose. I tried the following animations in a futile attempt to pinpoint the problem:

*I tried an animation where the character lifted his arm upwards from a -45 degree angle to a 45 degree angle, and in the game his arm translated (still skinned properly) through his body out past the other arm while doing an odd rotation. I also tried an animation

*An animation of the character bending his torso back 90 degrees (by the initial Bip spine). This resulted in what seemed to be the entire torso bending back as I had bent it in Max, but without taking any child limbs with it (the head and arms stayed in place)

*An animation of the character bending his leg at the calf backward at 90 degrees. This resulted in the entire leg being distorted except for the foot, which in Max, does not rotate when you rotate the leg.

I'm starting to get the suspicion (though keep in mind if I knew the problem, it would already be fixed) that this may be related to how I'm exporting something, either the Ogre mesh, or the Havok skeleton, rather than my code. Any insight that could be offered would be greatly appreciated.

PS. As of writing this post it occurred to me that I'm using Max's Biped; Is there any reason this shouldn't work with Havok, despite the animations playing just fine in the Preview Tool?
I have no idea, it ought to be working.
Another long shot, Havok might be deriving scaling propierties to children, while Ogre turns them off by default.

To get a better idea of what's going on, I would leave them in the rest pose and debug if the transforms from both skeletons match.
Then I would pick one bone by it's index from Havok (i.e. the torso, as you've been trying) rotate it 90°; and copy the result to Ogre. Then see the what happens. Note I wouldn't be iterating through all your bones to copy all transforms, I would disable that code and copy just the torso's.

If the torso works ok, go to another bone, if that bones ok, see what happens when modifying a bone, and it's immediate parent (you would then be copying two bone transformations)

This topic is closed to new replies.

Advertisement