1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-26 09:35:28 +00:00

Specify the animation key to stop playing at

This commit is contained in:
Chris Robinson 2013-02-23 05:15:10 -08:00
parent b8f5813609
commit e6da9dfae5
4 changed files with 39 additions and 27 deletions

View File

@ -113,7 +113,7 @@ CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Anim
mAnimation->setAccumulation(Ogre::Vector3(1.0f, 1.0f, 0.0f)); mAnimation->setAccumulation(Ogre::Vector3(1.0f, 1.0f, 0.0f));
} }
if(mAnimation->hasAnimation(mCurrentGroup)) if(mAnimation->hasAnimation(mCurrentGroup))
mAnimation->play(mCurrentGroup, "stop", loop); mAnimation->play(mCurrentGroup, "stop", "stop", loop);
} }
CharacterController::CharacterController(const CharacterController &rhs) CharacterController::CharacterController(const CharacterController &rhs)
@ -152,7 +152,7 @@ void CharacterController::markerEvent(float time, const std::string &evt)
if(mAnimQueue.size() >= 2 && mAnimQueue[0] == mAnimQueue[1]) if(mAnimQueue.size() >= 2 && mAnimQueue[0] == mAnimQueue[1])
{ {
mAnimQueue.pop_front(); mAnimQueue.pop_front();
mAnimation->play(mCurrentGroup, "loop start", false); mAnimation->play(mCurrentGroup, "loop start", "stop", false);
} }
else if(mAnimQueue.size() > 0) else if(mAnimQueue.size() > 0)
{ {
@ -160,7 +160,7 @@ void CharacterController::markerEvent(float time, const std::string &evt)
if(mAnimQueue.size() > 0) if(mAnimQueue.size() > 0)
{ {
mCurrentGroup = mAnimQueue.front(); mCurrentGroup = mAnimQueue.front();
mAnimation->play(mCurrentGroup, "start", false); mAnimation->play(mCurrentGroup, "start", "stop", false);
} }
} }
return; return;
@ -247,7 +247,7 @@ void CharacterController::playGroup(const std::string &groupname, int mode, int
mAnimQueue.push_back(groupname); mAnimQueue.push_back(groupname);
mCurrentGroup = groupname; mCurrentGroup = groupname;
mState = CharState_SpecialIdle; mState = CharState_SpecialIdle;
mAnimation->play(mCurrentGroup, ((mode==2) ? "loop start" : "start"), false); mAnimation->play(mCurrentGroup, ((mode==2) ? "loop start" : "start"), "stop", false);
} }
else if(mode == 0) else if(mode == 0)
{ {
@ -283,7 +283,7 @@ void CharacterController::setState(CharacterState state, bool loop)
if(mAnimation->hasAnimation(anim)) if(mAnimation->hasAnimation(anim))
{ {
mCurrentGroup = anim; mCurrentGroup = anim;
mAnimation->play(mCurrentGroup, "start", loop); mAnimation->play(mCurrentGroup, "start", "stop", loop);
} }
} }

View File

