From 81095686bf42ffbf33e447e8d9167cbc7ad0b1bc Mon Sep 17 00:00:00 2001 From: Mads Buvik Sandvei Date: Sun, 3 Dec 2023 13:06:09 +0100 Subject: [PATCH] Reset mPreviousAccumulatePosition when not accumulating to avoid an instant transition when resuming idle anims. --- apps/openmw/mwmechanics/character.cpp | 5 +++-- apps/openmw/mwrender/animation.cpp | 18 ++++++++++++------ apps/openmw/mwrender/animation.hpp | 5 +++-- apps/openmw/mwrender/creatureanimation.cpp | 4 ++-- apps/openmw/mwrender/creatureanimation.hpp | 2 +- apps/openmw/mwrender/npcanimation.cpp | 4 ++-- apps/openmw/mwrender/npcanimation.hpp | 2 +- 7 files changed, 24 insertions(+), 16 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 9a9f62f9ac..2ef3479cd9 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -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; diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index b9d6759dc7..cb51bcd00f 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -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; } diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index 990910fc50..0e748180e8 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -14,6 +14,7 @@ #include #include #include +#include namespace ESM { @@ -265,6 +266,7 @@ namespace MWRender Resource::ResourceSystem* mResourceSystem; osg::Vec3f mAccumulate; + std::optional mPreviousAccumulatePosition; TextKeyListener* mTextKeyListener; @@ -276,7 +278,6 @@ namespace MWRender float mUpperBodyYawRadians; float mLegsYawRadians; float mBodyPitchRadians; - osg::Vec3f mPreviousPosition; osg::ref_ptr 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); diff --git a/apps/openmw/mwrender/creatureanimation.cpp b/apps/openmw/mwrender/creatureanimation.cpp index 7767520715..65f48f5ade 100644 --- a/apps/openmw/mwrender/creatureanimation.cpp +++ b/apps/openmw/mwrender/creatureanimation.cpp @@ -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()); diff --git a/apps/openmw/mwrender/creatureanimation.hpp b/apps/openmw/mwrender/creatureanimation.hpp index 05235e5191..9ff3d55375 100644 --- a/apps/openmw/mwrender/creatureanimation.hpp +++ b/apps/openmw/mwrender/creatureanimation.hpp @@ -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. diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 469978e6eb..951d16aefe 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -693,9 +693,9 @@ namespace MWRender return std::make_unique(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); diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index a03ee28f3a..0c2d67db86 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -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.