Handle looping in the Animation object

This commit is contained in:
Chris Robinson 2013-01-21 22:51:13 -08:00
parent e956a1cbc0
commit 37fe1bd3f0
5 changed files with 44 additions and 38 deletions

View file

@ -61,8 +61,9 @@ static void getStateInfo(CharacterState state, std::string *group, Ogre::Vector3
throw std::runtime_error("Failed to find character state "+Ogre::StringConverter::toString(state)); throw std::runtime_error("Failed to find character state "+Ogre::StringConverter::toString(state));
} }
CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim, CharacterState state, bool loop) CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim, CharacterState state, bool loop)
: mPtr(ptr), mAnimation(anim), mDirection(Ogre::Vector3::ZERO), mState(state), mSkipAnim(false), mLoop(loop) : mPtr(ptr), mAnimation(anim), mDirection(Ogre::Vector3::ZERO), mState(state), mSkipAnim(false)
{ {
if(!mAnimation) if(!mAnimation)
return; return;
@ -73,13 +74,13 @@ CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Anim
getStateInfo(mState, &mCurrentGroup, &accum); getStateInfo(mState, &mCurrentGroup, &accum);
mAnimation->setAccumulation(accum); mAnimation->setAccumulation(accum);
if(mAnimation->hasAnimation(mCurrentGroup)) if(mAnimation->hasAnimation(mCurrentGroup))
mAnimation->play(mCurrentGroup, "stop"); mAnimation->play(mCurrentGroup, "stop", loop);
} }
CharacterController::CharacterController(const CharacterController &rhs) CharacterController::CharacterController(const CharacterController &rhs)
: mPtr(rhs.mPtr), mAnimation(rhs.mAnimation), mAnimQueue(rhs.mAnimQueue) : mPtr(rhs.mPtr), mAnimation(rhs.mAnimation), mAnimQueue(rhs.mAnimQueue)
, mCurrentGroup(rhs.mCurrentGroup), mDirection(rhs.mDirection) , mCurrentGroup(rhs.mCurrentGroup), mDirection(rhs.mDirection)
, mState(rhs.mState), mSkipAnim(rhs.mSkipAnim), mLoop(rhs.mLoop) , mState(rhs.mState), mSkipAnim(rhs.mSkipAnim)
{ {
if(!mAnimation) if(!mAnimation)
return; return;
@ -103,32 +104,12 @@ void CharacterController::markerEvent(float time, const std::string &evt)
return; return;
} }
if(evt == "loop stop")
{
if(mAnimQueue.size() == 0)
{
if(time > 0.0f && mLoop)
mAnimation->play(mCurrentGroup, "loop start");
}
else if(mAnimQueue.size() >= 2 && mAnimQueue[0] == mAnimQueue[1])
{
mAnimQueue.pop_front();
mAnimation->play(mCurrentGroup, "loop start");
}
return;
}
if(evt == "stop") if(evt == "stop")
{ {
if(mAnimQueue.size() == 0) if(mAnimQueue.size() >= 2 && mAnimQueue[0] == mAnimQueue[1])
{
if(time > 0.0f && mLoop)
mAnimation->play(mCurrentGroup, "loop start");
}
else if(mAnimQueue.size() >= 2 && mAnimQueue[0] == mAnimQueue[1])
{ {
mAnimQueue.pop_front(); mAnimQueue.pop_front();
mAnimation->play(mCurrentGroup, "loop start"); mAnimation->play(mCurrentGroup, "loop start", false);
} }
else if(mAnimQueue.size() > 0) else if(mAnimQueue.size() > 0)
{ {
@ -136,7 +117,7 @@ void CharacterController::markerEvent(float time, const std::string &evt)
if(mAnimQueue.size() > 0) if(mAnimQueue.size() > 0)
{ {
mCurrentGroup = mAnimQueue.front(); mCurrentGroup = mAnimQueue.front();
mAnimation->play(mCurrentGroup, "start"); mAnimation->play(mCurrentGroup, "start", false);
} }
} }
return; return;
@ -185,9 +166,8 @@ void CharacterController::playGroup(const std::string &groupname, int mode, int
mAnimQueue.push_back(groupname); mAnimQueue.push_back(groupname);
mCurrentGroup = groupname; mCurrentGroup = groupname;
mState = CharState_Idle; mState = CharState_Idle;
mLoop = false;
mAnimation->setAccumulation(Ogre::Vector3::ZERO); mAnimation->setAccumulation(Ogre::Vector3::ZERO);
mAnimation->play(mCurrentGroup, ((mode==2) ? "loop start" : "start")); mAnimation->play(mCurrentGroup, ((mode==2) ? "loop start" : "start"), false);
} }
else if(mode == 0) else if(mode == 0)
{ {
@ -208,11 +188,7 @@ void CharacterController::setState(CharacterState state, bool loop)
{ {
if(mState == state) if(mState == state)
return; return;
else
{
mState = state; mState = state;
mLoop = loop;
}
if(!mAnimation) if(!mAnimation)
return; return;
@ -225,7 +201,7 @@ void CharacterController::setState(CharacterState state, bool loop)
{ {
mCurrentGroup = anim; mCurrentGroup = anim;
mAnimation->setAccumulation(accum); mAnimation->setAccumulation(accum);
mAnimation->play(mCurrentGroup, "start"); mAnimation->play(mCurrentGroup, "start", loop);
} }
} }

View file

@ -37,7 +37,6 @@ class CharacterController
std::string mCurrentGroup; std::string mCurrentGroup;
CharacterState mState; CharacterState mState;
bool mSkipAnim; bool mSkipAnim;
bool mLoop;
protected: protected:
/* Called by the animation whenever a new text key is reached. */ /* Called by the animation whenever a new text key is reached. */

View file

@ -26,6 +26,7 @@ Animation::Animation(const MWWorld::Ptr &ptr)
, mLastPosition(0.0f) , mLastPosition(0.0f)
, mCurrentKeys(NULL) , mCurrentKeys(NULL)
, mAnimState(NULL) , mAnimState(NULL)
, mLooping(false)
, mAnimSpeedMult(1.0f) , mAnimSpeedMult(1.0f)
{ {
} }
@ -173,7 +174,7 @@ float Animation::findStart(const std::string &groupname, const std::string &star
} }
void Animation::play(const std::string &groupname, const std::string &start) void Animation::play(const std::string &groupname, const std::string &start, bool loop)
{ {
try { try {
if(mAnimState) if(mAnimState)
@ -181,6 +182,7 @@ void Animation::play(const std::string &groupname, const std::string &start)
mAnimState = mEntityList.mSkelBase->getAnimationState(groupname); mAnimState = mEntityList.mSkelBase->getAnimationState(groupname);
mAnimState->setEnabled(true); mAnimState->setEnabled(true);
mCurrentKeys = &mTextKeys[groupname]; mCurrentKeys = &mTextKeys[groupname];
mLooping = loop;
resetPosition(findStart(groupname, start)); resetPosition(findStart(groupname, start));
} }
@ -209,6 +211,33 @@ Ogre::Vector3 Animation::runAnimation(float timepassed)
movement += updatePosition(time); movement += updatePosition(time);
timepassed = targetTime - time; timepassed = targetTime - time;
if(evt == "start" || evt == "loop start")
{
/* Do nothing */
continue;
}
if(evt == "loop stop")
{
if(mLooping)
{
resetPosition(findStart(mAnimState->getAnimationName(), "loop start"));
if(mAnimState->getTimePosition() >= time)
break;
}
continue;
}
if(evt == "stop")
{
if(mLooping)
{
resetPosition(findStart(mAnimState->getAnimationName(), "loop start"));
if(mAnimState->getTimePosition() >= time)
break;
}
else if(mController)
mController->markerEvent(time, evt);
continue;
}
if(mController) if(mController)
mController->markerEvent(time, evt); mController->markerEvent(time, evt);
} }

View file

@ -31,6 +31,8 @@ protected:
NifOgre::TextKeyMap *mCurrentKeys; NifOgre::TextKeyMap *mCurrentKeys;
NifOgre::TextKeyMap::const_iterator mNextKey; NifOgre::TextKeyMap::const_iterator mNextKey;
Ogre::AnimationState *mAnimState; Ogre::AnimationState *mAnimState;
bool mLooping;
float mAnimSpeedMult; float mAnimSpeedMult;
/* Updates the animation to the specified time, and returns the movement /* Updates the animation to the specified time, and returns the movement
@ -59,7 +61,7 @@ public:
void setSpeedMult(float speedmult) void setSpeedMult(float speedmult)
{ mAnimSpeedMult = speedmult; } { mAnimSpeedMult = speedmult; }
void play(const std::string &groupname, const std::string &start); void play(const std::string &groupname, const std::string &start, bool loop);
virtual Ogre::Vector3 runAnimation(float timepassed); virtual Ogre::Vector3 runAnimation(float timepassed);
}; };

View file

@ -144,7 +144,7 @@ namespace MWRender
{ {
mSelectionBuffer = new OEngine::Render::SelectionBuffer(mCamera, 512, 1024, RV_PlayerPreview); mSelectionBuffer = new OEngine::Render::SelectionBuffer(mCamera, 512, 1024, RV_PlayerPreview);
mAnimation->play("inventoryhandtohand", "start"); mAnimation->play("inventoryhandtohand", "start", false);
} }
// -------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------