Use the NodeTargetValue for the NonAccum root

actorid
Chris Robinson 12 years ago
parent adc6a948c7
commit cc70c6263b

@ -41,12 +41,12 @@ Animation::Animation(const MWWorld::Ptr &ptr)
, mNonAccumRoot(NULL)
, mAccumulate(0.0f)
, mLastPosition(0.0f)
, mCurrentAnim(NULL)
, mCurrentControllers(NULL)
, mCurrentKeys(NULL)
, mCurrentTime(0.0f)
, mPlaying(false)
, mLooping(false)
, mNonAccumCtrl(NULL)
, mAnimVelocity(0.0f)
, mAnimSpeedMult(1.0f)
{
@ -209,48 +209,31 @@ void Animation::updatePtr(const MWWorld::Ptr &ptr)
}
float Animation::calcAnimVelocity(Ogre::Animation *anim, const std::string &bonename, const std::string &groupname, const NifOgre::TextKeyMap *keys)
float Animation::calcAnimVelocity(NifOgre::NodeTargetValue<Ogre::Real> *nonaccumctrl, const std::string &groupname, const NifOgre::TextKeyMap *keys)
{
const Ogre::NodeAnimationTrack *track = 0;
Ogre::Animation::NodeTrackIterator trackiter = anim->getNodeTrackIterator();
while(!track && trackiter.hasMoreElements())
{
const Ogre::NodeAnimationTrack *cur = trackiter.getNext();
if(cur->getAssociatedNode()->getName() == bonename)
track = cur;
}
if(track && track->getNumKeyFrames() > 1)
const std::string loopstart = groupname+": loop start";
const std::string loopstop = groupname+": loop stop";
float loopstarttime = 0.0f;
float loopstoptime = std::numeric_limits<float>::max();
NifOgre::TextKeyMap::const_iterator keyiter = keys->begin();
while(keyiter != keys->end())
{
const std::string loopstart = groupname+": loop start";
const std::string loopstop = groupname+": loop stop";
float loopstarttime = 0.0f;
float loopstoptime = anim->getLength();
NifOgre::TextKeyMap::const_iterator keyiter = keys->begin();
while(keyiter != keys->end())
if(keyiter->second == loopstart)
loopstarttime = keyiter->first;
else if(keyiter->second == loopstop)
{
if(keyiter->second == loopstart)
loopstarttime = keyiter->first;
else if(keyiter->second == loopstop)
{
loopstoptime = keyiter->first;
break;
}
keyiter++;
loopstoptime = keyiter->first;
break;
}
keyiter++;
}
if(loopstoptime > loopstarttime)
{
Ogre::TransformKeyFrame startkf(0, loopstarttime);
Ogre::TransformKeyFrame endkf(0, loopstoptime);
track->getInterpolatedKeyFrame(anim->_getTimeIndex(loopstarttime), &startkf);
track->getInterpolatedKeyFrame(anim->_getTimeIndex(loopstoptime), &endkf);
if(loopstoptime > loopstarttime)
{
Ogre::Vector3 startpos = nonaccumctrl->getTranslation(loopstarttime);
Ogre::Vector3 endpos = nonaccumctrl->getTranslation(loopstarttime);
return startkf.getTranslate().distance(endkf.getTranslate()) /
(loopstoptime-loopstarttime);
}
return startpos.distance(endpos) / (loopstoptime-loopstarttime);
}
return 0.0f;
@ -298,20 +281,8 @@ Ogre::Vector3 Animation::updatePosition()
{
Ogre::Vector3 posdiff;
Ogre::TransformKeyFrame kf(0, mCurrentTime);
Ogre::Animation::NodeTrackIterator trackiter = mCurrentAnim->getNodeTrackIterator();
while(trackiter.hasMoreElements())
{
const Ogre::NodeAnimationTrack *track = trackiter.getNext();
if(track->getAssociatedNode()->getName() == mNonAccumRoot->getName())
{
track->getInterpolatedKeyFrame(mCurrentAnim->_getTimeIndex(mCurrentTime), &kf);
break;
}
}
/* Get the non-accumulation root's difference from the last update. */
posdiff = (kf.getTranslate() - mLastPosition) * mAccumulate;
posdiff = (mNonAccumCtrl->getTranslation(mCurrentTime) - mLastPosition) * mAccumulate;
/* Translate the accumulation root back to compensate for the move. */
mLastPosition += posdiff;
@ -344,24 +315,9 @@ void Animation::reset(const std::string &start, const std::string &stop)
mStopKey--;
}
if(mNonAccumRoot)
{
const Ogre::NodeAnimationTrack *track = 0;
Ogre::Animation::NodeTrackIterator trackiter = mCurrentAnim->getNodeTrackIterator();
while(!track && trackiter.hasMoreElements())
{
const Ogre::NodeAnimationTrack *cur = trackiter.getNext();
if(cur->getAssociatedNode()->getName() == mNonAccumRoot->getName())
track = cur;
}
if(track)
{
Ogre::TransformKeyFrame kf(0, mCurrentTime);
track->getInterpolatedKeyFrame(mCurrentAnim->_getTimeIndex(mCurrentTime), &kf);
mLastPosition = kf.getTranslate() * mAccumulate;
}
}
if(mNonAccumCtrl)
mLastPosition = mNonAccumCtrl->getTranslation(mCurrentTime) *
mAccumulate;
}
@ -431,24 +387,34 @@ void Animation::play(const std::string &groupname, const std::string &start, con
{
if(iter->mSkelBase && iter->mSkelBase->hasAnimationState(groupname))
{
Ogre::SkeletonInstance *skel = iter->mSkelBase->getSkeleton();
Ogre::Animation *anim = skel->getAnimation(groupname);
const NifOgre::TextKeyMap *keys = &iter->mTextKeys.begin()->second;
NifOgre::NodeTargetValue<Ogre::Real> *nonaccumctrl = NULL;
for(size_t i = 0;i < iter->mControllers.size();i++)
{
NifOgre::NodeTargetValue<Ogre::Real> *dstval;
dstval = dynamic_cast<NifOgre::NodeTargetValue<Ogre::Real>*>(iter->mControllers[i].getDestination().getPointer());
if(dstval && dstval->getNode() == mNonAccumRoot)
{
nonaccumctrl = dstval;
break;
}
}
if(!foundanim)
{
mCurrentAnim = anim;
mCurrentKeys = keys;
mCurrentGroup = groupname;
mCurrentControllers = &iter->mControllers;
mNonAccumCtrl = nonaccumctrl;
mAnimVelocity = 0.0f;
foundanim = true;
}
if(!mNonAccumRoot)
break;
mAnimVelocity = calcAnimVelocity(anim, mNonAccumRoot->getName(), groupname, keys);
mAnimVelocity = calcAnimVelocity(nonaccumctrl, groupname, keys);
if(mAnimVelocity > 0.0f) break;
}
}
@ -469,7 +435,7 @@ Ogre::Vector3 Animation::runAnimation(float timepassed)
Ogre::Vector3 movement(0.0f);
timepassed *= mAnimSpeedMult;
while(mCurrentAnim && mPlaying)
while(!mCurrentGroup.empty() && mPlaying)
{
float targetTime = mCurrentTime + timepassed;
if(mNextKey->first > targetTime)

@ -50,7 +50,6 @@ protected:
Ogre::Bone *mNonAccumRoot;
Ogre::Vector3 mAccumulate;
Ogre::Vector3 mLastPosition;
Ogre::Animation *mCurrentAnim;
std::string mCurrentGroup;
std::vector<Ogre::Controller<Ogre::Real> > *mCurrentControllers;
@ -62,10 +61,11 @@ protected:
bool mPlaying;
bool mLooping;
NifOgre::NodeTargetValue<Ogre::Real> *mNonAccumCtrl;
float mAnimVelocity;
float mAnimSpeedMult;
static float calcAnimVelocity(Ogre::Animation *anim, const std::string &bonename,
static float calcAnimVelocity(NifOgre::NodeTargetValue<Ogre::Real> *nonaccumctrl,
const std::string &groupname, const NifOgre::TextKeyMap *keys);
/* Updates a skeleton instance so that all bones matching the source skeleton (based on

Loading…
Cancel
Save