Use shared pointers to store animation sources

This ensures references to the sources stay valid as long it the object
is, rather than becoming invalidated whenever one is added or removed.
actorid
Chris Robinson 12 years ago
parent 6b8a687a79
commit 4ea347ac52

@ -189,19 +189,17 @@ void Animation::addAnimSource(const std::string &model)
return; return;
std::vector<Ogre::Controller<Ogre::Real> > ctrls; std::vector<Ogre::Controller<Ogre::Real> > ctrls;
mAnimSources.push_back(AnimSource()); Ogre::SharedPtr<AnimSource> animsrc(OGRE_NEW AnimSource);
NifOgre::Loader::createKfControllers(mSkelBase, kfname, mAnimSources.back().mTextKeys, ctrls); NifOgre::Loader::createKfControllers(mSkelBase, kfname, animsrc->mTextKeys, ctrls);
if(mAnimSources.back().mTextKeys.size() == 0 || ctrls.size() == 0) if(animsrc->mTextKeys.size() == 0 || ctrls.size() == 0)
{
mAnimSources.pop_back();
return; return;
}
std::vector<Ogre::Controller<Ogre::Real> > *grpctrls = mAnimSources.back().mControllers; mAnimSources.push_back(animsrc);
NifOgre::NodeTargetValue<Ogre::Real> *dstval;
std::vector<Ogre::Controller<Ogre::Real> > *grpctrls = animsrc->mControllers;
for(size_t i = 0;i < ctrls.size();i++) for(size_t i = 0;i < ctrls.size();i++)
{ {
NifOgre::NodeTargetValue<Ogre::Real> *dstval;
dstval = static_cast<NifOgre::NodeTargetValue<Ogre::Real>*>(ctrls[i].getDestination().getPointer()); dstval = static_cast<NifOgre::NodeTargetValue<Ogre::Real>*>(ctrls[i].getDestination().getPointer());
size_t grp = detectAnimGroup(dstval->getNode()); size_t grp = detectAnimGroup(dstval->getNode());
@ -264,7 +262,7 @@ bool Animation::hasAnimation(const std::string &anim)
AnimSourceList::const_iterator iter(mAnimSources.begin()); AnimSourceList::const_iterator iter(mAnimSources.begin());
for(;iter != mAnimSources.end();iter++) for(;iter != mAnimSources.end();iter++)
{ {
const NifOgre::TextKeyMap &keys = iter->mTextKeys; const NifOgre::TextKeyMap &keys = (*iter)->mTextKeys;
if(findGroupStart(keys, anim) != keys.end()) if(findGroupStart(keys, anim) != keys.end())
return true; return true;
} }
@ -510,9 +508,9 @@ bool Animation::play(const std::string &groupname, Priority priority, int groups
for(;iter != mAnimSources.rend();iter++) for(;iter != mAnimSources.rend();iter++)
{ {
AnimState state; AnimState state;
if(reset(state, iter->mTextKeys, groupname, start, stop, startpoint)) if(reset(state, (*iter)->mTextKeys, groupname, start, stop, startpoint))
{ {
state.mSource = &*iter; state.mSource = *iter;
state.mLoopCount = loops; state.mLoopCount = loops;
state.mPlaying = true; state.mPlaying = true;
state.mPriority = priority; state.mPriority = priority;
@ -561,7 +559,7 @@ bool Animation::resetActiveGroups()
bool ismoving = false; bool ismoving = false;
const AnimSource *animsrc = state->second.mSource; const Ogre::SharedPtr<AnimSource> &animsrc = state->second.mSource;
const NifOgre::TextKeyMap &keys = animsrc->mTextKeys; const NifOgre::TextKeyMap &keys = animsrc->mTextKeys;
const std::vector<Ogre::Controller<Ogre::Real> >&ctrls = animsrc->mControllers[0]; const std::vector<Ogre::Controller<Ogre::Real> >&ctrls = animsrc->mControllers[0];
for(size_t i = 0;i < ctrls.size();i++) for(size_t i = 0;i < ctrls.size();i++)
@ -579,18 +577,25 @@ bool Animation::resetActiveGroups()
} }
// If there's no velocity, keep looking // If there's no velocity, keep looking
while(!(mAnimVelocity > 1.0f) && animsrc-- != &mAnimSources[0]) if(!(mAnimVelocity > 1.0f))
{ {
const NifOgre::TextKeyMap &keys = animsrc->mTextKeys; AnimSourceList::const_reverse_iterator animiter = mAnimSources.rbegin();
const std::vector<Ogre::Controller<Ogre::Real> >&ctrls = animsrc->mControllers[0]; while(*animiter != animsrc)
for(size_t i = 0;i < ctrls.size();i++) ++animiter;
while(!(mAnimVelocity > 1.0f) && ++animiter != mAnimSources.rend())
{ {
NifOgre::NodeTargetValue<Ogre::Real> *dstval; const NifOgre::TextKeyMap &keys = (*animiter)->mTextKeys;
dstval = static_cast<NifOgre::NodeTargetValue<Ogre::Real>*>(ctrls[i].getDestination().getPointer()); const std::vector<Ogre::Controller<Ogre::Real> >&ctrls = (*animiter)->mControllers[0];
if(dstval->getNode() == mNonAccumRoot) for(size_t i = 0;i < ctrls.size();i++)
{ {
mAnimVelocity = calcAnimVelocity(keys, dstval, mAccumulate, state->first); NifOgre::NodeTargetValue<Ogre::Real> *dstval;
break; dstval = static_cast<NifOgre::NodeTargetValue<Ogre::Real>*>(ctrls[i].getDestination().getPointer());
if(dstval->getNode() == mNonAccumRoot)
{
mAnimVelocity = calcAnimVelocity(keys, dstval, mAccumulate, state->first);
break;
}
} }
} }
} }
@ -675,7 +680,7 @@ Ogre::Vector3 Animation::runAnimation(float duration)
const std::string &name = mAnimationValuePtr[grp]->getAnimName(); const std::string &name = mAnimationValuePtr[grp]->getAnimName();
if(!name.empty() && (stateiter=mStates.find(name)) != mStates.end()) if(!name.empty() && (stateiter=mStates.find(name)) != mStates.end())
{ {
AnimSource *src = stateiter->second.mSource; const Ogre::SharedPtr<AnimSource> &src = stateiter->second.mSource;
for(size_t i = 0;i < src->mControllers[grp].size();i++) for(size_t i = 0;i < src->mControllers[grp].size();i++)
src->mControllers[grp][i].update(); src->mControllers[grp][i].update();
} }

@ -57,10 +57,10 @@ protected:
NifOgre::TextKeyMap mTextKeys; NifOgre::TextKeyMap mTextKeys;
std::vector<Ogre::Controller<Ogre::Real> > mControllers[sNumGroups]; std::vector<Ogre::Controller<Ogre::Real> > mControllers[sNumGroups];
}; };
typedef std::vector<AnimSource> AnimSourceList; typedef std::vector< Ogre::SharedPtr<AnimSource> > AnimSourceList;
struct AnimState { struct AnimState {
AnimSource *mSource; Ogre::SharedPtr<AnimSource> mSource;
NifOgre::TextKeyMap::const_iterator mStartKey; NifOgre::TextKeyMap::const_iterator mStartKey;
NifOgre::TextKeyMap::const_iterator mLoopStartKey; NifOgre::TextKeyMap::const_iterator mLoopStartKey;
NifOgre::TextKeyMap::const_iterator mStopKey; NifOgre::TextKeyMap::const_iterator mStopKey;
@ -75,7 +75,8 @@ protected:
int mGroups; int mGroups;
bool mAutoDisable; bool mAutoDisable;
AnimState() : mSource(NULL), mTime(0.0f), mPlaying(false), mLoopCount(0) AnimState() : mTime(0.0f), mPlaying(false), mLoopCount(0),
mPriority(0), mGroups(0), mAutoDisable(true)
{ } { }
}; };
typedef std::map<std::string,AnimState> AnimStateMap; typedef std::map<std::string,AnimState> AnimStateMap;

Loading…
Cancel
Save