forked from mirror/openmw-tes3mp
Handle looping in the Animation object
This commit is contained in:
parent
e956a1cbc0
commit
37fe1bd3f0
5 changed files with 44 additions and 38 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in a new issue