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:
parent
adc6a948c7
commit
cc70c6263b
2 changed files with 42 additions and 76 deletions
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue