diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index c9b2489848..129206f519 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -1479,6 +1479,8 @@ bool CharacterController::updateWeaponState() } } + mAnimation->setAccurateAiming(mUpperBodyState > UpperCharState_WeapEquiped); + return forcestateupdate; } diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index 1e46cc71a5..5aaa4071b8 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -439,6 +439,7 @@ public: virtual void setHeadYaw(float yawRadians); virtual float getHeadPitch() const; virtual float getHeadYaw() const; + virtual void setAccurateAiming(bool enabled) {} private: Animation(const Animation&); diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 0b3838a33b..8156712661 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -281,7 +281,9 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr par mShowWeapons(false), mShowCarriedLeft(true), mNpcType(Type_Normal), - mSoundsDisabled(disableSounds) + mSoundsDisabled(disableSounds), + mAccurateAiming(false), + mAimingFactor(0.f) { mNpc = mPtr.get()->mBase; @@ -726,7 +728,14 @@ osg::Vec3f NpcAnimation::runAnimation(float timepassed) if (mFirstPersonNeckController) { - mFirstPersonNeckController->setRotate(osg::Quat(mPtr.getRefData().getPosition().rot[0], osg::Vec3f(-1,0,0))); + if (mAccurateAiming) + mAimingFactor = 1.f; + else + mAimingFactor = std::max(0.f, mAimingFactor - timepassed * 0.5f); + + float rotateFactor = 0.75f + 0.25f * mAimingFactor; + + mFirstPersonNeckController->setRotate(osg::Quat(mPtr.getRefData().getPosition().rot[0] * rotateFactor, osg::Vec3f(-1,0,0))); mFirstPersonNeckController->setOffset(mFirstPersonOffset); } @@ -1072,4 +1081,9 @@ void NpcAnimation::updatePtr(const MWWorld::Ptr &updated) mHeadAnimationTime->updatePtr(updated); } +void NpcAnimation::setAccurateAiming(bool enabled) +{ + mAccurateAiming = enabled; +} + } diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index b4272226d9..2289703c8f 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -67,6 +67,9 @@ private: bool mSoundsDisabled; + bool mAccurateAiming; + float mAimingFactor; + void updateNpcBase(); PartHolderPtr insertBoundedPart(const std::string &model, const std::string &bonename, @@ -104,6 +107,10 @@ public: virtual void enableHeadAnimation(bool enable); + /// 1: the first person meshes follow the camera's rotation completely + /// 0: the first person meshes follow the camera with a reduced factor, so you can look down at your own hands + virtual void setAccurateAiming(bool enabled); + virtual void setWeaponGroup(const std::string& group); virtual osg::Vec3f runAnimation(float timepassed);