1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-03-31 14:36:39 +00:00

Reset mPreviousAccumulatePosition when not accumulating to avoid an instant transition when resuming idle anims.

This commit is contained in:
Mads Buvik Sandvei 2023-12-03 13:06:09 +01:00
parent cedc5289d7
commit 81095686bf
7 changed files with 24 additions and 16 deletions

View file

@ -2446,10 +2446,11 @@ namespace MWMechanics
} }
} }
bool doMovementAccumulation = isMovementAnimationControlled();
osg::Vec3f movementFromAnimation osg::Vec3f movementFromAnimation
= mAnimation->runAnimation(mSkipAnim && !isScriptedAnimPlaying() ? 0.f : duration); = mAnimation->runAnimation(mSkipAnim && !isScriptedAnimPlaying() ? 0.f : duration, doMovementAccumulation);
if (mPtr.getClass().isActor() && isMovementAnimationControlled() && !isScriptedAnimPlaying()) if (mPtr.getClass().isActor() && doMovementAccumulation && !isScriptedAnimPlaying())
{ {
if (duration > 0.0f) if (duration > 0.0f)
movementFromAnimation /= duration; movementFromAnimation /= duration;

View file

@ -1178,8 +1178,11 @@ namespace MWRender
// starts and stops with Bip01 at the same position, totaling 0 movement. This allows us to accurately move // starts and stops with Bip01 at the same position, totaling 0 movement. This allows us to accurately move
// the character by just moving it from the position Bip01 was last frame to where it is this frame, without // the character by just moving it from the position Bip01 was last frame to where it is this frame, without
// needing to accumulate anything in-between. // needing to accumulate anything in-between.
position += offset - mPreviousPosition; if (mPreviousAccumulatePosition)
mPreviousPosition = offset; {
position += offset - mPreviousAccumulatePosition.value();
}
mPreviousAccumulatePosition = offset;
} }
else else
{ {
@ -1190,8 +1193,11 @@ namespace MWRender
} }
} }
osg::Vec3f Animation::runAnimation(float duration) osg::Vec3f Animation::runAnimation(float duration, bool accumulateMovement)
{ {
if (!accumulateMovement)
mPreviousAccumulatePosition = std::nullopt;
osg::Vec3f movement(0.f, 0.f, 0.f); osg::Vec3f movement(0.f, 0.f, 0.f);
AnimStateMap::iterator stateiter = mStates.begin(); AnimStateMap::iterator stateiter = mStates.begin();
while (stateiter != mStates.end()) while (stateiter != mStates.end())
@ -1215,13 +1221,13 @@ namespace MWRender
float targetTime = state.getTime() + timepassed; float targetTime = state.getTime() + timepassed;
if (textkey == textkeys.end() || textkey->first > targetTime) if (textkey == textkeys.end() || textkey->first > targetTime)
{ {
if (mAccumCtrl && state.mTime == mAnimationTimePtr[0]->getTimePtr()) if (accumulateMovement && mAccumCtrl && state.mTime == mAnimationTimePtr[0]->getTimePtr())
updatePosition(state.getTime(), targetTime, movement, hasMovement); updatePosition(state.getTime(), targetTime, movement, hasMovement);
state.setTime(std::min(targetTime, state.mStopTime)); state.setTime(std::min(targetTime, state.mStopTime));
} }
else else
{ {
if (mAccumCtrl && state.mTime == mAnimationTimePtr[0]->getTimePtr()) if (accumulateMovement && mAccumCtrl && state.mTime == mAnimationTimePtr[0]->getTimePtr())
updatePosition(state.getTime(), textkey->first, movement, hasMovement); updatePosition(state.getTime(), textkey->first, movement, hasMovement);
state.setTime(textkey->first); state.setTime(textkey->first);
} }
@ -1305,7 +1311,7 @@ namespace MWRender
} }
if (mResetAccumRootCallback) if (accumulateMovement && mResetAccumRootCallback)
mResetAccumRootCallback->accumulate(movement, duration); mResetAccumRootCallback->accumulate(movement, duration);
return movement; return movement;
} }

View file

