mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-27 03:35:27 +00:00
Use reset to check that the animation exists and has the right markers
This commit is contained in:
parent
507d72ede5
commit
a2fc43c7df
@ -209,14 +209,14 @@ void Animation::updatePtr(const MWWorld::Ptr &ptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float Animation::calcAnimVelocity(NifOgre::NodeTargetValue<Ogre::Real> *nonaccumctrl, const std::string &groupname, const NifOgre::TextKeyMap *keys)
|
float Animation::calcAnimVelocity(const NifOgre::TextKeyMap &keys, NifOgre::NodeTargetValue<Ogre::Real> *nonaccumctrl, const std::string &groupname)
|
||||||
{
|
{
|
||||||
const std::string loopstart = groupname+": loop start";
|
const std::string loopstart = groupname+": loop start";
|
||||||
const std::string loopstop = groupname+": loop stop";
|
const std::string loopstop = groupname+": loop stop";
|
||||||
float loopstarttime = 0.0f;
|
float loopstarttime = 0.0f;
|
||||||
float loopstoptime = std::numeric_limits<float>::max();
|
float loopstoptime = 0.0f;
|
||||||
NifOgre::TextKeyMap::const_iterator keyiter = keys->begin();
|
NifOgre::TextKeyMap::const_iterator keyiter = keys.begin();
|
||||||
while(keyiter != keys->end())
|
while(keyiter != keys.end())
|
||||||
{
|
{
|
||||||
if(keyiter->second == loopstart)
|
if(keyiter->second == loopstart)
|
||||||
loopstarttime = keyiter->first;
|
loopstarttime = keyiter->first;
|
||||||
@ -291,36 +291,44 @@ Ogre::Vector3 Animation::updatePosition()
|
|||||||
return posdiff;
|
return posdiff;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Animation::reset(const std::string &start, const std::string &stop)
|
bool Animation::reset(const NifOgre::TextKeyMap &keys, NifOgre::NodeTargetValue<Ogre::Real> *nonaccumctrl, const std::string &groupname, const std::string &start, const std::string &stop)
|
||||||
{
|
{
|
||||||
std::string tag = mCurrentGroup+": "+start;
|
std::string tag = groupname+": "+start;
|
||||||
mStartKey = mCurrentKeys->begin();
|
NifOgre::TextKeyMap::const_iterator startkey(keys.begin());
|
||||||
while(mStartKey != mCurrentKeys->end() && mStartKey->second != tag)
|
while(startkey != keys.end() && startkey->second != tag)
|
||||||
mStartKey++;
|
startkey++;
|
||||||
if(mStartKey == mCurrentKeys->end() && tag == "loop start")
|
if(startkey == keys.end() && tag == "loop start")
|
||||||
{
|
{
|
||||||
tag = mCurrentGroup+": start";
|
tag = groupname+": start";
|
||||||
mStartKey = mCurrentKeys->begin();
|
startkey = keys.begin();
|
||||||
while(mStartKey != mCurrentKeys->end() && mStartKey->second != tag)
|
while(startkey != keys.end() && startkey->second != tag)
|
||||||
mStartKey++;
|
startkey++;
|
||||||
}
|
}
|
||||||
if(mStartKey == mCurrentKeys->end())
|
if(startkey == keys.end())
|
||||||
mStartKey = mCurrentKeys->begin();
|
return false;
|
||||||
|
|
||||||
tag = mCurrentGroup+": "+stop;
|
tag = groupname+": "+stop;
|
||||||
mStopKey = mStartKey;
|
NifOgre::TextKeyMap::const_iterator stopkey(startkey);
|
||||||
while(mStopKey != mCurrentKeys->end() && mStopKey->second != tag)
|
while(stopkey != keys.end() && stopkey->second != tag)
|
||||||
mStopKey++;
|
stopkey++;
|
||||||
if(mStopKey == mCurrentKeys->end())
|
if(stopkey == keys.end())
|
||||||
mStopKey--;
|
return false;
|
||||||
|
|
||||||
mCurrentTime = mStartKey->first;
|
if(startkey == stopkey)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
mStartKey = startkey;
|
||||||
mLoopStartKey = mStartKey;
|
mLoopStartKey = mStartKey;
|
||||||
|
mStopKey = stopkey;
|
||||||
mNextKey = mStartKey;
|
mNextKey = mStartKey;
|
||||||
++mNextKey;
|
++mNextKey;
|
||||||
|
|
||||||
if(mNonAccumCtrl)
|
mCurrentTime = mStartKey->first;
|
||||||
mLastPosition = mNonAccumCtrl->getTranslation(mCurrentTime) * mAccumulate;
|
|
||||||
|
if(nonaccumctrl)
|
||||||
|
mLastPosition = nonaccumctrl->getTranslation(mCurrentTime) * mAccumulate;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Animation::doLoop()
|
void Animation::doLoop()
|
||||||
@ -390,45 +398,46 @@ void Animation::play(const std::string &groupname, const std::string &start, con
|
|||||||
/* Look in reverse; last-inserted source has priority. */
|
/* Look in reverse; last-inserted source has priority. */
|
||||||
for(std::vector<NifOgre::ObjectList>::reverse_iterator iter(mObjectLists.rbegin());iter != mObjectLists.rend();iter++)
|
for(std::vector<NifOgre::ObjectList>::reverse_iterator iter(mObjectLists.rbegin());iter != mObjectLists.rend();iter++)
|
||||||
{
|
{
|
||||||
if(iter->mSkelBase && iter->mSkelBase->hasAnimationState(groupname))
|
if(iter->mTextKeys.size() == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const NifOgre::TextKeyMap &keys = iter->mTextKeys.begin()->second;
|
||||||
|
NifOgre::NodeTargetValue<Ogre::Real> *nonaccumctrl = NULL;
|
||||||
|
for(size_t i = 0;i < iter->mControllers.size();i++)
|
||||||
{
|
{
|
||||||
const NifOgre::TextKeyMap *keys = &iter->mTextKeys.begin()->second;
|
NifOgre::NodeTargetValue<Ogre::Real> *dstval;
|
||||||
NifOgre::NodeTargetValue<Ogre::Real> *nonaccumctrl = NULL;
|
dstval = dynamic_cast<NifOgre::NodeTargetValue<Ogre::Real>*>(iter->mControllers[i].getDestination().getPointer());
|
||||||
for(size_t i = 0;i < iter->mControllers.size();i++)
|
if(dstval && dstval->getNode() == mNonAccumRoot)
|
||||||
{
|
{
|
||||||
NifOgre::NodeTargetValue<Ogre::Real> *dstval;
|
nonaccumctrl = dstval;
|
||||||
dstval = dynamic_cast<NifOgre::NodeTargetValue<Ogre::Real>*>(iter->mControllers[i].getDestination().getPointer());
|
|
||||||
if(dstval && dstval->getNode() == mNonAccumRoot)
|
|
||||||
{
|
|
||||||
nonaccumctrl = dstval;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!foundanim)
|
|
||||||
{
|
|
||||||
mCurrentKeys = keys;
|
|
||||||
mCurrentGroup = groupname;
|
|
||||||
mCurrentControllers = &iter->mControllers;
|
|
||||||
mNonAccumCtrl = nonaccumctrl;
|
|
||||||
mAnimVelocity = 0.0f;
|
|
||||||
|
|
||||||
foundanim = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!mNonAccumRoot)
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
mAnimVelocity = calcAnimVelocity(nonaccumctrl, groupname, keys);
|
|
||||||
if(mAnimVelocity > 0.0f) break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!foundanim)
|
||||||
|
{
|
||||||
|
if(!reset(keys, nonaccumctrl, groupname, start, stop))
|
||||||
|
continue;
|
||||||
|
mCurrentKeys = &keys;
|
||||||
|
mCurrentGroup = groupname;
|
||||||
|
mCurrentControllers = &iter->mControllers;
|
||||||
|
mNonAccumCtrl = nonaccumctrl;
|
||||||
|
mAnimVelocity = 0.0f;
|
||||||
|
|
||||||
|
setLooping(loop);
|
||||||
|
mPlaying = true;
|
||||||
|
|
||||||
|
foundanim = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!mNonAccumRoot)
|
||||||
|
break;
|
||||||
|
|
||||||
|
mAnimVelocity = calcAnimVelocity(keys, nonaccumctrl, groupname);
|
||||||
|
if(mAnimVelocity > 0.0f) break;
|
||||||
}
|
}
|
||||||
if(!foundanim)
|
if(!foundanim)
|
||||||
throw std::runtime_error("Failed to find animation "+groupname);
|
throw std::runtime_error("Failed to find animation "+groupname);
|
||||||
|
|
||||||
reset(start, stop);
|
|
||||||
setLooping(loop);
|
|
||||||
mPlaying = true;
|
|
||||||
}
|
}
|
||||||
catch(std::exception &e) {
|
catch(std::exception &e) {
|
||||||
std::cerr<< e.what() <<std::endl;
|
std::cerr<< e.what() <<std::endl;
|
||||||
|
@ -66,8 +66,9 @@ protected:
|
|||||||
float mAnimVelocity;
|
float mAnimVelocity;
|
||||||
float mAnimSpeedMult;
|
float mAnimSpeedMult;
|
||||||
|
|
||||||
static float calcAnimVelocity(NifOgre::NodeTargetValue<Ogre::Real> *nonaccumctrl,
|
static float calcAnimVelocity(const NifOgre::TextKeyMap &keys,
|
||||||
const std::string &groupname, const NifOgre::TextKeyMap *keys);
|
NifOgre::NodeTargetValue<Ogre::Real> *nonaccumctrl,
|
||||||
|
const std::string &groupname);
|
||||||
|
|
||||||
/* 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
|
||||||
* bone names) are positioned identically. */
|
* bone names) are positioned identically. */
|
||||||
@ -79,9 +80,10 @@ protected:
|
|||||||
|
|
||||||
/* Resets the animation to the time of the specified start marker, without
|
/* Resets the animation to the time of the specified start marker, without
|
||||||
* moving anything, and set the end time to the specified stop marker. If
|
* moving anything, and set the end time to the specified stop marker. If
|
||||||
* the marker is not found, it resets to the beginning or end respectively.
|
* the marker is not found, or if the markers are the same, it returns
|
||||||
|
* false.
|
||||||
*/
|
*/
|
||||||
void reset(const std::string &start, const std::string &stop=std::string());
|
bool reset(const NifOgre::TextKeyMap &keys, NifOgre::NodeTargetValue<Ogre::Real> *nonaccumctrl, const std::string &groupname, const std::string &start, const std::string &stop);
|
||||||
|
|
||||||
void doLoop();
|
void doLoop();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user