mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-03-28 20:06:41 +00:00
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));
|
mAnimation->setAccumulation(Ogre::Vector3(0.0f));
|
||||||
}
|
}
|
||||||
if(mAnimation->hasAnimation(mCurrentGroup))
|
if(mAnimation->hasAnimation(mCurrentGroup))
|
||||||
mAnimation->play(mCurrentGroup, "stop", "stop", loop);
|
mAnimation->play(mCurrentGroup, "start", "stop", loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
CharacterController::CharacterController(const CharacterController &rhs)
|
CharacterController::CharacterController(const CharacterController &rhs)
|
||||||
|
|
|
@ -293,36 +293,51 @@ Ogre::Vector3 Animation::updatePosition()
|
||||||
|
|
||||||
void Animation::reset(const std::string &start, const std::string &stop)
|
void Animation::reset(const std::string &start, const std::string &stop)
|
||||||
{
|
{
|
||||||
|
std::string tag = mCurrentGroup+": "+start;
|
||||||
mStartKey = mCurrentKeys->begin();
|
mStartKey = mCurrentKeys->begin();
|
||||||
|
while(mStartKey != mCurrentKeys->end() && mStartKey->second != tag)
|
||||||
while(mStartKey != mCurrentKeys->end() && mStartKey->second != start)
|
|
||||||
mStartKey++;
|
mStartKey++;
|
||||||
if(mStartKey != mCurrentKeys->end())
|
if(mStartKey == mCurrentKeys->end() && tag == "loop start")
|
||||||
mCurrentTime = mStartKey->first;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
tag = mCurrentGroup+": start";
|
||||||
mStartKey = mCurrentKeys->begin();
|
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)
|
tag = mCurrentGroup+": "+stop;
|
||||||
{
|
mStopKey = mStartKey;
|
||||||
mStopKey = mStartKey;
|
while(mStopKey != mCurrentKeys->end() && mStopKey->second != tag)
|
||||||
while(mStopKey != mCurrentKeys->end() && mStopKey->second != stop)
|
mStopKey++;
|
||||||
mStopKey++;
|
if(mStopKey == mCurrentKeys->end())
|
||||||
if(mStopKey == mCurrentKeys->end())
|
mStopKey--;
|
||||||
mStopKey--;
|
|
||||||
}
|
mCurrentTime = mStartKey->first;
|
||||||
|
mLoopStartKey = mStartKey;
|
||||||
|
mNextKey = mStartKey;
|
||||||
|
++mNextKey;
|
||||||
|
|
||||||
if(mNonAccumCtrl)
|
if(mNonAccumCtrl)
|
||||||
mLastPosition = mNonAccumCtrl->getTranslation(mCurrentTime) *
|
mLastPosition = mNonAccumCtrl->getTranslation(mCurrentTime) * mAccumulate;
|
||||||
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)
|
if(evt.compare(0, 7, "sound: ") == 0)
|
||||||
{
|
{
|
||||||
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
|
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)
|
if(evt.compare(off, len, "start") == 0 || evt.compare(off, len, "loop start") == 0)
|
||||||
{
|
{
|
||||||
/* Do nothing */
|
mLoopStartKey = key;
|
||||||
return true;
|
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)
|
if(mLooping)
|
||||||
{
|
{
|
||||||
reset(mCurrentGroup+": loop start");
|
doLoop();
|
||||||
if(mCurrentTime >= time)
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(evt.compare(off, len, "stop") == 0)
|
|
||||||
{
|
|
||||||
if(mLooping)
|
|
||||||
{
|
|
||||||
reset(mCurrentGroup+": loop start");
|
|
||||||
if(mCurrentTime >= time)
|
if(mCurrentTime >= time)
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
|
@ -421,7 +426,7 @@ void Animation::play(const std::string &groupname, const std::string &start, con
|
||||||
if(!foundanim)
|
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(start, stop);
|
||||||
setLooping(loop);
|
setLooping(loop);
|
||||||
mPlaying = true;
|
mPlaying = true;
|
||||||
}
|
}
|
||||||
|
@ -446,18 +451,15 @@ Ogre::Vector3 Animation::runAnimation(float timepassed)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
float time = mNextKey->first;
|
NifOgre::TextKeyMap::const_iterator key(mNextKey++);
|
||||||
const std::string &evt = mNextKey->second;
|
mCurrentTime = key->first;
|
||||||
mNextKey++;
|
|
||||||
|
|
||||||
mCurrentTime = time;
|
|
||||||
if(mNonAccumRoot)
|
if(mNonAccumRoot)
|
||||||
movement += updatePosition();
|
movement += updatePosition();
|
||||||
|
|
||||||
mPlaying = (mLooping || mStopKey->first > mCurrentTime);
|
mPlaying = (mLooping || mStopKey->first > mCurrentTime);
|
||||||
timepassed = targetTime - mCurrentTime;
|
timepassed = targetTime - mCurrentTime;
|
||||||
|
|
||||||
if(!handleEvent(time, evt))
|
if(!handleTextKey(key))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,7 @@ protected:
|
||||||
std::vector<Ogre::Controller<Ogre::Real> > *mCurrentControllers;
|
std::vector<Ogre::Controller<Ogre::Real> > *mCurrentControllers;
|
||||||
const NifOgre::TextKeyMap *mCurrentKeys;
|
const NifOgre::TextKeyMap *mCurrentKeys;
|
||||||
NifOgre::TextKeyMap::const_iterator mStartKey;
|
NifOgre::TextKeyMap::const_iterator mStartKey;
|
||||||
|
NifOgre::TextKeyMap::const_iterator mLoopStartKey;
|
||||||
NifOgre::TextKeyMap::const_iterator mStopKey;
|
NifOgre::TextKeyMap::const_iterator mStopKey;
|
||||||
NifOgre::TextKeyMap::const_iterator mNextKey;
|
NifOgre::TextKeyMap::const_iterator mNextKey;
|
||||||
float mCurrentTime;
|
float mCurrentTime;
|
||||||
|
@ -82,7 +83,9 @@ protected:
|
||||||
*/
|
*/
|
||||||
void reset(const std::string &start, const std::string &stop=std::string());
|
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);
|
void addObjectList(Ogre::SceneNode *node, const std::string &model, bool baseonly);
|
||||||
static void destroyObjectList(Ogre::SceneManager *sceneMgr, NifOgre::ObjectList &objects);
|
static void destroyObjectList(Ogre::SceneManager *sceneMgr, NifOgre::ObjectList &objects);
|
||||||
|
|
Loading…
Reference in a new issue