1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-27 03:35:27 +00:00

Use reset to check that the animation exists and has the right markers

This commit is contained in:
Chris Robinson 2013-04-22 20:41:54 -07:00
parent 507d72ede5
commit a2fc43c7df
2 changed files with 72 additions and 61 deletions

View File

@ -209,14 +209,14 @@ void Animation::updatePtr(const MWWorld::Ptr &ptr)
} }
float Animation::calcAnimVelocity(NifOgre::NodeTargetValue<Ogre::Real> *nonaccumctrl, const std::string &groupname, const NifOgre::TextKeyMap *keys) float Animation::calcAnimVelocity(const NifOgre::TextKeyMap &keys, NifOgre::NodeTargetValue<Ogre::Real> *nonaccumctrl, const std::string &groupname)
{ {
const std::string loopstart = groupname+": loop start"; const std::string loopstart = groupname+": loop start";
const std::string loopstop = groupname+": loop stop"; const std::string loopstop = groupname+": loop stop";
float loopstarttime = 0.0f; float loopstarttime = 0.0f;
float loopstoptime = std::numeric_limits<float>::max(); float loopstoptime = 0.0f;
NifOgre::TextKeyMap::const_iterator keyiter = keys->begin(); NifOgre::TextKeyMap::const_iterator keyiter = keys.begin();
while(keyiter != keys->end()) while(keyiter != keys.end())
{ {
if(keyiter->second == loopstart) if(keyiter->second == loopstart)
loopstarttime = keyiter->first; loopstarttime = keyiter->first;
@ -291,36 +291,44 @@ Ogre::Vector3 Animation::updatePosition()
return posdiff; return posdiff;
} }
void Animation::reset(const std::string &start, const std::string &stop) bool Animation::reset(const NifOgre::TextKeyMap &keys, NifOgre::NodeTargetValue<Ogre::Real> *nonaccumctrl, const std::string &groupname, const std::string &start, const std::string &stop)
{ {
std::string tag = mCurrentGroup+": "+start; std::string tag = groupname+": "+start;
mStartKey = mCurrentKeys->begin(); NifOgre::TextKeyMap::const_iterator startkey(keys.begin());
while(mStartKey != mCurrentKeys->end() && mStartKey->second != tag) while(startkey != keys.end() && startkey->second != tag)
mStartKey++; startkey++;
if(mStartKey == mCurrentKeys->end() && tag == "loop start") if(startkey == keys.end() && tag == "loop start")
{ {
tag = mCurrentGroup+": start"; tag = groupname+": start";
mStartKey = mCurrentKeys->begin(); startkey = keys.begin();
while(mStartKey != mCurrentKeys->end() && mStartKey->second != tag) while(startkey != keys.end() && startkey->second != tag)
mStartKey++; startkey++;
} }
if(mStartKey == mCurrentKeys->end()) if(startkey == keys.end())
mStartKey = mCurrentKeys->begin(); return false;
tag = mCurrentGroup+": "+stop; tag = groupname+": "+stop;
mStopKey = mStartKey; NifOgre::TextKeyMap::const_iterator stopkey(startkey);
while(mStopKey != mCurrentKeys->end() && mStopKey->second != tag) while(stopkey != keys.end() && stopkey->second != tag)
mStopKey++; stopkey++;
if(mStopKey == mCurrentKeys->end()) if(stopkey == keys.end())
mStopKey--; return false;
mCurrentTime = mStartKey->first; if(startkey == stopkey)
return false;
mStartKey = startkey;
mLoopStartKey = mStartKey; mLoopStartKey = mStartKey;
mStopKey = stopkey;
mNextKey = mStartKey; mNextKey = mStartKey;
++mNextKey; ++mNextKey;
if(mNonAccumCtrl) mCurrentTime = mStartKey->first;
mLastPosition = mNonAccumCtrl->getTranslation(mCurrentTime) * mAccumulate;
if(nonaccumctrl)
mLastPosition = nonaccumctrl->getTranslation(mCurrentTime) * mAccumulate;
return true;
} }
void Animation::doLoop() void Animation::doLoop()
@ -390,45 +398,46 @@ void Animation::play(const std::string &groupname, const std::string &start, con
/* 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->mTextKeys.size() == 0)
continue;
const NifOgre::TextKeyMap &keys = iter->mTextKeys.begin()->second;
NifOgre::NodeTargetValue<Ogre::Real> *nonaccumctrl = NULL;
for(size_t i = 0;i < iter->mControllers.size();i++)
{ {
const NifOgre::TextKeyMap *keys = &iter->mTextKeys.begin()->second; NifOgre::NodeTargetValue<Ogre::Real> *dstval;
NifOgre::NodeTargetValue<Ogre::Real> *nonaccumctrl = NULL; dstval = dynamic_cast<NifOgre::NodeTargetValue<Ogre::Real>*>(iter->mControllers[i].getDestination().getPointer());
for(size_t i = 0;i < iter->mControllers.size();i++) if(dstval && dstval->getNode() == mNonAccumRoot)
{ {
NifOgre::NodeTargetValue<Ogre::Real> *dstval; nonaccumctrl = dstval;
dstval = dynamic_cast<NifOgre::NodeTargetValue<Ogre::Real>*>(iter->mControllers[i].getDestination().getPointer());
if(dstval && dstval->getNode() == mNonAccumRoot)
{
nonaccumctrl = dstval;
break;
}
}
if(!foundanim)
{
mCurrentKeys = keys;
mCurrentGroup = groupname;
mCurrentControllers = &iter->mControllers;
mNonAccumCtrl = nonaccumctrl;
mAnimVelocity = 0.0f;
foundanim = true;
}
if(!mNonAccumRoot)
break; break;
}
mAnimVelocity = calcAnimVelocity(nonaccumctrl, groupname, keys);
if(mAnimVelocity > 0.0f) break;
} }
if(!foundanim)
{
if(!reset(keys, nonaccumctrl, groupname, start, stop))
continue;
mCurrentKeys = &keys;
mCurrentGroup = groupname;
mCurrentControllers = &iter->mControllers;
mNonAccumCtrl = nonaccumctrl;
mAnimVelocity = 0.0f;
setLooping(loop);
mPlaying = true;
foundanim = true;
}
if(!mNonAccumRoot)
break;
mAnimVelocity = calcAnimVelocity(keys, nonaccumctrl, groupname);
if(mAnimVelocity > 0.0f) break;
} }
if(!foundanim) if(!foundanim)
throw std::runtime_error("Failed to find animation "+groupname); throw std::runtime_error("Failed to find animation "+groupname);
reset(start, stop);
setLooping(loop);
mPlaying = true;
} }
catch(std::exception &e) { catch(std::exception &e) {
std::cerr<< e.what() <<std::endl; std::cerr<< e.what() <<std::endl;

View File

@ -66,8 +66,9 @@ protected:
float mAnimVelocity; float mAnimVelocity;
float mAnimSpeedMult; float mAnimSpeedMult;
static float calcAnimVelocity(NifOgre::NodeTargetValue<Ogre::Real> *nonaccumctrl, static float calcAnimVelocity(const NifOgre::TextKeyMap &keys,
const std::string &groupname, const NifOgre::TextKeyMap *keys); NifOgre::NodeTargetValue<Ogre::Real> *nonaccumctrl,
const std::string &groupname);
/* 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. */
@ -79,9 +80,10 @@ protected:
/* Resets the animation to the time of the specified start marker, without /* Resets the animation to the time of the specified start marker, without
* moving anything, and set the end time to the specified stop marker. If * moving anything, and set the end time to the specified stop marker. If
* the marker is not found, it resets to the beginning or end respectively. * the marker is not found, or if the markers are the same, it returns
* false.
*/ */
void reset(const std::string &start, const std::string &stop=std::string()); bool reset(const NifOgre::TextKeyMap &keys, NifOgre::NodeTargetValue<Ogre::Real> *nonaccumctrl, const std::string &groupname, const std::string &start, const std::string &stop);
void doLoop(); void doLoop();