From f296d13c20e89ec49869aa8f4194bfc9cf738e52 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 16 Jul 2013 00:43:31 -0700 Subject: [PATCH] Add a speed multiplier to the animation state --- apps/openmw/mwmechanics/character.cpp | 22 +++++++++++----------- apps/openmw/mwrender/animation.cpp | 9 ++++++--- apps/openmw/mwrender/animation.hpp | 9 ++++++--- apps/openmw/mwrender/characterpreview.cpp | 8 ++++---- apps/openmw/mwworld/player.cpp | 4 ++-- 5 files changed, 29 insertions(+), 23 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 8c231107e6..0d62e546a1 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -166,7 +166,7 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat mAnimation->disable(mCurrentIdle); mCurrentIdle = idle; mAnimation->play(mCurrentIdle, Priority_Default, MWRender::Animation::Group_All, false, - "start", "stop", 0.0f, ~0ul); + 1.0f, "start", "stop", 0.0f, ~0ul); } if(force || movement != mMovementState) @@ -208,7 +208,7 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat mCurrentMovement = movement; if(!mCurrentMovement.empty()) mAnimation->play(mCurrentMovement, Priority_Movement, movegroup, false, - "start", "stop", 0.0f, ~0ul); + 1.0f, "start", "stop", 0.0f, ~0ul); } } @@ -263,7 +263,7 @@ CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Anim mCurrentDeath = state->groupname; mAnimation->play(mCurrentDeath, Priority_Death, MWRender::Animation::Group_All, - false, "start", "stop", 1.0f, 0); + false, 1.0f, "start", "stop", 1.0f, 0); } } @@ -294,7 +294,7 @@ void CharacterController::update(float duration, Movement &movement) mAnimation->play(mAnimQueue.front().first, Priority_Default, MWRender::Animation::Group_All, false, - "start", "stop", 0.0f, mAnimQueue.front().second); + 1.0f, "start", "stop", 0.0f, mAnimQueue.front().second); } } } @@ -406,7 +406,7 @@ void CharacterController::update(float duration, Movement &movement) mAnimation->play(mAnimQueue.front().first, Priority_Default, MWRender::Animation::Group_All, false, - "start", "stop", 0.0f, mAnimQueue.front().second); + 1.0f, "start", "stop", 0.0f, mAnimQueue.front().second); } } @@ -494,7 +494,7 @@ void CharacterController::update(float duration, Movement &movement) getWeaponGroup(mWeaponType, weapgroup); mAnimation->play(weapgroup, Priority_Weapon, MWRender::Animation::Group_UpperBody, true, - "unequip start", "unequip stop", 0.0f, 0); + 1.0f, "unequip start", "unequip stop", 0.0f, 0); } else { @@ -502,7 +502,7 @@ void CharacterController::update(float duration, Movement &movement) mAnimation->showWeapons(false); mAnimation->play(weapgroup, Priority_Weapon, MWRender::Animation::Group_UpperBody, true, - "equip start", "equip stop", 0.0f, 0); + 1.0f, "equip start", "equip stop", 0.0f, 0); } mWeaponType = weaptype; @@ -526,7 +526,7 @@ void CharacterController::update(float duration, Movement &movement) if(!mAnimation->isPlaying("torch")) mAnimation->play("torch", Priority_Torch, MWRender::Animation::Group_LeftArm, false, - "start", "stop", 0.0f, (~(size_t)0)); + 1.0f, "start", "stop", 0.0f, (~(size_t)0)); } else if(mAnimation->isPlaying("torch")) mAnimation->disable("torch"); @@ -583,7 +583,7 @@ void CharacterController::playGroup(const std::string &groupname, int mode, int mIdleState = CharState_SpecialIdle; mAnimation->play(groupname, Priority_Default, - MWRender::Animation::Group_All, false, + MWRender::Animation::Group_All, false, 1.0f, ((mode==2) ? "loop start" : "start"), "stop", 0.0f, count-1); } else if(mode == 0) @@ -631,7 +631,7 @@ void CharacterController::forceStateUpdate() mCurrentDeath = state->groupname; if(!mAnimation->getInfo(mCurrentDeath)) mAnimation->play(mCurrentDeath, Priority_Death, MWRender::Animation::Group_All, - false, "start", "stop", 0.0f, 0); + false, 1.0f, "start", "stop", 0.0f, 0); } } @@ -652,7 +652,7 @@ void CharacterController::kill() mCurrentDeath = state->groupname; if(mAnimation && !mAnimation->getInfo(mCurrentDeath)) mAnimation->play(mCurrentDeath, Priority_Death, MWRender::Animation::Group_All, - false, "start", "stop", 0.0f, 0); + false, 1.0f, "start", "stop", 0.0f, 0); } void CharacterController::resurrect() diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index f958b82860..0888d391b3 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -517,7 +517,7 @@ bool Animation::handleTextKey(AnimState &state, const std::string &groupname, co } -void Animation::play(const std::string &groupname, int priority, int groups, bool autodisable, const std::string &start, const std::string &stop, float startpoint, size_t loops) +void Animation::play(const std::string &groupname, int priority, int groups, bool autodisable, float speedmult, const std::string &start, const std::string &stop, float startpoint, size_t loops) { if(!mSkelBase) return; @@ -555,6 +555,7 @@ void Animation::play(const std::string &groupname, int priority, int groups, boo if(reset(state, (*iter)->mTextKeys, groupname, start, stop, startpoint)) { state.mSource = *iter; + state.mSpeedMult = speedmult; state.mLoopCount = loops; state.mPlaying = true; state.mPriority = priority; @@ -650,12 +651,13 @@ void Animation::resetActiveGroups() } -bool Animation::getInfo(const std::string &groupname, float *complete, std::string *start, std::string *stop) const +bool Animation::getInfo(const std::string &groupname, float *complete, float *speedmult, std::string *start, std::string *stop) const { AnimStateMap::const_iterator iter = mStates.find(groupname); if(iter == mStates.end()) { if(complete) *complete = 0.0f; + if(speedmult) *speedmult = 0.0f; if(start) *start = ""; if(stop) *stop = ""; return false; @@ -663,6 +665,7 @@ bool Animation::getInfo(const std::string &groupname, float *complete, std::stri if(complete) *complete = (iter->second.mTime - iter->second.mStartKey->first) / (iter->second.mStopKey->first - iter->second.mStartKey->first); + if(speedmult) *speedmult = iter->second.mSpeedMult; if(start) *start = iter->second.mStartKey->second.substr(groupname.size()+2); if(stop) *stop = iter->second.mStopKey->second.substr(groupname.size()+2); return true; @@ -687,7 +690,7 @@ Ogre::Vector3 Animation::runAnimation(float duration) while(stateiter != mStates.end()) { AnimState &state = stateiter->second; - float timepassed = duration; + float timepassed = duration * state.mSpeedMult; while(state.mPlaying) { float targetTime = state.mTime + timepassed; diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index f87fade556..4955acb3bd 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -66,6 +66,7 @@ protected: NifOgre::TextKeyMap::const_iterator mNextKey; float mTime; + float mSpeedMult; bool mPlaying; size_t mLoopCount; @@ -74,7 +75,7 @@ protected: int mGroups; bool mAutoDisable; - AnimState() : mTime(0.0f), mPlaying(false), mLoopCount(0), + AnimState() : mTime(0.0f), mSpeedMult(1.0f), mPlaying(false), mLoopCount(0), mPriority(0), mGroups(0), mAutoDisable(true) { } }; @@ -183,6 +184,7 @@ public: * \param groups Bone groups to play the animation on. * \param autodisable Automatically disable the animation when it stops * playing. + * \param speedmult Speed multiplier for the animation. * \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 @@ -192,7 +194,7 @@ public: * otherwise it will use "start" and "stop". */ void play(const std::string &groupname, int priority, int groups, bool autodisable, - const std::string &start, const std::string &stop, + float speedmult, const std::string &start, const std::string &stop, float startpoint, size_t loops); /** Returns true if the named animation group is playing. */ @@ -201,11 +203,12 @@ public: /** Gets info about the given animation group. * \param groupname Animation group to check. * \param complete Stores completion amount (0 = at start key, 0.5 = half way between start and stop keys), etc. + * \param speedmult Stores the animation speed multiplier * \param start Stores the start key * \param stop Stores the stop key * \return True if the animation is active, false otherwise. */ - bool getInfo(const std::string &groupname, float *complete=NULL, std::string *start=NULL, std::string *stop=NULL) const; + bool getInfo(const std::string &groupname, float *complete=NULL, float *speedmult=NULL, std::string *start=NULL, std::string *stop=NULL) const; /** Disables the specified animation group; * \param groupname Animation group to disable. diff --git a/apps/openmw/mwrender/characterpreview.cpp b/apps/openmw/mwrender/characterpreview.cpp index c6e6e158e7..88d8704451 100644 --- a/apps/openmw/mwrender/characterpreview.cpp +++ b/apps/openmw/mwrender/characterpreview.cpp @@ -177,7 +177,7 @@ namespace MWRender if(groupname != mCurrentAnimGroup) { mCurrentAnimGroup = groupname; - mAnimation->play(mCurrentAnimGroup, 1, Animation::Group_All, false, "start", "stop", 0.0f, 0); + mAnimation->play(mCurrentAnimGroup, 1, Animation::Group_All, false, 1.0f, "start", "stop", 0.0f, 0); } MWWorld::ContainerStoreIterator torch = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); @@ -185,7 +185,7 @@ namespace MWRender { if(!mAnimation->getInfo("torch")) mAnimation->play("torch", 2, MWRender::Animation::Group_LeftArm, false, - "start", "stop", 0.0f, (~(size_t)0)); + 1.0f, "start", "stop", 0.0f, ~0ul); } else if(mAnimation->getInfo("torch")) mAnimation->disable("torch"); @@ -215,7 +215,7 @@ namespace MWRender mAnimation->showWeapons(true); mCurrentAnimGroup = "inventoryhandtohand"; - mAnimation->play(mCurrentAnimGroup, 1, Animation::Group_All, false, "start", "stop", 0.0f, 0); + mAnimation->play(mCurrentAnimGroup, 1, Animation::Group_All, false, 1.0f, "start", "stop", 0.0f, 0); } // -------------------------------------------------------------------------------------------------- @@ -252,7 +252,7 @@ namespace MWRender void RaceSelectionPreview::onSetup () { - mAnimation->play("idle", 1, Animation::Group_All, false, "start", "stop", 0.0f, 0); + mAnimation->play("idle", 1, Animation::Group_All, false, 1.0f, "start", "stop", 0.0f, 0); updateCamera(); } diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index cd1eb823da..4d6f50ffd2 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -163,13 +163,13 @@ namespace MWWorld { if (!target.isEmpty()) MWMechanics::Security(getPlayer()).pickLock(target, item, resultMessage, resultSound); - anim->play("pickprobe", MWMechanics::Priority_Weapon, MWRender::Animation::Group_UpperBody, true, "start", "stop", 0.0, 0); + anim->play("pickprobe", MWMechanics::Priority_Weapon, MWRender::Animation::Group_UpperBody, true, 1.0f, "start", "stop", 0.0, 0); } else if (item.getTypeName() == typeid(ESM::Probe).name()) { if (!target.isEmpty()) MWMechanics::Security(getPlayer()).probeTrap(target, item, resultMessage, resultSound); - anim->play("pickprobe", MWMechanics::Priority_Weapon, MWRender::Animation::Group_UpperBody, true, "start", "stop", 0.0, 0); + anim->play("pickprobe", MWMechanics::Priority_Weapon, MWRender::Animation::Group_UpperBody, true, 1.0f, "start", "stop", 0.0, 0); } if (!resultMessage.empty())