mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-20 07:23:51 +00:00
Add support for playing animation groups
This commit is contained in:
parent
f953d7f8c0
commit
9a7a629d0f
2 changed files with 129 additions and 16 deletions
|
@ -7,6 +7,7 @@
|
||||||
#include <OgreSubMesh.h>
|
#include <OgreSubMesh.h>
|
||||||
#include <OgreSceneManager.h>
|
#include <OgreSceneManager.h>
|
||||||
|
|
||||||
|
|
||||||
namespace MWRender
|
namespace MWRender
|
||||||
{
|
{
|
||||||
std::map<std::string, int> Animation::sUniqueIDs;
|
std::map<std::string, int> Animation::sUniqueIDs;
|
||||||
|
@ -28,16 +29,117 @@ Animation::~Animation()
|
||||||
mEntityList.mEntities.clear();
|
mEntityList.mEntities.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Animation::playGroup(std::string groupname, int mode, int loops)
|
|
||||||
{
|
struct checklow {
|
||||||
if(groupname == "all")
|
bool operator()(const char &a, const char &b) const
|
||||||
{
|
{
|
||||||
mAnimate = loops;
|
return ::tolower(a) == ::tolower(b);
|
||||||
mTime = 0.0f;
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool Animation::findGroupTimes(const std::string &groupname, float *starttime, float *stoptime, float *loopstarttime, float *loopstoptime)
|
||||||
|
{
|
||||||
|
const std::string &start = groupname+": start";
|
||||||
|
const std::string &startloop = groupname+": loop start";
|
||||||
|
const std::string &stop = groupname+": stop";
|
||||||
|
const std::string &stoploop = groupname+": loop stop";
|
||||||
|
|
||||||
|
*starttime = -1.0f;
|
||||||
|
*stoptime = -1.0f;
|
||||||
|
*loopstarttime = -1.0f;
|
||||||
|
*loopstoptime = -1.0f;
|
||||||
|
|
||||||
|
NifOgre::TextKeyMap::const_iterator iter;
|
||||||
|
for(iter = mTextKeys.begin();iter != mTextKeys.end();iter++)
|
||||||
|
{
|
||||||
|
if(*starttime >= 0.0f && *stoptime >= 0.0f && *loopstarttime >= 0.0f && *loopstoptime >= 0.0f)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
std::string::const_iterator strpos = iter->second.begin();
|
||||||
|
std::string::const_iterator strend = iter->second.end();
|
||||||
|
|
||||||
|
while(strpos != strend)
|
||||||
|
{
|
||||||
|
size_t strlen = strend-strpos;
|
||||||
|
std::string::const_iterator striter;
|
||||||
|
|
||||||
|
if(start.size() <= strlen &&
|
||||||
|
((striter=std::mismatch(strpos, strend, start.begin(), checklow()).first) == strend ||
|
||||||
|
*striter == '\r' || *striter == '\n'))
|
||||||
|
{
|
||||||
|
*starttime = iter->first;
|
||||||
|
*loopstarttime = iter->first;
|
||||||
|
}
|
||||||
|
else if(startloop.size() <= strlen &&
|
||||||
|
((striter=std::mismatch(strpos, strend, startloop.begin(), checklow()).first) == strend ||
|
||||||
|
*striter == '\r' || *striter == '\n'))
|
||||||
|
{
|
||||||
|
*loopstarttime = iter->first;
|
||||||
|
}
|
||||||
|
else if(stoploop.size() <= strlen &&
|
||||||
|
((striter=std::mismatch(strpos, strend, stoploop.begin(), checklow()).first) == strend ||
|
||||||
|
*striter == '\r' || *striter == '\n'))
|
||||||
|
{
|
||||||
|
*loopstoptime = iter->first;
|
||||||
|
}
|
||||||
|
else if(stop.size() <= strlen &&
|
||||||
|
((striter=std::mismatch(strpos, strend, stop.begin(), checklow()).first) == strend ||
|
||||||
|
*striter == '\r' || *striter == '\n'))
|
||||||
|
{
|
||||||
|
*stoptime = iter->first;
|
||||||
|
if(*loopstoptime < 0.0f)
|
||||||
|
*loopstoptime = iter->first;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
strpos = std::find(strpos+1, strend, '\n');
|
||||||
|
while(strpos != strend && *strpos == '\n')
|
||||||
|
strpos++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (*starttime >= 0.0f && *stoptime >= 0.0f && *loopstarttime >= 0.0f && *loopstoptime >= 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Animation::playGroup(std::string groupname, int mode, int loops)
|
||||||
|
{
|
||||||
|
float start, stop, loopstart, loopstop;
|
||||||
|
|
||||||
|
if(groupname == "all")
|
||||||
|
{
|
||||||
|
mLoopStartTime = mStartTime = 0.0f;
|
||||||
|
mLoopStopTime = mStopTime = 0.0f;
|
||||||
|
|
||||||
|
if(mEntityList.mSkelBase)
|
||||||
|
{
|
||||||
|
Ogre::AnimationStateSet *aset = mEntityList.mSkelBase->getAllAnimationStates();
|
||||||
|
Ogre::AnimationStateIterator as = aset->getAnimationStateIterator();
|
||||||
|
while(as.hasMoreElements())
|
||||||
|
{
|
||||||
|
Ogre::AnimationState *state = as.getNext();
|
||||||
|
mLoopStopTime = mStopTime = state->getLength();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mAnimate = loops;
|
||||||
|
mTime = mStartTime;
|
||||||
|
}
|
||||||
|
else if(findGroupTimes(groupname, &start, &stop, &loopstart, &loopstop))
|
||||||
|
{
|
||||||
|
mStartTime = start;
|
||||||
|
mStopTime = stop;
|
||||||
|
mLoopStartTime = loopstart;
|
||||||
|
mLoopStopTime = loopstop;
|
||||||
|
|
||||||
|
mAnimate = loops;
|
||||||
|
mTime = mStartTime;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw std::runtime_error("Failed to find animation group "+groupname);
|
||||||
|
}
|
||||||
|
|
||||||
void Animation::skipAnim()
|
void Animation::skipAnim()
|
||||||
{
|
{
|
||||||
mSkipFrame = true;
|
mSkipFrame = true;
|
||||||
|
@ -45,9 +147,22 @@ void Animation::skipAnim()
|
||||||
|
|
||||||
void Animation::runAnimation(float timepassed)
|
void Animation::runAnimation(float timepassed)
|
||||||
{
|
{
|
||||||
if(mAnimate != 0 && !mSkipFrame)
|
if(mAnimate > 0 && !mSkipFrame)
|
||||||
{
|
{
|
||||||
mTime += timepassed;
|
mTime += timepassed;
|
||||||
|
if(mTime >= mLoopStopTime)
|
||||||
|
{
|
||||||
|
if(mAnimate > 1)
|
||||||
|
{
|
||||||
|
mAnimate--;
|
||||||
|
mTime = mTime - mLoopStopTime + mLoopStartTime;
|
||||||
|
}
|
||||||
|
else if(mTime >= mStopTime)
|
||||||
|
{
|
||||||
|
mAnimate--;
|
||||||
|
mTime = mStopTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(mEntityList.mSkelBase)
|
if(mEntityList.mSkelBase)
|
||||||
{
|
{
|
||||||
|
@ -57,16 +172,6 @@ void Animation::runAnimation(float timepassed)
|
||||||
{
|
{
|
||||||
Ogre::AnimationState *state = as.getNext();
|
Ogre::AnimationState *state = as.getNext();
|
||||||
state->setTimePosition(mTime);
|
state->setTimePosition(mTime);
|
||||||
if(mTime >= state->getLength())
|
|
||||||
{
|
|
||||||
if(mAnimate != -1)
|
|
||||||
mAnimate--;
|
|
||||||
//std::cout << "Stopping the animation\n";
|
|
||||||
if(mAnimate == 0)
|
|
||||||
mTime = state->getLength();
|
|
||||||
else
|
|
||||||
mTime = mTime - state->getLength();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,12 +26,20 @@ protected:
|
||||||
static std::map<std::string, int> sUniqueIDs;
|
static std::map<std::string, int> sUniqueIDs;
|
||||||
|
|
||||||
float mTime;
|
float mTime;
|
||||||
|
float mStartTime;
|
||||||
|
float mStopTime;
|
||||||
|
float mLoopStartTime;
|
||||||
|
float mLoopStopTime;
|
||||||
|
|
||||||
int mAnimate;
|
int mAnimate;
|
||||||
bool mSkipFrame;
|
bool mSkipFrame;
|
||||||
|
|
||||||
NifOgre::EntityList mEntityList;
|
NifOgre::EntityList mEntityList;
|
||||||
NifOgre::TextKeyMap mTextKeys;
|
NifOgre::TextKeyMap mTextKeys;
|
||||||
|
|
||||||
|
bool findGroupTimes(const std::string &groupname, float *starttime, float *stoptime,
|
||||||
|
float *loopstarttime, float *loopstoptime);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Animation(OEngine::Render::OgreRenderer& _rend);
|
Animation(OEngine::Render::OgreRenderer& _rend);
|
||||||
virtual ~Animation();
|
virtual ~Animation();
|
||||||
|
|
Loading…
Reference in a new issue