mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-03 23:56:43 +00:00 
			
		
		
		
	Specify the animation key to stop playing at
This commit is contained in:
		
							parent
							
								
									b8f5813609
								
							
						
					
					
						commit
						e6da9dfae5
					
				
					 4 changed files with 39 additions and 27 deletions
				
			
		| 
						 | 
					@ -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);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // --------------------------------------------------------------------------------------------------
 | 
					    // --------------------------------------------------------------------------------------------------
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue