From 9f850b6ffcedaa946251a5551cca16992e7731f3 Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Sat, 18 Jul 2020 11:48:46 +0200 Subject: [PATCH] Move deferred rotation logic from renderingmanager.cpp to camera.cpp --- apps/openmw/mwrender/camera.cpp | 69 ++++++++++++++++++++++- apps/openmw/mwrender/camera.hpp | 9 +++ apps/openmw/mwrender/renderingmanager.cpp | 55 +----------------- apps/openmw/mwrender/renderingmanager.hpp | 8 --- apps/openmw/mwworld/worldimp.cpp | 4 +- 5 files changed, 81 insertions(+), 64 deletions(-) diff --git a/apps/openmw/mwrender/camera.cpp b/apps/openmw/mwrender/camera.cpp index 16deed8783..877cb7570b 100644 --- a/apps/openmw/mwrender/camera.cpp +++ b/apps/openmw/mwrender/camera.cpp @@ -13,6 +13,7 @@ #include "../mwworld/refdata.hpp" #include "../mwmechanics/drawstate.hpp" +#include "../mwmechanics/movement.hpp" #include "../mwmechanics/npcstats.hpp" #include "npcanimation.hpp" @@ -72,7 +73,9 @@ namespace MWRender mSmoothedSpeed(0.f), mZoomOutWhenMoveCoef(Settings::Manager::getFloat("zoom out when move coef", "Camera")), mDynamicCameraDistanceEnabled(false), - mShowCrosshairInThirdPersonMode(false) + mShowCrosshairInThirdPersonMode(false), + mDeferredRotation(osg::Vec3f()), + mDeferredRotationDisabled(false) { mCameraDistance = mBaseCameraDistance; @@ -269,7 +272,10 @@ namespace MWRender void Camera::allowVanityMode(bool allow) { if (!allow && mMode == Mode::Vanity) + { + disableDeferredPreviewRotation(); toggleVanityMode(false); + } mVanityAllowed = allow; } @@ -290,6 +296,8 @@ namespace MWRender if ((mMode == Mode::Vanity) == enable) return true; mMode = enable ? Mode::Vanity : Mode::Normal; + if (!enable) + calculateDeferredRotation(); processViewChange(); return true; @@ -304,6 +312,8 @@ namespace MWRender return; mMode = enable ? Mode::Preview : Mode::Normal; + if (!enable) + calculateDeferredRotation(); processViewChange(); } @@ -411,4 +421,61 @@ namespace MWRender rotateCamera(getPitch(), getYaw(), false); } + void Camera::applyDeferredPreviewRotationToPlayer(float dt) + { + if (isVanityOrPreviewModeEnabled() || mTrackingPtr.isEmpty()) + return; + + osg::Vec3f rot = mDeferredRotation; + float delta = rot.normalize(); + delta = std::min(delta, (delta + 1.f) * 3 * dt); + rot *= delta; + mDeferredRotation -= rot; + + auto& movement = mTrackingPtr.getClass().getMovementSettings(mTrackingPtr); + movement.mRotation[0] += rot.x(); + movement.mRotation[1] += rot.y(); + movement.mRotation[2] += rot.z(); + if (std::abs(mDeferredRotation.z()) > 0.0001) + { + float s = std::sin(mDeferredRotation.z()); + float c = std::cos(mDeferredRotation.z()); + float x = movement.mPosition[0]; + float y = movement.mPosition[1]; + movement.mPosition[0] = x * c + y * s; + movement.mPosition[1] = x * -s + y * c; + } + } + + void Camera::rotateCameraToTrackingPtr() + { + setPitch(-mTrackingPtr.getRefData().getPosition().rot[0] - mDeferredRotation.x()); + setYaw(-mTrackingPtr.getRefData().getPosition().rot[2] - mDeferredRotation.z()); + } + + void Camera::calculateDeferredRotation() + { + MWWorld::Ptr ptr = mTrackingPtr; + if (isVanityOrPreviewModeEnabled() || ptr.isEmpty()) + return; + if (isFirstPerson() || mDeferredRotationDisabled) + { + mDeferredRotationDisabled = false; + mDeferredRotation = osg::Vec3f(); + rotateCameraToTrackingPtr(); + return; + } + + mDeferredRotation.x() = -ptr.getRefData().getPosition().rot[0] - mPitch; + mDeferredRotation.z() = -ptr.getRefData().getPosition().rot[2] - mYaw; + if (mDeferredRotation.x() > osg::PI) + mDeferredRotation.x() -= 2 * osg::PI; + if (mDeferredRotation.x() < -osg::PI) + mDeferredRotation.x() += 2 * osg::PI; + if (mDeferredRotation.z() > osg::PI) + mDeferredRotation.z() -= 2 * osg::PI; + if (mDeferredRotation.z() < -osg::PI) + mDeferredRotation.z() += 2 * osg::PI; + } + } diff --git a/apps/openmw/mwrender/camera.hpp b/apps/openmw/mwrender/camera.hpp index 4c5523974f..c5f7ec2b2c 100644 --- a/apps/openmw/mwrender/camera.hpp +++ b/apps/openmw/mwrender/camera.hpp @@ -75,6 +75,11 @@ namespace MWRender osg::ref_ptr mUpdateCallback; + // Used to rotate player to the direction of view after exiting preview or vanity mode. + osg::Vec3f mDeferredRotation; + bool mDeferredRotationDisabled; + void calculateDeferredRotation(); + public: Camera(osg::Camera* camera); ~Camera(); @@ -98,6 +103,7 @@ namespace MWRender /// Set where the camera is looking at. Uses Morrowind (euler) angles /// \param rot Rotation angles in radians void rotateCamera(float pitch, float yaw, bool adjust); + void rotateCameraToTrackingPtr(); float getYaw() const { return mYaw; } void setYaw(float angle); @@ -114,6 +120,9 @@ namespace MWRender /// @note this may be ignored if an important animation is currently playing void togglePreviewMode(bool enable); + void applyDeferredPreviewRotationToPlayer(float dt); + void disableDeferredPreviewRotation() { mDeferredRotationDisabled = true; } + /// \brief Lowers the camera for sneak. void setSneakOffset(float offset); diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index e4150eebcc..d9739e844c 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -58,7 +58,6 @@ #include "../mwgui/loadingscreen.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" -#include "../mwmechanics/movement.hpp" #include "sky.hpp" #include "effectmanager.hpp" @@ -204,8 +203,6 @@ namespace MWRender , mNightEyeFactor(0.f) , mFieldOfViewOverridden(false) , mFieldOfViewOverride(0.f) - , mDeferredRotation(osg::Vec3f()) - , mDeferredRotationDisabled(false) { resourceSystem->getSceneManager()->setParticleSystemMask(MWRender::Mask_ParticleSystem); resourceSystem->getSceneManager()->setShaderPath(resourcePath + "/shaders"); @@ -656,8 +653,7 @@ namespace MWRender if(ptr == mCamera->getTrackingPtr() && !mCamera->isVanityOrPreviewModeEnabled()) { - mCamera->rotateCamera(-ptr.getRefData().getPosition().rot[0] - mDeferredRotation.x(), - -ptr.getRefData().getPosition().rot[2] - mDeferredRotation.z(), false); + mCamera->rotateCameraToTrackingPtr(); } ptr.getRefData().getBaseNode()->setAttitude(rot); @@ -1328,50 +1324,6 @@ namespace MWRender return true; } - void RenderingManager::applyDeferredPreviewRotationToPlayer(float dt) - { - MWWorld::Ptr ptr = mCamera->getTrackingPtr(); - if (mCamera->isVanityOrPreviewModeEnabled() || ptr.isEmpty()) - return; - - osg::Vec3f rot = mDeferredRotation; - float delta = rot.normalize(); - delta = std::min(delta, (delta + 1.f) * 3 * dt); - rot *= delta; - mDeferredRotation -= rot; - - auto& movement = ptr.getClass().getMovementSettings(ptr); - movement.mRotation[0] += rot.x(); - movement.mRotation[1] += rot.y(); - movement.mRotation[2] += rot.z(); - } - - void RenderingManager::calculateDeferredRotation() - { - MWWorld::Ptr ptr = mCamera->getTrackingPtr(); - if (mCamera->isVanityOrPreviewModeEnabled() || ptr.isEmpty()) - return; - if (mCamera->isFirstPerson() || mDeferredRotationDisabled) - { - mDeferredRotationDisabled = false; - mDeferredRotation = osg::Vec3f(); - mCamera->rotateCamera(-ptr.getRefData().getPosition().rot[0], - -ptr.getRefData().getPosition().rot[2], false); - return; - } - - mDeferredRotation.x() = -ptr.getRefData().getPosition().rot[0] - mCamera->getPitch(); - mDeferredRotation.z() = -ptr.getRefData().getPosition().rot[2] - mCamera->getYaw(); - if (mDeferredRotation.x() > osg::PI) - mDeferredRotation.x() -= 2 * osg::PI; - if (mDeferredRotation.x() < -osg::PI) - mDeferredRotation.x() += 2 * osg::PI; - if (mDeferredRotation.z() > osg::PI) - mDeferredRotation.z() -= 2 * osg::PI; - if (mDeferredRotation.z() < -osg::PI) - mDeferredRotation.z() += 2 * osg::PI; - } - void RenderingManager::setCameraDistance(float dist, bool adjust, bool override) { if(!mCamera->isVanityOrPreviewModeEnabled() && !mCamera->isFirstPerson()) @@ -1421,14 +1373,11 @@ namespace MWRender void RenderingManager::togglePreviewMode(bool enable) { mCamera->togglePreviewMode(enable); - calculateDeferredRotation(); } bool RenderingManager::toggleVanityMode(bool enable) { - bool res = mCamera->toggleVanityMode(enable); - calculateDeferredRotation(); - return res; + return mCamera->toggleVanityMode(enable); } void RenderingManager::allowVanityMode(bool allow) diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 000826caa1..d6a0f89c31 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -221,9 +221,6 @@ namespace MWRender void allowVanityMode(bool allow); void changeVanityModeScale(float factor); - void applyDeferredPreviewRotationToPlayer(float dt); - void disableDeferredPreviewRotation() { mDeferredRotationDisabled = true; } - /// temporarily override the field of view with given value. void overrideFieldOfView(float val); /// reset a previous overrideFieldOfView() call, i.e. revert to field of view specified in the settings file. @@ -313,11 +310,6 @@ namespace MWRender float mFieldOfView; float mFirstPersonFieldOfView; - // Used to rotate player to the direction of view after exiting preview or vanity mode. - osg::Vec3f mDeferredRotation; - bool mDeferredRotationDisabled; - void calculateDeferredRotation(); - void operator = (const RenderingManager&); RenderingManager(const RenderingManager&); }; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 423c55732c..ca451601ba 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2407,12 +2407,12 @@ namespace MWWorld void World::disableDeferredPreviewRotation() { - mRendering->disableDeferredPreviewRotation(); + mRendering->getCamera()->disableDeferredPreviewRotation(); } void World::applyDeferredPreviewRotationToPlayer(float dt) { - mRendering->applyDeferredPreviewRotationToPlayer(dt); + mRendering->getCamera()->applyDeferredPreviewRotationToPlayer(dt); } void World::allowVanityMode(bool allow)