mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 23:53:52 +00:00
Emulate vanilla animation loops more closely
This commit is contained in:
parent
b332a13b4e
commit
bf9dc45b2b
3 changed files with 83 additions and 40 deletions
|
@ -1533,6 +1533,9 @@ void CharacterController::update(float duration)
|
||||||
|
|
||||||
updateMagicEffects();
|
updateMagicEffects();
|
||||||
|
|
||||||
|
if(mAnimQueue.size() > 1 && (mAnimation->getLoopingEnabled(mAnimQueue.front().mGroup) == true))
|
||||||
|
mAnimation->setLoopingEnabled(mAnimQueue.front().mGroup, false);
|
||||||
|
|
||||||
if(!cls.isActor())
|
if(!cls.isActor())
|
||||||
{
|
{
|
||||||
if(mAnimQueue.size() > 1)
|
if(mAnimQueue.size() > 1)
|
||||||
|
@ -2009,8 +2012,26 @@ bool CharacterController::playGroup(const std::string &groupname, int mode, int
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!mAnimQueue.empty() && mAnimQueue.front().mGroup == groupname && isAnimPlaying(mAnimQueue.front().mGroup))
|
// If the given animation is a looped animation, is already playing
|
||||||
|
// and has not yet reached its Loop Stop key, make it the only animation
|
||||||
|
// in the queue, and retain the loop count from the animation that was
|
||||||
|
// already playing. This emulates observed behavior from the original
|
||||||
|
// engine and allows banners to animate correctly.
|
||||||
|
if (!mAnimQueue.empty() && mAnimQueue.front().mGroup == groupname &&
|
||||||
|
mAnimation->getTextKeyTime(mAnimQueue.front().mGroup+": loop start") >= 0)
|
||||||
|
{
|
||||||
|
float endOfLoop = mAnimation->getTextKeyTime(mAnimQueue.front().mGroup+": loop stop");
|
||||||
|
|
||||||
|
if (endOfLoop < 0) // if no Loop Stop key was found, use the Stop key
|
||||||
|
endOfLoop = mAnimation->getTextKeyTime(mAnimQueue.front().mGroup+": stop");
|
||||||
|
|
||||||
|
if (endOfLoop > 0 && (mAnimation->getCurrentTime(mAnimQueue.front().mGroup) < endOfLoop))
|
||||||
|
{
|
||||||
|
mAnimation->setLoopingEnabled(mAnimQueue.front().mGroup, true);
|
||||||
|
mAnimQueue.resize(1);
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
count = std::max(count, 1);
|
count = std::max(count, 1);
|
||||||
|
|
||||||
|
@ -2035,8 +2056,6 @@ bool CharacterController::playGroup(const std::string &groupname, int mode, int
|
||||||
}
|
}
|
||||||
else if(mode == 0)
|
else if(mode == 0)
|
||||||
{
|
{
|
||||||
if (!mAnimQueue.empty())
|
|
||||||
mAnimation->stopLooping(mAnimQueue.front().mGroup);
|
|
||||||
mAnimQueue.resize(1);
|
mAnimQueue.resize(1);
|
||||||
mAnimQueue.push_back(entry);
|
mAnimQueue.push_back(entry);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1023,9 +1023,8 @@ namespace MWRender
|
||||||
{
|
{
|
||||||
float targetTime;
|
float targetTime;
|
||||||
|
|
||||||
if(state.getTime() >= state.mLoopStopTime && state.mLoopCount > 0)
|
if (state.getTime() < state.mLoopStopTime || state.mLoopCount == 0)
|
||||||
goto handle_loop;
|
{
|
||||||
|
|
||||||
targetTime = state.getTime() + timepassed;
|
targetTime = state.getTime() + timepassed;
|
||||||
if(textkey == textkeys.end() || textkey->first > targetTime)
|
if(textkey == textkeys.end() || textkey->first > targetTime)
|
||||||
{
|
{
|
||||||
|
@ -1048,10 +1047,14 @@ namespace MWRender
|
||||||
handleTextKey(state, stateiter->first, textkey, textkeys);
|
handleTextKey(state, stateiter->first, textkey, textkeys);
|
||||||
++textkey;
|
++textkey;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(state.getTime() >= state.mLoopStopTime && state.mLoopCount > 0)
|
if(state.getTime() >= state.mLoopStopTime)
|
||||||
|
{
|
||||||
|
if (!state.mLoopingEnabled)
|
||||||
|
state.mLoopCount = 0;
|
||||||
|
else if (state.mLoopCount > 0)
|
||||||
{
|
{
|
||||||
handle_loop:
|
|
||||||
state.mLoopCount--;
|
state.mLoopCount--;
|
||||||
state.setTime(state.mLoopStartTime);
|
state.setTime(state.mLoopStartTime);
|
||||||
state.mPlaying = true;
|
state.mPlaying = true;
|
||||||
|
@ -1066,6 +1069,7 @@ namespace MWRender
|
||||||
if(state.getTime() >= state.mLoopStopTime)
|
if(state.getTime() >= state.mLoopStopTime)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(timepassed <= 0.0f)
|
if(timepassed <= 0.0f)
|
||||||
break;
|
break;
|
||||||
|
@ -1095,6 +1099,21 @@ namespace MWRender
|
||||||
return movement;
|
return movement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Animation::setLoopingEnabled(const std::string &groupname, bool enabled)
|
||||||
|
{
|
||||||
|
AnimStateMap::iterator state(mStates.find(groupname));
|
||||||
|
if(state != mStates.end())
|
||||||
|
state->second.mLoopingEnabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Animation::getLoopingEnabled(const std::string &groupname) const
|
||||||
|
{
|
||||||
|
AnimStateMap::const_iterator state(mStates.find(groupname));
|
||||||
|
if(state != mStates.end())
|
||||||
|
return state->second.mLoopingEnabled;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void Animation::setObjectRoot(const std::string &model, bool forceskeleton, bool baseonly, bool isCreature)
|
void Animation::setObjectRoot(const std::string &model, bool forceskeleton, bool baseonly, bool isCreature)
|
||||||
{
|
{
|
||||||
osg::ref_ptr<osg::StateSet> previousStateset;
|
osg::ref_ptr<osg::StateSet> previousStateset;
|
||||||
|
|
|
@ -183,6 +183,7 @@ protected:
|
||||||
float mSpeedMult;
|
float mSpeedMult;
|
||||||
|
|
||||||
bool mPlaying;
|
bool mPlaying;
|
||||||
|
bool mLoopingEnabled;
|
||||||
size_t mLoopCount;
|
size_t mLoopCount;
|
||||||
|
|
||||||
AnimPriority mPriority;
|
AnimPriority mPriority;
|
||||||
|
@ -190,8 +191,8 @@ protected:
|
||||||
bool mAutoDisable;
|
bool mAutoDisable;
|
||||||
|
|
||||||
AnimState() : mStartTime(0.0f), mLoopStartTime(0.0f), mLoopStopTime(0.0f), mStopTime(0.0f),
|
AnimState() : mStartTime(0.0f), mLoopStartTime(0.0f), mLoopStopTime(0.0f), mStopTime(0.0f),
|
||||||
mTime(new float), mSpeedMult(1.0f), mPlaying(false), mLoopCount(0),
|
mTime(new float), mSpeedMult(1.0f), mPlaying(false), mLoopingEnabled(true),
|
||||||
mPriority(0), mBlendMask(0), mAutoDisable(true)
|
mLoopCount(0), mPriority(0), mBlendMask(0), mAutoDisable(true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
~AnimState();
|
~AnimState();
|
||||||
|
@ -432,6 +433,10 @@ public:
|
||||||
|
|
||||||
virtual osg::Vec3f runAnimation(float duration);
|
virtual osg::Vec3f runAnimation(float duration);
|
||||||
|
|
||||||
|
void setLoopingEnabled(const std::string &groupname, bool enabled);
|
||||||
|
|
||||||
|
bool getLoopingEnabled(const std::string &groupname) const;
|
||||||
|
|
||||||
/// This is typically called as part of runAnimation, but may be called manually if needed.
|
/// This is typically called as part of runAnimation, but may be called manually if needed.
|
||||||
void updateEffects(float duration);
|
void updateEffects(float duration);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue