Add a speed multiplier to the animation state

This commit is contained in:
Chris Robinson 2013-07-16 00:43:31 -07:00
parent 3a1facefdf
commit f296d13c20
5 changed files with 29 additions and 23 deletions

View file

@ -166,7 +166,7 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat
mAnimation->disable(mCurrentIdle); mAnimation->disable(mCurrentIdle);
mCurrentIdle = idle; mCurrentIdle = idle;
mAnimation->play(mCurrentIdle, Priority_Default, MWRender::Animation::Group_All, false, 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) if(force || movement != mMovementState)
@ -208,7 +208,7 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat
mCurrentMovement = movement; mCurrentMovement = movement;
if(!mCurrentMovement.empty()) if(!mCurrentMovement.empty())
mAnimation->play(mCurrentMovement, Priority_Movement, movegroup, false, 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; mCurrentDeath = state->groupname;
mAnimation->play(mCurrentDeath, Priority_Death, MWRender::Animation::Group_All, 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, mAnimation->play(mAnimQueue.front().first, Priority_Default,
MWRender::Animation::Group_All, false, 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, mAnimation->play(mAnimQueue.front().first, Priority_Default,
MWRender::Animation::Group_All, false, 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); getWeaponGroup(mWeaponType, weapgroup);
mAnimation->play(weapgroup, Priority_Weapon, mAnimation->play(weapgroup, Priority_Weapon,
MWRender::Animation::Group_UpperBody, true, MWRender::Animation::Group_UpperBody, true,
"unequip start", "unequip stop", 0.0f, 0); 1.0f, "unequip start", "unequip stop", 0.0f, 0);
} }
else else
{ {
@ -502,7 +502,7 @@ void CharacterController::update(float duration, Movement &movement)
mAnimation->showWeapons(false); mAnimation->showWeapons(false);
mAnimation->play(weapgroup, Priority_Weapon, mAnimation->play(weapgroup, Priority_Weapon,
MWRender::Animation::Group_UpperBody, true, MWRender::Animation::Group_UpperBody, true,
"equip start", "equip stop", 0.0f, 0); 1.0f, "equip start", "equip stop", 0.0f, 0);
} }
mWeaponType = weaptype; mWeaponType = weaptype;
@ -526,7 +526,7 @@ void CharacterController::update(float duration, Movement &movement)
if(!mAnimation->isPlaying("torch")) if(!mAnimation->isPlaying("torch"))
mAnimation->play("torch", Priority_Torch, mAnimation->play("torch", Priority_Torch,
MWRender::Animation::Group_LeftArm, false, 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")) else if(mAnimation->isPlaying("torch"))
mAnimation->disable("torch"); mAnimation->disable("torch");
@ -583,7 +583,7 @@ void CharacterController::playGroup(const std::string &groupname, int mode, int
mIdleState = CharState_SpecialIdle; mIdleState = CharState_SpecialIdle;
mAnimation->play(groupname, Priority_Default, 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); ((mode==2) ? "loop start" : "start"), "stop", 0.0f, count-1);
} }
else if(mode == 0) else if(mode == 0)
@ -631,7 +631,7 @@ void CharacterController::forceStateUpdate()
mCurrentDeath = state->groupname; mCurrentDeath = state->groupname;
if(!mAnimation->getInfo(mCurrentDeath)) if(!mAnimation->getInfo(mCurrentDeath))
mAnimation->play(mCurrentDeath, Priority_Death, MWRender::Animation::Group_All, 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; mCurrentDeath = state->groupname;
if(mAnimation && !mAnimation->getInfo(mCurrentDeath)) if(mAnimation && !mAnimation->getInfo(mCurrentDeath))
mAnimation->play(mCurrentDeath, Priority_Death, MWRender::Animation::Group_All, 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() void CharacterController::resurrect()

View file

@ -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) if(!mSkelBase)
return; 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)) if(reset(state, (*iter)->mTextKeys, groupname, start, stop, startpoint))
{ {
state.mSource = *iter; state.mSource = *iter;
state.mSpeedMult = speedmult;
state.mLoopCount = loops; state.mLoopCount = loops;
state.mPlaying = true; state.mPlaying = true;
state.mPriority = priority; 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); AnimStateMap::const_iterator iter = mStates.find(groupname);
if(iter == mStates.end()) if(iter == mStates.end())
{ {
if(complete) *complete = 0.0f; if(complete) *complete = 0.0f;
if(speedmult) *speedmult = 0.0f;
if(start) *start = ""; if(start) *start = "";
if(stop) *stop = ""; if(stop) *stop = "";
return false; 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) / if(complete) *complete = (iter->second.mTime - iter->second.mStartKey->first) /
(iter->second.mStopKey->first - 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(start) *start = iter->second.mStartKey->second.substr(groupname.size()+2);
if(stop) *stop = iter->second.mStopKey->second.substr(groupname.size()+2); if(stop) *stop = iter->second.mStopKey->second.substr(groupname.size()+2);
return true; return true;
@ -687,7 +690,7 @@ Ogre::Vector3 Animation::runAnimation(float duration)
while(stateiter != mStates.end()) while(stateiter != mStates.end())
{ {
AnimState &state = stateiter->second; AnimState &state = stateiter->second;
float timepassed = duration; float timepassed = duration * state.mSpeedMult;
while(state.mPlaying) while(state.mPlaying)
{ {
float targetTime = state.mTime + timepassed; float targetTime = state.mTime + timepassed;

View file

@ -66,6 +66,7 @@ protected:
NifOgre::TextKeyMap::const_iterator mNextKey; NifOgre::TextKeyMap::const_iterator mNextKey;
float mTime; float mTime;
float mSpeedMult;
bool mPlaying; bool mPlaying;
size_t mLoopCount; size_t mLoopCount;
@ -74,7 +75,7 @@ protected:
int mGroups; int mGroups;
bool mAutoDisable; 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) mPriority(0), mGroups(0), mAutoDisable(true)
{ } { }
}; };
@ -183,6 +184,7 @@ public:
* \param groups Bone groups to play the animation on. * \param groups Bone groups to play the animation on.
* \param autodisable Automatically disable the animation when it stops * \param autodisable Automatically disable the animation when it stops
* playing. * playing.
* \param speedmult Speed multiplier for the animation.
* \param start Key marker from which to start. * \param start Key marker from which to start.
* \param stop Key marker to stop at. * \param stop Key marker to stop at.
* \param startpoint How far in between the two markers to start. 0 starts * \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". * otherwise it will use "start" and "stop".
*/ */
void play(const std::string &groupname, int priority, int groups, bool autodisable, 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); float startpoint, size_t loops);
/** Returns true if the named animation group is playing. */ /** Returns true if the named animation group is playing. */
@ -201,11 +203,12 @@ public:
/** Gets info about the given animation group. /** Gets info about the given animation group.
* \param groupname Animation group to check. * \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 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 start Stores the start key
* \param stop Stores the stop key * \param stop Stores the stop key
* \return True if the animation is active, false otherwise. * \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; /** Disables the specified animation group;
* \param groupname Animation group to disable. * \param groupname Animation group to disable.

View file

@ -177,7 +177,7 @@ namespace MWRender
if(groupname != mCurrentAnimGroup) if(groupname != mCurrentAnimGroup)
{ {
mCurrentAnimGroup = groupname; 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); MWWorld::ContainerStoreIterator torch = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft);
@ -185,7 +185,7 @@ namespace MWRender
{ {
if(!mAnimation->getInfo("torch")) if(!mAnimation->getInfo("torch"))
mAnimation->play("torch", 2, MWRender::Animation::Group_LeftArm, false, 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")) else if(mAnimation->getInfo("torch"))
mAnimation->disable("torch"); mAnimation->disable("torch");
@ -215,7 +215,7 @@ namespace MWRender
mAnimation->showWeapons(true); mAnimation->showWeapons(true);
mCurrentAnimGroup = "inventoryhandtohand"; 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 () 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(); updateCamera();
} }

View file

@ -163,13 +163,13 @@ namespace MWWorld
{ {
if (!target.isEmpty()) if (!target.isEmpty())
MWMechanics::Security(getPlayer()).pickLock(target, item, resultMessage, resultSound); 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()) else if (item.getTypeName() == typeid(ESM::Probe).name())
{ {
if (!target.isEmpty()) if (!target.isEmpty())
MWMechanics::Security(getPlayer()).probeTrap(target, item, resultMessage, resultSound); 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()) if (!resultMessage.empty())