How can I modify animation keyframes to use other skeleton?

Problems building or running the engine, queries about how to use features etc.
Post Reply
megatema
Halfling
Posts: 43
Joined: Fri Mar 09, 2007 12:59 pm
Location: Saint-Petersburg, Russia
x 2
Contact:

How can I modify animation keyframes to use other skeleton?

Post by megatema »

How can I modify animation keyframes to use other initial skeleton position (rotation, scale)?

I have a few .skeleton files. Every skeleton file has one animation inside, because I can’t merge all animation in one file before I export it. I use LinkedSkeletonAnimationSource to load this animation. But I have a problem. Animations (in linked skeletons) use initial transformation from base skeleton and do not play correctly (because animations consist of relative to initial pose transformations). I tried to modify Entity skeleton before play my animation:

Code: Select all

Skeleton::BoneIterator boneIter = pBaseSkel->getBoneIterator();

while(boneIter.hasMoreElements())
{
	Bone *oldBone = boneIter.getNext();
	Bone *newBone = animSrc.pSkeleton->getBone(oldBone->getName());

	oldBone->setPosition(newBone->getInitialPosition());		
	oldBone->setOrientation(newBone->getInitialOrientation());
	oldBone->setScale(newBone->getInitialScale());

	oldBone->setInitialState();
}
It works well, but it's bad way to solve this problem, I think. Because, I’m going to blend animation, and I don’t know how Ogre can blend different animation based on different skeletons. :)

Then, I started to think about different way to solve this. I tried to modify animation, shift and rotate all keyframes to base initial transformation:

Code: Select all

Animation * pAnim = animSrc.pSkeleton->getAnimation("walk");
	
Animation::NodeTrackIterator trackIter = pAnim->getNodeTrackIterator();

while (trackIter.hasMoreElements())
{
NodeAnimationTrack* track = trackIter.getNext();

	//bone from linked skeleton
	Bone*  bone = animSrc.pSkeleton->getBone(track->getHandle());

	//bone from base skeleton
        Bone*  boneMain = pBaseSkel->getBone(bone->getName());
			
	//we need to calculate different of this skeletons
	Vector3 posDelta = boneMain->getInitialPosition() - bone->getInitialPosition();
		
	Matrix3 m1, m2,delta,rot;

	boneMain->getInitialOrientation().ToRotationMatrix(m1);
	bone->getInitialOrientation().ToRotationMatrix(m2);
	m2.Inverse();

	delta = m1*m2;

	short num = track->getNumKeyFrames();

	for(short i = 0; i < num; i++)
	{
		TransformKeyFrame *key = track->getNodeKeyFrame(i);
		
		key->getRotation().ToRotationMatrix(rot);
	
		Vector3    v = key->getTranslate();
			
		rot = rot*delta;
		v = v + posDelta;

		Quaternion q(rot);
				
		key->setRotation(q);
		key->setTranslate(v);
	}
}
But result is weird :) May be anybody knows why it’s not worked?
genva
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 1603
Joined: Wed Oct 20, 2004 7:54 am
Location: Beijing, China
x 1

Post by genva »

[angry on]
:evil: You are discourteous, do you known?

We work for Ogre and answer questions in off hours, got no fee for it. You ask this question just a while ago, within three hours, why you sent several e-mail to us but can't wait for a bit? Are you think we are work full time for you?

I keep my right to refuse answer your question.
[angry off]
megatema
Halfling
Posts: 43
Joined: Fri Mar 09, 2007 12:59 pm
Location: Saint-Petersburg, Russia
x 2
Contact:

Post by megatema »

genva wrote:[angry on]
:evil: You are discourteous, do you known?

We work for Ogre and answer questions in off hours, got no fee for it. You ask this question just a while ago, within three hours, why you sent several e-mail to us but can't wait for a bit? Are you think we are work full time for you?

I keep my right to refuse answer your question.
[angry off]
I'm very sorry! :oops: But it's really important for us.
User avatar
sinbad
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 19269
Joined: Sun Oct 06, 2002 11:19 pm
Location: Guernsey, Channel Islands
x 66
Contact:

Post by sinbad »

genva is right, it's extremely presumptuous of you to start emailing the team directly (twice in my case) because you don't get an answer within a couple of hours. It might be important to you, but there are at least a thousand or so other people here who also have what they perceive to be important questions, and you're just one of them. We do our best, but we're not super-human or poised at the keyboard 24/7 waiting for your questions you know. The team cannot answer every single question, never mind whithin 2 hours. Taking liberties like that just puts people off actually helping you. Personally your email ticked me off so I just shelved it for a few more hours - I've calmed down now so my response is more polite than it might have been.

Put it this way - when you're getting help for free out of the good of people's hearts, you don't get to crack the whip, ok? Especially when people might be at work or asleep in their own time zone and you only waited for 2 short hours.

Right, back to the question. I believe what you're saying is that you're linking animations across 2 skeletons which don't have the same bind pose, correct?

You can't really do this. The reason is simple - the bind position is used at either end of the skeletal animation calculation - to reset the bones and then to calculate a final transforms to take each vertex in object space into bone space and then back out to the final animated position. If you blend together animations from one skeleton with animations from another, they have to have the same bind position otherwise that won't work. There really isn't anything you can do about that. You can vary the elements that aren't animated (a common one is scale for example, so you can use common animations from one humanoid to another much larger one), but the bind settings of the parts that change in the animation (position, orientation) must be consistent.
Post Reply