From ddbd87e2a1af1b0f4a13c3c91acb558193cd8494 Mon Sep 17 00:00:00 2001 From: Sam Hellawell Date: Thu, 4 Jul 2024 03:12:06 +0100 Subject: [PATCH] Fix blending with additional offsets (sneaking issue) --- apps/openmw/mwrender/animblendcontroller.cpp | 24 +++++++++++++++++++- apps/openmw/mwrender/rotatecontroller.hpp | 10 ++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwrender/animblendcontroller.cpp b/apps/openmw/mwrender/animblendcontroller.cpp index 412c83d89a..8c40cd441b 100644 --- a/apps/openmw/mwrender/animblendcontroller.cpp +++ b/apps/openmw/mwrender/animblendcontroller.cpp @@ -1,4 +1,5 @@ #include "animblendcontroller.hpp" +#include "rotatecontroller.hpp" #include @@ -308,10 +309,31 @@ namespace MWRender { mBlendTrigger = false; mBlendStartTime = time; - // Nif mRotation is used here because it's unaffected by the side-effects of RotationController + + // Nif mRotationScale is used here because it's unaffected by the side-effects of RotationController mBlendStartRot = node->mRotationScale.toOsgMatrix().getRotate(); mBlendStartTrans = node->getMatrix().getTrans(); mBlendStartScale = node->mScale; + + // Subtract any rotate controller's offset from start transform (if it appears after this callback) + // this is required otherwise the blend start will be with an offset, then offset could be applied again + // fixes an issue with camera jumping during first person sneak jumping camera + osg::Callback* updateCb = node->getUpdateCallback()->getNestedCallback(); + while (updateCb) + { + MWRender::RotateController* rotateController = dynamic_cast(updateCb); + if (rotateController) + { + const osg::Quat rotate = rotateController->getRotate(); + const osg::Vec3f offset = rotateController->getOffset(); + const osg::Quat worldOrient = rotateController->getWorldOrientation(node) * rotate.inverse(); + const osg::Quat worldOrientInverse = worldOrient.inverse(); + + mBlendStartTrans -= worldOrientInverse * offset; + } + + updateCb = updateCb->getNestedCallback(); + } } calculateInterpFactor(time); diff --git a/apps/openmw/mwrender/rotatecontroller.hpp b/apps/openmw/mwrender/rotatecontroller.hpp index 3c7e130d98..143585d039 100644 --- a/apps/openmw/mwrender/rotatecontroller.hpp +++ b/apps/openmw/mwrender/rotatecontroller.hpp @@ -20,10 +20,20 @@ namespace MWRender public: RotateController(osg::Node* relativeTo); + osg::Quat getWorldOrientation(osg::Node* node); + void setEnabled(bool enabled); void setOffset(const osg::Vec3f& offset); void setRotate(const osg::Quat& rotate); + const osg::Vec3f getOffset() const { + return mOffset; + } + + const osg::Quat getRotate() const { + return mRotate; + } + void operator()(osg::MatrixTransform* node, osg::NodeVisitor* nv); protected: