Look through the whole animation stack to find the "velocity"

This commit is contained in:
Chris Robinson 2013-04-22 01:40:41 -07:00
parent a7776e124c
commit 9485a4aa6d
2 changed files with 35 additions and 25 deletions

View file

@ -209,26 +209,26 @@ void Animation::updatePtr(const MWWorld::Ptr &ptr)
} }
void Animation::calcAnimVelocity() float Animation::calcAnimVelocity(Ogre::Animation *anim, const std::string &bonename, const std::string &groupname, const NifOgre::TextKeyMap *keys)
{ {
const Ogre::NodeAnimationTrack *track = 0; const Ogre::NodeAnimationTrack *track = 0;
Ogre::Animation::NodeTrackIterator trackiter = mCurrentAnim->getNodeTrackIterator(); Ogre::Animation::NodeTrackIterator trackiter = anim->getNodeTrackIterator();
while(!track && trackiter.hasMoreElements()) while(!track && trackiter.hasMoreElements())
{ {
const Ogre::NodeAnimationTrack *cur = trackiter.getNext(); const Ogre::NodeAnimationTrack *cur = trackiter.getNext();
if(cur->getAssociatedNode()->getName() == mNonAccumRoot->getName()) if(cur->getAssociatedNode()->getName() == bonename)
track = cur; track = cur;
} }
if(track && track->getNumKeyFrames() > 1) if(track && track->getNumKeyFrames() > 1)
{ {
const std::string loopstart = mCurrentGroup+": loop start"; const std::string loopstart = groupname+": loop start";
const std::string loopstop = mCurrentGroup+": loop stop"; const std::string loopstop = groupname+": loop stop";
float loopstarttime = 0.0f; float loopstarttime = 0.0f;
float loopstoptime = mCurrentAnim->getLength(); float loopstoptime = anim->getLength();
NifOgre::TextKeyMap::const_iterator keyiter = mCurrentKeys->begin(); NifOgre::TextKeyMap::const_iterator keyiter = keys->begin();
while(keyiter != mCurrentKeys->end()) while(keyiter != keys->end())
{ {
if(keyiter->second == loopstart) if(keyiter->second == loopstart)
loopstarttime = keyiter->first; loopstarttime = keyiter->first;
@ -245,13 +245,15 @@ void Animation::calcAnimVelocity()
Ogre::TransformKeyFrame startkf(0, loopstarttime); Ogre::TransformKeyFrame startkf(0, loopstarttime);
Ogre::TransformKeyFrame endkf(0, loopstoptime); Ogre::TransformKeyFrame endkf(0, loopstoptime);
track->getInterpolatedKeyFrame(mCurrentAnim->_getTimeIndex(loopstarttime), &startkf); track->getInterpolatedKeyFrame(anim->_getTimeIndex(loopstarttime), &startkf);
track->getInterpolatedKeyFrame(mCurrentAnim->_getTimeIndex(loopstoptime), &endkf); track->getInterpolatedKeyFrame(anim->_getTimeIndex(loopstoptime), &endkf);
mAnimVelocity = startkf.getTranslate().distance(endkf.getTranslate()) / return startkf.getTranslate().distance(endkf.getTranslate()) /
(loopstoptime-loopstarttime); (loopstoptime-loopstarttime);
} }
} }
return 0.0f;
} }
static void updateBoneTree(const Ogre::SkeletonInstance *skelsrc, Ogre::Bone *bone) static void updateBoneTree(const Ogre::SkeletonInstance *skelsrc, Ogre::Bone *bone)
@ -423,27 +425,34 @@ bool Animation::handleEvent(float time, const std::string &evt)
void Animation::play(const std::string &groupname, const std::string &start, const std::string &stop, bool loop) void Animation::play(const std::string &groupname, const std::string &start, const std::string &stop, bool loop)
{ {
try { try {
bool found = false; bool foundanim = false;
/* Look in reverse; last-inserted source has priority. */ /* Look in reverse; last-inserted source has priority. */
for(std::vector<NifOgre::ObjectList>::reverse_iterator iter(mObjectLists.rbegin());iter != mObjectLists.rend();iter++) for(std::vector<NifOgre::ObjectList>::reverse_iterator iter(mObjectLists.rbegin());iter != mObjectLists.rend();iter++)
{ {
if(iter->mSkelBase && iter->mSkelBase->hasAnimationState(groupname)) if(iter->mSkelBase && iter->mSkelBase->hasAnimationState(groupname))
{ {
Ogre::SkeletonInstance *skel = iter->mSkelBase->getSkeleton(); Ogre::SkeletonInstance *skel = iter->mSkelBase->getSkeleton();
mCurrentAnim = skel->getAnimation(groupname); Ogre::Animation *anim = skel->getAnimation(groupname);
mCurrentKeys = &iter->mTextKeys.begin()->second; const NifOgre::TextKeyMap *keys = &iter->mTextKeys.begin()->second;
mCurrentGroup = groupname; if(!foundanim)
mCurrentControllers = &iter->mControllers; {
mCurrentAnim = anim;
mCurrentKeys = keys;
mCurrentGroup = groupname;
mCurrentControllers = &iter->mControllers;
mAnimVelocity = 0.0f; mAnimVelocity = 0.0f;
if(mNonAccumRoot) foundanim = true;
calcAnimVelocity(); }
found = true; if(!mNonAccumRoot)
break; break;
mAnimVelocity = calcAnimVelocity(anim, mNonAccumRoot->getName(), groupname, keys);
if(mAnimVelocity > 0.0f) break;
} }
} }
if(!found) if(!foundanim)
throw std::runtime_error("Failed to find animation "+groupname); throw std::runtime_error("Failed to find animation "+groupname);
reset(mCurrentGroup+": "+start, mCurrentGroup+": "+stop); reset(mCurrentGroup+": "+start, mCurrentGroup+": "+stop);

View file

@ -54,7 +54,7 @@ protected:
std::string mCurrentGroup; std::string mCurrentGroup;
std::vector<Ogre::Controller<Ogre::Real> > *mCurrentControllers; std::vector<Ogre::Controller<Ogre::Real> > *mCurrentControllers;
NifOgre::TextKeyMap *mCurrentKeys; const NifOgre::TextKeyMap *mCurrentKeys;
NifOgre::TextKeyMap::const_iterator mStartKey; NifOgre::TextKeyMap::const_iterator mStartKey;
NifOgre::TextKeyMap::const_iterator mStopKey; NifOgre::TextKeyMap::const_iterator mStopKey;
NifOgre::TextKeyMap::const_iterator mNextKey; NifOgre::TextKeyMap::const_iterator mNextKey;
@ -65,7 +65,8 @@ protected:
float mAnimVelocity; float mAnimVelocity;
float mAnimSpeedMult; float mAnimSpeedMult;
void calcAnimVelocity(); static float calcAnimVelocity(Ogre::Animation *anim, const std::string &bonename,
const std::string &groupname, const NifOgre::TextKeyMap *keys);
/* Updates a skeleton instance so that all bones matching the source skeleton (based on /* Updates a skeleton instance so that all bones matching the source skeleton (based on
* bone names) are positioned identically. */ * bone names) are positioned identically. */