@ -26,6 +26,7 @@ Animation::Animation(const MWWorld::Ptr &ptr)
, mCurrentKeys(NULL) , mCurrentKeys(NULL)
, mCurrentAnim(NULL) , mCurrentAnim(NULL)
, mCurrentTime(0.0f) , mCurrentTime(0.0f)
, mStopTime(0.0f)
, mPlaying(false) , mPlaying(false)
, mLooping(false) , mLooping(false)
, mAnimVelocity(0.0f) , mAnimVelocity(0.0f)
@ -293,12 +294,12 @@ Ogre::Vector3 Animation::updatePosition(float time)
return posdiff; return posdiff;
} }
void Animation::reset(const std::string &marker) void Animation::reset(const std::string &start, const std::string &stop)
{ {
mNextKey = mCurrentKeys->begin(); mNextKey = mCurrentKeys->begin();
while(mNextKey != mCurrentKeys->end() && mNextKey->second != marker)
mNextKey++;
while(mNextKey != mCurrentKeys->end() && mNextKey->second != start)
mNextKey++;
if(mNextKey != mCurrentKeys->end()) if(mNextKey != mCurrentKeys->end())
mCurrentTime = mNextKey->first; mCurrentTime = mNextKey->first;
else else
@ -307,6 +308,17 @@ void Animation::reset(const std::string &marker)
mCurrentTime = 0.0f; mCurrentTime = 0.0f;
} }
if(stop.length() > 0)
{
NifOgre::TextKeyMap::const_iterator stopKey = mNextKey;
while(stopKey != mCurrentKeys->end() && stopKey->second != stop)
stopKey++;
if(stopKey != mCurrentKeys->end())
mStopTime = stopKey->first;
else
mStopTime = mCurrentAnim->getLength();
}
if(mNonAccumRoot) if(mNonAccumRoot)
{ {
const Ogre::NodeAnimationTrack *track = 0; const Ogre::NodeAnimationTrack *track = 0;
@ -328,7 +340,7 @@ void Animation::reset(const std::string &marker)
} }
void Animation::play(const std::string &groupname, const std::string &start, bool loop) void Animation::play(const std::string &groupname, const std::string &start, const std::string &stop, bool loop)
{ {
try { try {
bool found = false; bool found = false;
@ -351,9 +363,9 @@ void Animation::play(const std::string &groupname, const std::string &start, boo
if(!found) if(!found)
throw std::runtime_error("Failed to find animation "+groupname); throw std::runtime_error("Failed to find animation "+groupname);
reset(start); reset(start, stop);
setLooping(loop);
mPlaying = true; mPlaying = true;
mLooping = loop;
} }
catch(std::exception &e) { catch(std::exception &e) {
std::cerr<< e.what() <<std::endl; std::cerr<< e.what() <<std::endl;
@ -367,11 +379,11 @@ Ogre::Vector3 Animation::runAnimation(float timepassed)
timepassed *= mAnimSpeedMult; timepassed *= mAnimSpeedMult;
while(mCurrentAnim && mPlaying) while(mCurrentAnim && mPlaying)
{ {
float targetTime = mCurrentTime + timepassed; float targetTime = std::min(mStopTime, mCurrentTime+timepassed);
if(mNextKey == mCurrentKeys->end() || mNextKey->first > targetTime) if(mNextKey == mCurrentKeys->end() || mNextKey->first > targetTime)
{ {
movement += updatePosition(targetTime); movement += updatePosition(targetTime);
mPlaying = (mLooping || mCurrentAnim->getLength() >= targetTime); mPlaying = (mLooping || mStopTime > targetTime);
break; break;
} }
@ -380,6 +392,8 @@ Ogre::Vector3 Animation::runAnimation(float timepassed)
mNextKey++; mNextKey++;
movement += updatePosition(time); movement += updatePosition(time);
mPlaying = (mLooping || mStopTime > time);
timepassed = targetTime - time; timepassed = targetTime - time;
if(evt == "start" || evt == "loop start") if(evt == "start" || evt == "loop start")
@ -391,7 +405,7 @@ Ogre::Vector3 Animation::runAnimation(float timepassed)
{ {
if(mLooping) if(mLooping)
{ {
reset("loop start"); reset("loop start", "");
if(mCurrentTime >= time) if(mCurrentTime >= time)
break; break;
} }
@ -401,17 +415,12 @@ Ogre::Vector3 Animation::runAnimation(float timepassed)
{ {
if(mLooping) if(mLooping)
{ {
reset("loop start"); reset("loop start", "");
if(mCurrentTime >= time) if(mCurrentTime >= time)
break; break;
continue;
} }
else // fall-through
{
mPlaying = false;
if(mController)
mController->markerEvent(time, evt);
}
continue;
} }
if(mController) if(mController)
mController->markerEvent(time, evt); mController->markerEvent(time, evt);

View File

@ -33,6 +33,7 @@ protected:
NifOgre::TextKeyMap::const_iterator mNextKey; NifOgre::TextKeyMap::const_iterator mNextKey;
Ogre::Animation *mCurrentAnim; Ogre::Animation *mCurrentAnim;
float mCurrentTime; float mCurrentTime;
float mStopTime;
bool mPlaying; bool mPlaying;
bool mLooping; bool mLooping;
@ -53,9 +54,11 @@ protected:
* vector since the last update or reset. */ * vector since the last update or reset. */
Ogre::Vector3 updatePosition(float time); Ogre::Vector3 updatePosition(float time);
/* Resets the animation to the time of the specified marker, without moving /* Resets the animation to the time of the specified start marker, without
* anything. If the marker is not found, it resets to the beginning. */ * moving anything, and set the end time to the specified stop marker. If
void reset(const std::string &marker); * the marker is not found, it resets to the beginning or end respectively.
*/
void reset(const std::string &start, const std::string &stop);
/* Specifies a list of skeleton names to use as animation sources. */ /* Specifies a list of skeleton names to use as animation sources. */
void setAnimationSources(const std::vector<std::string> &names); void setAnimationSources(const std::vector<std::string> &names);
@ -86,7 +89,7 @@ public:
void setLooping(bool loop); void setLooping(bool loop);
void play(const std::string &groupname, const std::string &start, bool loop); void play(const std::string &groupname, const std::string &start, const std::string &stop, bool loop);
virtual Ogre::Vector3 runAnimation(float timepassed); virtual Ogre::Vector3 runAnimation(float timepassed);
}; };

View File

@ -145,7 +145,7 @@ namespace MWRender
{ {
mSelectionBuffer = new OEngine::Render::SelectionBuffer(mCamera, 512, 1024, RV_PlayerPreview); mSelectionBuffer = new OEngine::Render::SelectionBuffer(mCamera, 512, 1024, RV_PlayerPreview);
mAnimation->play("inventoryhandtohand", "start", false); mAnimation->play("inventoryhandtohand", "start", "stop", false);
} }
// -------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------