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

macos_ci_fix
Mads Buvik Sandvei 1 year ago
parent cedc5289d7
commit 81095686bf

@ -2446,10 +2446,11 @@ namespace MWMechanics
}
}
bool doMovementAccumulation = isMovementAnimationControlled();
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)
movementFromAnimation /= duration;

@ -1178,8 +1178,11 @@ namespace MWRender
// 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
// needing to accumulate anything in-between.
position += offset - mPreviousPosition;
mPreviousPosition = offset;
if (mPreviousAccumulatePosition)
{
position += offset - mPreviousAccumulatePosition.value();
}
mPreviousAccumulatePosition = offset;
}
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);
AnimStateMap::iterator stateiter = mStates.begin();
while (stateiter != mStates.end())
@ -1215,13 +1221,13 @@ namespace MWRender
float targetTime = state.getTime() + timepassed;
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);
state.setTime(std::min(targetTime, state.mStopTime));
}
else
{
if (mAccumCtrl && state.mTime == mAnimationTimePtr[0]->getTimePtr())
if (accumulateMovement && mAccumCtrl && state.mTime == mAnimationTimePtr[0]->getTimePtr())
updatePosition(state.getTime(), textkey->first, movement, hasMovement);
state.setTime(textkey->first);
}
@ -1305,7 +1311,7 @@ namespace MWRender
}
if (mResetAccumRootCallback)
if (accumulateMovement && mResetAccumRootCallback)
mResetAccumRootCallback->accumulate(movement, duration);
return movement;
}

@ -14,6 +14,7 @@
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <optional>
namespace ESM
{
@ -265,6 +266,7 @@ namespace MWRender
Resource::ResourceSystem* mResourceSystem;
osg::Vec3f mAccumulate;
std::optional<osg::Vec3f> mPreviousAccumulatePosition;
TextKeyListener* mTextKeyListener;
@ -276,7 +278,6 @@ namespace MWRender
float mUpperBodyYawRadians;
float mLegsYawRadians;
float mBodyPitchRadians;
osg::Vec3f mPreviousPosition;
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. */
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);

@ -258,9 +258,9 @@ namespace MWRender
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());

@ -59,7 +59,7 @@ namespace MWRender
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
/// to indicate the facing orientation of the character.

@ -693,9 +693,9 @@ namespace MWRender
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);

@ -130,7 +130,7 @@ namespace MWRender
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
/// to indicate the facing orientation of the character.

Loading…
Cancel
Save