1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-22 10:53:54 +00:00

Properly check if an animation exists before playing it

This commit is contained in:
Chris Robinson 2013-01-19 21:55:04 -08:00
parent 68779375b2
commit 85ca1e993f
4 changed files with 22 additions and 35 deletions

View file

@ -65,29 +65,24 @@ static void getStateInfo(CharacterState state, std::string *group, Ogre::Vector3
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), mLoop(loop)
{ {
if(mAnimation) if(!mAnimation)
mAnimNames = mAnimation->getAnimationNames();
if(mAnimNames.size() == 0)
{
mAnimation = NULL;
return; return;
}
mAnimation->setController(this); mAnimation->setController(this);
Ogre::Vector3 accum; Ogre::Vector3 accum;
getStateInfo(mState, &mCurrentGroup, &accum); getStateInfo(mState, &mCurrentGroup, &accum);
mAnimation->setAccumulation(accum); mAnimation->setAccumulation(accum);
mAnimation->play(mCurrentGroup, "stop"); if(mAnimation->hasAnimation(mCurrentGroup))
mAnimation->play(mCurrentGroup, "stop");
} }
CharacterController::CharacterController(const CharacterController &rhs) CharacterController::CharacterController(const CharacterController &rhs)
: mPtr(rhs.mPtr), mAnimation(rhs.mAnimation), mAnimNames(rhs.mAnimNames) : mPtr(rhs.mPtr), mAnimation(rhs.mAnimation), mAnimQueue(rhs.mAnimQueue)
, mAnimQueue(rhs.mAnimQueue), mCurrentGroup(rhs.mCurrentGroup) , mCurrentGroup(rhs.mCurrentGroup), mDirection(rhs.mDirection)
, mDirection(rhs.mDirection), mState(rhs.mState), mSkipAnim(rhs.mSkipAnim) , mState(rhs.mState), mSkipAnim(rhs.mSkipAnim), mLoop(rhs.mLoop)
, mLoop(rhs.mLoop)
{ {
if(mAnimNames.size() == 0) if(!mAnimation)
return; return;
/* We've been copied. Update the animation with the new controller. */ /* We've been copied. Update the animation with the new controller. */
mAnimation->setController(this); mAnimation->setController(this);
@ -186,7 +181,7 @@ Ogre::Vector3 CharacterController::update(float duration)
void CharacterController::playGroup(const std::string &groupname, int mode, int count) void CharacterController::playGroup(const std::string &groupname, int mode, int count)
{ {
if(std::find(mAnimNames.begin(), mAnimNames.end(), groupname) != mAnimNames.end()) if(mAnimation && mAnimation->hasAnimation(groupname))
{ {
count = std::max(count, 1); count = std::max(count, 1);
if(mode != 0 || mAnimQueue.size() == 0) if(mode != 0 || mAnimQueue.size() == 0)
@ -230,14 +225,19 @@ void CharacterController::setState(CharacterState state, bool loop)
mLoop = loop; mLoop = loop;
} }
if(mAnimNames.size() == 0) if(!mAnimation)
return; return;
mAnimQueue.clear(); mAnimQueue.clear();
std::string anim;
Ogre::Vector3 accum; Ogre::Vector3 accum;
getStateInfo(mState, &mCurrentGroup, &accum); getStateInfo(mState, &anim, &accum);
mAnimation->setAccumulation(accum); if(mAnimation->hasAnimation(anim))
mAnimation->play(mCurrentGroup, "start"); {
mCurrentGroup = anim;
mAnimation->setAccumulation(accum);
mAnimation->play(mCurrentGroup, "start");
}
} }
} }

View file

@ -30,8 +30,6 @@ class CharacterController
MWWorld::Ptr mPtr; MWWorld::Ptr mPtr;
MWRender::Animation *mAnimation; MWRender::Animation *mAnimation;
std::vector<std::string> mAnimNames;
typedef std::deque<std::string> AnimationQueue; typedef std::deque<std::string> AnimationQueue;
AnimationQueue mAnimQueue; AnimationQueue mAnimQueue;

View file

@ -100,17 +100,9 @@ void Animation::createEntityList(Ogre::SceneNode *node, const std::string &model
} }
std::vector<std::string> Animation::getAnimationNames() bool Animation::hasAnimation(const std::string &anim)
{ {
std::vector<std::string> anims; return mEntityList.mSkelBase && mEntityList.mSkelBase->hasAnimationState(anim);
if(mEntityList.mSkelBase)
{
Ogre::AnimationStateSet *as = mEntityList.mSkelBase->getAllAnimationStates();
Ogre::AnimationStateIterator ai = as->getAnimationStateIterator();
while(ai.hasMoreElements())
anims.push_back(ai.getNext()->getAnimationName());
}
return anims;
} }
@ -188,13 +180,9 @@ 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)
{ {
try { try {
if(!mEntityList.mSkelBase)
throw std::runtime_error("Attempting to animate an inanimate object");
Ogre::AnimationState *newstate = mEntityList.mSkelBase->getAnimationState(groupname);
if(mAnimState) if(mAnimState)
mAnimState->setEnabled(false); mAnimState->setEnabled(false);
mAnimState = newstate; mAnimState = mEntityList.mSkelBase->getAnimationState(groupname);
mAnimState->setEnabled(true); mAnimState->setEnabled(true);
mCurrentKeys = &mTextKeys[groupname]; mCurrentKeys = &mTextKeys[groupname];

View file

@ -48,7 +48,8 @@ public:
virtual ~Animation(); virtual ~Animation();
void setController(MWMechanics::CharacterController *controller); void setController(MWMechanics::CharacterController *controller);
std::vector<std::string> getAnimationNames();
bool hasAnimation(const std::string &anim);
// Specifies the axis' to accumulate on. Non-accumulated axis will just // Specifies the axis' to accumulate on. Non-accumulated axis will just
// move visually, but not affect the actual movement. Each x/y/z value // move visually, but not affect the actual movement. Each x/y/z value