1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-02-01 20:45:33 +00:00

Reset the initial state of animated nodes on the skeleton instances

This is so the animation specifies node keyframe data based on the node's
parent. This will also be necessary for applying animations from different
skeleton sources, as they can have different binding positions (even native
.skeleton resources will need to specify animation data this way).
This commit is contained in:
Chris Robinson 2013-01-26 04:48:53 -08:00
parent 05f8b8c283
commit b1ffdf855f
2 changed files with 27 additions and 10 deletions

View file

@ -78,7 +78,7 @@ void Animation::createEntityList(Ogre::SceneNode *node, const std::string &model
mAccumRoot->setManuallyControlled(true);
mNonAccumRoot = skelinst->getBone(bone->getHandle());
mStartPosition = mNonAccumRoot->getPosition();
mStartPosition = mNonAccumRoot->getInitialPosition();
mLastPosition = mStartPosition;
asiter = aset->getAnimationStateIterator();
@ -93,6 +93,26 @@ void Animation::createEntityList(Ogre::SceneNode *node, const std::string &model
break;
}
// Reset initial state of bones that are animated, so the animation correctly applies.
if(skelinst->getNumAnimations() > 0)
{
Ogre::Animation *anim = skelinst->getAnimation(0);
Ogre::Animation::NodeTrackIterator trackiter = anim->getNodeTrackIterator();
while(trackiter.hasMoreElements())
{
const Ogre::Node *srcnode = trackiter.getNext()->getAssociatedNode();
const Ogre::Node *srcbone = dynamic_cast<const Ogre::Bone*>(srcnode);
if(!srcbone || !skelinst->hasBone(srcbone->getName()))
continue;
Ogre::Bone *bone = skelinst->getBone(srcbone->getName());
bone->setOrientation(Ogre::Quaternion::IDENTITY);
bone->setPosition(Ogre::Vector3::ZERO);
bone->setScale(Ogre::Vector3(1.0f));
bone->setInitialState();
}
}
}
}

View file

@ -193,19 +193,16 @@ static void buildAnimation(Ogre::Skeleton *skel, const std::string &name, const
Ogre::NodeAnimationTrack *nodetrack = anim->hasNodeTrack(bone->getHandle()) ?
anim->getNodeTrack(bone->getHandle()) :
anim->createNodeTrack(bone->getHandle(), bone);
const Ogre::Quaternion &startquat = bone->getInitialOrientation();
const Ogre::Vector3 &starttrans = bone->getInitialPosition();
const Ogre::Vector3 &startscale = bone->getInitialScale();
Ogre::Quaternion lastquat, curquat;
Ogre::Vector3 lasttrans(0.0f), curtrans(0.0f);
Ogre::Vector3 lastscale(1.0f), curscale(1.0f);
if(quatiter != quatkeys.mKeys.end())
lastquat = curquat = startquat.Inverse() * quatiter->mValue;
lastquat = curquat = quatiter->mValue;
if(traniter != trankeys.mKeys.end())
lasttrans = curtrans = traniter->mValue - starttrans;
lasttrans = curtrans = traniter->mValue;
if(scaleiter != scalekeys.mKeys.end())
lastscale = curscale = Ogre::Vector3(scaleiter->mValue) / startscale;
lastscale = curscale = Ogre::Vector3(scaleiter->mValue);
float begTime = std::max(kfc->timeStart, startTime);
float endTime = std::min(kfc->timeStop, stopTime);
bool didlast = false;
@ -235,19 +232,19 @@ static void buildAnimation(Ogre::Skeleton *skel, const std::string &name, const
{
lastquat = curquat;
if(++quatiter != quatkeys.mKeys.end())
curquat = startquat.Inverse() * quatiter->mValue;
curquat = quatiter->mValue;
}
while(traniter != trankeys.mKeys.end() && curtime >= traniter->mTime)
{
lasttrans = curtrans;
if(++traniter != trankeys.mKeys.end())
curtrans = traniter->mValue - starttrans;
curtrans = traniter->mValue;
}
while(scaleiter != scalekeys.mKeys.end() && curtime >= scaleiter->mTime)
{
lastscale = curscale;
if(++scaleiter != scalekeys.mKeys.end())
curscale = Ogre::Vector3(scaleiter->mValue) / startscale;
curscale = Ogre::Vector3(scaleiter->mValue);
}
Ogre::TransformKeyFrame *kframe;