Allow specifying where to start in an animation

This commit is contained in:
Chris Robinson 2013-04-24 19:09:36 -07:00
parent 333354fe62
commit 0817d59f23
4 changed files with 38 additions and 16 deletions

View file

@ -121,7 +121,7 @@ CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Anim
mAnimation->setAccumulation(Ogre::Vector3(0.0f));
}
if(mAnimation->hasAnimation(mCurrentGroup))
mAnimation->play(mCurrentGroup, "start", "stop", loop ? (~(size_t)0) : 0);
mAnimation->play(mCurrentGroup, "start", "stop", 1.0f, loop ? (~(size_t)0) : 0);
}
CharacterController::~CharacterController()
@ -204,15 +204,15 @@ void CharacterController::update(float duration, Movement &movement)
}
else if(getState() != CharState_SpecialIdle || !mAnimation->isPlaying(0))
{
if(mAnimQueue.size() > 0)
if(mAnimQueue.size() == 0)
setState((inwater ? CharState_IdleSwim : (sneak ? CharState_IdleSneak : CharState_Idle)), true);
else
{
mCurrentGroup = mAnimQueue.front().first;
size_t count = mAnimQueue.front().second;
mAnimQueue.pop_front();
mAnimation->play(mCurrentGroup, "start", "stop", count);
mAnimation->play(mCurrentGroup, "start", "stop", 0.0f, count);
}
else
setState((inwater ? CharState_IdleSwim : (sneak ? CharState_IdleSneak : CharState_Idle)), true);
}
movement.mRotation[0] += rot.x * duration;
@ -244,7 +244,7 @@ void CharacterController::playGroup(const std::string &groupname, int mode, int
mAnimQueue.clear();
mCurrentGroup = groupname;
mState = CharState_SpecialIdle;
mAnimation->play(mCurrentGroup, ((mode==2) ? "loop start" : "start"), "stop", count-1);
mAnimation->play(mCurrentGroup, ((mode==2) ? "loop start" : "start"), "stop", 0.0f, count-1);
}
else if(mode == 0)
{
@ -275,7 +275,7 @@ void CharacterController::setState(CharacterState state, bool loop)
if(mAnimation->hasAnimation(anim))
{
mCurrentGroup = anim;
mAnimation->play(mCurrentGroup, "start", "stop", loop ? (~(size_t)0) : 0);
mAnimation->play(mCurrentGroup, "start", "stop", 0.0f, loop ? (~(size_t)0) : 0);
}
}

View file

@ -402,7 +402,7 @@ void Animation::updatePosition(Ogre::Vector3 &position)
mAccumRoot->setPosition(-mLastPosition);
}
bool Animation::reset(size_t layeridx, const NifOgre::TextKeyMap &keys, NifOgre::NodeTargetValue<Ogre::Real> *nonaccumctrl, const std::string &groupname, const std::string &start, const std::string &stop)
bool Animation::reset(size_t layeridx, const NifOgre::TextKeyMap &keys, NifOgre::NodeTargetValue<Ogre::Real> *nonaccumctrl, const std::string &groupname, const std::string &start, const std::string &stop, float startpoint)
{
std::string tag = groupname+": "+start;
NifOgre::TextKeyMap::const_iterator startkey(keys.begin());
@ -432,9 +432,17 @@ bool Animation::reset(size_t layeridx, const NifOgre::TextKeyMap &keys, NifOgre:
mLayer[layeridx].mLoopStartKey = startkey;
mLayer[layeridx].mStopKey = stopkey;
mLayer[layeridx].mNextKey = startkey;
mLayer[layeridx].mNextKey++;
mLayer[layeridx].mTime = mLayer[layeridx].mStartKey->first;
mLayer[layeridx].mTime = mLayer[layeridx].mStartKey->first + ((mLayer[layeridx].mStopKey->first-
mLayer[layeridx].mStartKey->first) * startpoint);
tag = groupname+": loop start";
while(mLayer[layeridx].mNextKey->first <= mLayer[layeridx].mTime && mLayer[layeridx].mNextKey != mLayer[layeridx].mStopKey)
{
if(mLayer[layeridx].mNextKey->second == tag)
mLayer[layeridx].mLoopStartKey = mLayer[layeridx].mNextKey;
mLayer[layeridx].mNextKey++;
}
if(layeridx == 0 && nonaccumctrl)
mLastPosition = nonaccumctrl->getTranslation(mLayer[layeridx].mTime) * mAccumulate;
@ -507,7 +515,7 @@ bool Animation::handleTextKey(size_t layeridx, const NifOgre::TextKeyMap::const_
}
void Animation::play(const std::string &groupname, const std::string &start, const std::string &stop, size_t loops)
void Animation::play(const std::string &groupname, const std::string &start, const std::string &stop, float startpoint, size_t loops)
{
// TODO: parameterize this
size_t layeridx = 0;
@ -554,7 +562,7 @@ void Animation::play(const std::string &groupname, const std::string &start, con
if(!foundanim)
{
if(!reset(layeridx, keys, nonaccumctrl, groupname, start, stop))
if(!reset(layeridx, keys, nonaccumctrl, groupname, start, stop, startpoint))
continue;
mLayer[layeridx].mGroupName = groupname;
mLayer[layeridx].mTextKeys = &keys;

View file

@ -95,7 +95,10 @@ protected:
* the marker is not found, or if the markers are the same, it returns
* false.
*/
bool reset(size_t layeridx, const NifOgre::TextKeyMap &keys, NifOgre::NodeTargetValue<Ogre::Real> *nonaccumctrl, const std::string &groupname, const std::string &start, const std::string &stop);
bool reset(size_t layeridx, const NifOgre::TextKeyMap &keys,
NifOgre::NodeTargetValue<Ogre::Real> *nonaccumctrl,
const std::string &groupname, const std::string &start, const std::string &stop,
float startpoint);
bool doLoop(size_t layeridx);
@ -123,7 +126,18 @@ public:
void setSpeed(float speed);
void play(const std::string &groupname, const std::string &start, const std::string &stop, size_t loops);
/** Plays an animation.
* \param groupname Name of the animation group to play.
* \param start Key marker from which to start.
* \param stop Key marker to stop at.
* \param startpoint How far in between the two markers to start. 0 starts
* at the start marker, 1 starts at the stop marker.
* \param loops How many times to loop the animation. This will use the
* "loop start" and "loop stop" markers if they exist,
* otherwise it will use "start" and "stop".
*/
void play(const std::string &groupname, const std::string &start, const std::string &stop, float startpoint, size_t loops);
virtual Ogre::Vector3 runAnimation(float timepassed);
bool isPlaying(size_t layeridx) const

View file

@ -155,7 +155,7 @@ namespace MWRender
if (!mSelectionBuffer)
mSelectionBuffer = new OEngine::Render::SelectionBuffer(mCamera, 512, 1024, 0);
mAnimation->play("inventoryhandtohand", "start", "stop", 0);
mAnimation->play("inventoryhandtohand", "start", "stop", 0.0f, 0);
}
// --------------------------------------------------------------------------------------------------
@ -189,7 +189,7 @@ namespace MWRender
void RaceSelectionPreview::onSetup ()
{
mAnimation->play("idle", "start", "stop", 0);
mAnimation->play("idle", "start", "stop", 0.0f, 0);
updateCamera();
}