forked from mirror/openmw-tes3mp
Improve looping behavior
This commit is contained in:
parent
cc70c6263b
commit
bb64efc18e
3 changed files with 45 additions and 40 deletions
|
@ -123,7 +123,7 @@ CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Anim
|
|||
mAnimation->setAccumulation(Ogre::Vector3(0.0f));
|
||||
}
|
||||
if(mAnimation->hasAnimation(mCurrentGroup))
|
||||
mAnimation->play(mCurrentGroup, "stop", "stop", loop);
|
||||
mAnimation->play(mCurrentGroup, "start", "stop", loop);
|
||||
}
|
||||
|
||||
CharacterController::CharacterController(const CharacterController &rhs)
|
||||
|
|
|
@ -293,36 +293,51 @@ Ogre::Vector3 Animation::updatePosition()
|
|||
|
||||
void Animation::reset(const std::string &start, const std::string &stop)
|
||||
{
|
||||
std::string tag = mCurrentGroup+": "+start;
|
||||
mStartKey = mCurrentKeys->begin();
|
||||
|
||||
while(mStartKey != mCurrentKeys->end() && mStartKey->second != start)
|
||||
while(mStartKey != mCurrentKeys->end() && mStartKey->second != tag)
|
||||
mStartKey++;
|
||||
if(mStartKey != mCurrentKeys->end())
|
||||
mCurrentTime = mStartKey->first;
|
||||
else
|
||||
if(mStartKey == mCurrentKeys->end() && tag == "loop start")
|
||||
{
|
||||
tag = mCurrentGroup+": start";
|
||||
mStartKey = mCurrentKeys->begin();
|
||||
mCurrentTime = mStartKey->first;
|
||||
while(mStartKey != mCurrentKeys->end() && mStartKey->second != tag)
|
||||
mStartKey++;
|
||||
}
|
||||
mNextKey = mStartKey;
|
||||
if(mStartKey == mCurrentKeys->end())
|
||||
mStartKey = mCurrentKeys->begin();
|
||||
|
||||
if(stop.length() > 0)
|
||||
{
|
||||
mStopKey = mStartKey;
|
||||
while(mStopKey != mCurrentKeys->end() && mStopKey->second != stop)
|
||||
mStopKey++;
|
||||
if(mStopKey == mCurrentKeys->end())
|
||||
mStopKey--;
|
||||
}
|
||||
tag = mCurrentGroup+": "+stop;
|
||||
mStopKey = mStartKey;
|
||||
while(mStopKey != mCurrentKeys->end() && mStopKey->second != tag)
|
||||
mStopKey++;
|
||||
if(mStopKey == mCurrentKeys->end())
|
||||
mStopKey--;
|
||||
|
||||
mCurrentTime = mStartKey->first;
|
||||
mLoopStartKey = mStartKey;
|
||||
mNextKey = mStartKey;
|
||||
++mNextKey;
|
||||
|
||||
if(mNonAccumCtrl)
|
||||
mLastPosition = mNonAccumCtrl->getTranslation(mCurrentTime) *
|
||||
mAccumulate;
|
||||
mLastPosition = mNonAccumCtrl->getTranslation(mCurrentTime) * mAccumulate;
|
||||
}
|
||||
|
||||
void Animation::doLoop()
|
||||
{
|
||||
mCurrentTime = mLoopStartKey->first;
|
||||
mNextKey = mLoopStartKey;
|
||||
++mNextKey;
|
||||
if(mNonAccumCtrl)
|
||||
mLastPosition = mNonAccumCtrl->getTranslation(mCurrentTime) * mAccumulate;
|
||||
}
|
||||
|
||||
|
||||
bool Animation::handleEvent(float time, const std::string &evt)
|
||||
bool Animation::handleTextKey(const NifOgre::TextKeyMap::const_iterator &key)
|
||||
{
|
||||
float time = key->first;
|
||||
const std::string &evt = key->second;
|
||||
|
||||
if(evt.compare(0, 7, "sound: ") == 0)
|
||||
{
|
||||
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
|
||||
|
@ -347,25 +362,15 @@ bool Animation::handleEvent(float time, const std::string &evt)
|
|||
|
||||
if(evt.compare(off, len, "start") == 0 || evt.compare(off, len, "loop start") == 0)
|
||||
{
|
||||
/* Do nothing */
|
||||
mLoopStartKey = key;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(evt.compare(off, len, "loop stop") == 0)
|
||||
if(evt.compare(off, len, "loop stop") == 0 || evt.compare(off, len, "stop") == 0)
|
||||
{
|
||||
if(mLooping)
|
||||
{
|
||||
reset(mCurrentGroup+": loop start");
|
||||
if(mCurrentTime >= time)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if(evt.compare(off, len, "stop") == 0)
|
||||
{
|
||||
if(mLooping)
|
||||
{
|
||||
reset(mCurrentGroup+": loop start");
|
||||
doLoop();
|
||||
if(mCurrentTime >= time)
|
||||
return false;
|
||||
return true;
|
||||
|
@ -421,7 +426,7 @@ void Animation::play(const std::string &groupname, const std::string &start, con
|
|||
if(!foundanim)
|
||||
throw std::runtime_error("Failed to find animation "+groupname);
|
||||
|
||||
reset(mCurrentGroup+": "+start, mCurrentGroup+": "+stop);
|
||||
reset(start, stop);
|
||||
setLooping(loop);
|
||||
mPlaying = true;
|
||||
}
|
||||
|
@ -446,18 +451,15 @@ Ogre::Vector3 Animation::runAnimation(float timepassed)
|
|||
break;
|
||||
}
|
||||
|
||||
float time = mNextKey->first;
|
||||
const std::string &evt = mNextKey->second;
|
||||
mNextKey++;
|
||||
|
||||
mCurrentTime = time;
|
||||
NifOgre::TextKeyMap::const_iterator key(mNextKey++);
|
||||
mCurrentTime = key->first;
|
||||
if(mNonAccumRoot)
|
||||
movement += updatePosition();
|
||||
|
||||
mPlaying = (mLooping || mStopKey->first > mCurrentTime);
|
||||
timepassed = targetTime - mCurrentTime;
|
||||
|
||||
if(!handleEvent(time, evt))
|
||||
if(!handleTextKey(key))
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ protected:
|
|||
std::vector<Ogre::Controller<Ogre::Real> > *mCurrentControllers;
|
||||
const NifOgre::TextKeyMap *mCurrentKeys;
|
||||
NifOgre::TextKeyMap::const_iterator mStartKey;
|
||||
NifOgre::TextKeyMap::const_iterator mLoopStartKey;
|
||||
NifOgre::TextKeyMap::const_iterator mStopKey;
|
||||
NifOgre::TextKeyMap::const_iterator mNextKey;
|
||||
float mCurrentTime;
|
||||
|
@ -82,7 +83,9 @@ protected:
|
|||
*/
|
||||
void reset(const std::string &start, const std::string &stop=std::string());
|
||||
|
||||
bool handleEvent(float time, const std::string &evt);
|
||||
void doLoop();
|
||||
|
||||
bool handleTextKey(const NifOgre::TextKeyMap::const_iterator &key);
|
||||
|
||||
void addObjectList(Ogre::SceneNode *node, const std::string &model, bool baseonly);
|
||||
static void destroyObjectList(Ogre::SceneManager *sceneMgr, NifOgre::ObjectList &objects);
|
||||
|
|
Loading…
Reference in a new issue