@ -14,6 +14,7 @@
#include <unordered_map> #include <unordered_map>
#include <unordered_set> #include <unordered_set>
#include <vector> #include <vector>
#include <optional>
namespace ESM namespace ESM
{ {
@ -265,6 +266,7 @@ namespace MWRender
Resource::ResourceSystem* mResourceSystem; Resource::ResourceSystem* mResourceSystem;
osg::Vec3f mAccumulate; osg::Vec3f mAccumulate;
std::optional<osg::Vec3f> mPreviousAccumulatePosition;
TextKeyListener* mTextKeyListener; TextKeyListener* mTextKeyListener;
@ -276,7 +278,6 @@ namespace MWRender
float mUpperBodyYawRadians; float mUpperBodyYawRadians;
float mLegsYawRadians; float mLegsYawRadians;
float mBodyPitchRadians; float mBodyPitchRadians;
osg::Vec3f mPreviousPosition;
osg::ref_ptr<RotateController> addRotateController(std::string_view bone); osg::ref_ptr<RotateController> addRotateController(std::string_view bone);
@ -465,7 +466,7 @@ namespace MWRender
/** Retrieves the velocity (in units per second) that the animation will move. */ /** Retrieves the velocity (in units per second) that the animation will move. */
float getVelocity(std::string_view groupname) const; float getVelocity(std::string_view groupname) const;
virtual osg::Vec3f runAnimation(float duration); virtual osg::Vec3f runAnimation(float duration, bool accumulateMovement = false);
void setLoopingEnabled(std::string_view groupname, bool enabled); void setLoopingEnabled(std::string_view groupname, bool enabled);

View file

@ -258,9 +258,9 @@ namespace MWRender
WeaponAnimation::addControllers(mNodeMap, mActiveControllers, mObjectRoot.get()); WeaponAnimation::addControllers(mNodeMap, mActiveControllers, mObjectRoot.get());
} }
osg::Vec3f CreatureWeaponAnimation::runAnimation(float duration) osg::Vec3f CreatureWeaponAnimation::runAnimation(float duration, bool accumulateMovement)
{ {
osg::Vec3f ret = Animation::runAnimation(duration); osg::Vec3f ret = Animation::runAnimation(duration, accumulateMovement);
WeaponAnimation::configureControllers(mPtr.getRefData().getPosition().rot[0] + getBodyPitchRadians()); WeaponAnimation::configureControllers(mPtr.getRefData().getPosition().rot[0] + getBodyPitchRadians());

View file

@ -59,7 +59,7 @@ namespace MWRender
void addControllers() override; void addControllers() override;
osg::Vec3f runAnimation(float duration) override; osg::Vec3f runAnimation(float duration, bool accumulateMovement = false) override;
/// A relative factor (0-1) that decides if and how much the skeleton should be pitched /// A relative factor (0-1) that decides if and how much the skeleton should be pitched
/// to indicate the facing orientation of the character. /// to indicate the facing orientation of the character.

View file

@ -693,9 +693,9 @@ namespace MWRender
return std::make_unique<PartHolder>(attached); return std::make_unique<PartHolder>(attached);
} }
osg::Vec3f NpcAnimation::runAnimation(float timepassed) osg::Vec3f NpcAnimation::runAnimation(float timepassed, bool accumulateMovement)
{ {
osg::Vec3f ret = Animation::runAnimation(timepassed); osg::Vec3f ret = Animation::runAnimation(timepassed, accumulateMovement);
mHeadAnimationTime->update(timepassed); mHeadAnimationTime->update(timepassed);

View file

@ -130,7 +130,7 @@ namespace MWRender
void setWeaponGroup(const std::string& group, bool relativeDuration) override; void setWeaponGroup(const std::string& group, bool relativeDuration) override;
osg::Vec3f runAnimation(float timepassed) override; osg::Vec3f runAnimation(float timepassed, bool accumulateMovement = false) override;
/// A relative factor (0-1) that decides if and how much the skeleton should be pitched /// A relative factor (0-1) that decides if and how much the skeleton should be pitched
/// to indicate the facing orientation of the character. /// to indicate the facing orientation of the character.