1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-03-28 20:06:41 +00:00

Use the NodeTargetValue for the NonAccum root

This commit is contained in:
Chris Robinson 2013-04-22 04:10:46 -07:00
parent adc6a948c7
commit cc70c6263b
2 changed files with 42 additions and 76 deletions

View file

@ -41,12 +41,12 @@ Animation::Animation(const MWWorld::Ptr &ptr)
, mNonAccumRoot(NULL) , mNonAccumRoot(NULL)
, mAccumulate(0.0f) , mAccumulate(0.0f)
, mLastPosition(0.0f) , mLastPosition(0.0f)
, mCurrentAnim(NULL)
, mCurrentControllers(NULL) , mCurrentControllers(NULL)
, mCurrentKeys(NULL) , mCurrentKeys(NULL)
, mCurrentTime(0.0f) , mCurrentTime(0.0f)
, mPlaying(false) , mPlaying(false)
, mLooping(false) , mLooping(false)
, mNonAccumCtrl(NULL)
, mAnimVelocity(0.0f) , mAnimVelocity(0.0f)
, mAnimSpeedMult(1.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; const std::string loopstart = groupname+": loop start";
const std::string loopstop = groupname+": loop stop";
Ogre::Animation::NodeTrackIterator trackiter = anim->getNodeTrackIterator(); float loopstarttime = 0.0f;
while(!track && trackiter.hasMoreElements()) float loopstoptime = std::numeric_limits<float>::max();
NifOgre::TextKeyMap::const_iterator keyiter = keys->begin();
while(keyiter != keys->end())
{ {
const Ogre::NodeAnimationTrack *cur = trackiter.getNext(); if(keyiter->second == loopstart)
if(cur->getAssociatedNode()->getName() == bonename) loopstarttime = keyiter->first;
track = cur; else if(keyiter->second == loopstop)
{
loopstoptime = keyiter->first;
break;
}
keyiter++;
} }
if(track && track->getNumKeyFrames() > 1) if(loopstoptime > loopstarttime)
{ {
const std::string loopstart = groupname+": loop start"; Ogre::Vector3 startpos = nonaccumctrl->getTranslation(loopstarttime);
const std::string loopstop = groupname+": loop stop"; Ogre::Vector3 endpos = nonaccumctrl->getTranslation(loopstarttime);
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)
{
loopstoptime = keyiter->first;
break;
}
keyiter++;
}
if(loopstoptime > loopstarttime) return startpos.distance(endpos) / (loopstoptime-loopstarttime);
{
Ogre::TransformKeyFrame startkf(0, loopstarttime);
Ogre::TransformKeyFrame endkf(0, loopstoptime);
track->getInterpolatedKeyFrame(anim->_getTimeIndex(loopstarttime), &startkf);
track->getInterpolatedKeyFrame(anim->_getTimeIndex(loopstoptime), &endkf);
return startkf.getTranslate().distance(endkf.getTranslate()) /
(loopstoptime-loopstarttime);
}
} }
return 0.0f; return 0.0f;
@ -298,20 +281,8 @@ Ogre::Vector3 Animation::updatePosition()
{ {
Ogre::Vector3 posdiff; 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. */ /* 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. */ /* Translate the accumulation root back to compensate for the move. */
mLastPosition += posdiff; mLastPosition += posdiff;
@ -344,24 +315,9 @@ void Animation::reset(const std::string &start, const std::string &stop)
mStopKey--; mStopKey--;
} }
if(mNonAccumRoot) if(mNonAccumCtrl)
{ mLastPosition = mNonAccumCtrl->getTranslation(mCurrentTime) *
const Ogre::NodeAnimationTrack *track = 0; mAccumulate;
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;
}
}
} }
@ -431,24 +387,34 @@ void Animation::play(const std::string &groupname, const std::string &start, con
{ {
if(iter->mSkelBase && iter->mSkelBase->hasAnimationState(groupname)) 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; 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) if(!foundanim)
{ {
mCurrentAnim = anim;
mCurrentKeys = keys; mCurrentKeys = keys;
mCurrentGroup = groupname; mCurrentGroup = groupname;
mCurrentControllers = &iter->mControllers; mCurrentControllers = &iter->mControllers;
mNonAccumCtrl = nonaccumctrl;
mAnimVelocity = 0.0f; mAnimVelocity = 0.0f;
foundanim = true; foundanim = true;
} }
if(!mNonAccumRoot) if(!mNonAccumRoot)
break; break;
mAnimVelocity = calcAnimVelocity(anim, mNonAccumRoot->getName(), groupname, keys); mAnimVelocity = calcAnimVelocity(nonaccumctrl, groupname, keys);
if(mAnimVelocity > 0.0f) break; if(mAnimVelocity > 0.0f) break;
} }
} }
@ -469,7 +435,7 @@ Ogre::Vector3 Animation::runAnimation(float timepassed)
Ogre::Vector3 movement(0.0f); Ogre::Vector3 movement(0.0f);
timepassed *= mAnimSpeedMult; timepassed *= mAnimSpeedMult;
while(mCurrentAnim && mPlaying) while(!mCurrentGroup.empty() && mPlaying)
{ {
float targetTime = mCurrentTime + timepassed; float targetTime = mCurrentTime + timepassed;
if(mNextKey->first > targetTime) if(mNextKey->first > targetTime)

View file

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