1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-06-19 13:41:32 +00:00

Move deferred rotation logic from renderingmanager.cpp to camera.cpp

This commit is contained in:
Petr Mikheev 2020-07-18 11:48:46 +02:00
parent 63cab4052d
commit 9f850b6ffc
5 changed files with 81 additions and 64 deletions

View file

@ -13,6 +13,7 @@
#include "../mwworld/refdata.hpp" #include "../mwworld/refdata.hpp"
#include "../mwmechanics/drawstate.hpp" #include "../mwmechanics/drawstate.hpp"
#include "../mwmechanics/movement.hpp"
#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/npcstats.hpp"
#include "npcanimation.hpp" #include "npcanimation.hpp"
@ -72,7 +73,9 @@ namespace MWRender
mSmoothedSpeed(0.f), mSmoothedSpeed(0.f),
mZoomOutWhenMoveCoef(Settings::Manager::getFloat("zoom out when move coef", "Camera")), mZoomOutWhenMoveCoef(Settings::Manager::getFloat("zoom out when move coef", "Camera")),
mDynamicCameraDistanceEnabled(false), mDynamicCameraDistanceEnabled(false),
mShowCrosshairInThirdPersonMode(false) mShowCrosshairInThirdPersonMode(false),
mDeferredRotation(osg::Vec3f()),
mDeferredRotationDisabled(false)
{ {
mCameraDistance = mBaseCameraDistance; mCameraDistance = mBaseCameraDistance;
@ -269,7 +272,10 @@ namespace MWRender
void Camera::allowVanityMode(bool allow) void Camera::allowVanityMode(bool allow)
{ {
if (!allow && mMode == Mode::Vanity) if (!allow && mMode == Mode::Vanity)
{
disableDeferredPreviewRotation();
toggleVanityMode(false); toggleVanityMode(false);
}
mVanityAllowed = allow; mVanityAllowed = allow;
} }
@ -290,6 +296,8 @@ namespace MWRender
if ((mMode == Mode::Vanity) == enable) if ((mMode == Mode::Vanity) == enable)
return true; return true;
mMode = enable ? Mode::Vanity : Mode::Normal; mMode = enable ? Mode::Vanity : Mode::Normal;
if (!enable)
calculateDeferredRotation();
processViewChange(); processViewChange();
return true; return true;
@ -304,6 +312,8 @@ namespace MWRender
return; return;
mMode = enable ? Mode::Preview : Mode::Normal; mMode = enable ? Mode::Preview : Mode::Normal;
if (!enable)
calculateDeferredRotation();
processViewChange(); processViewChange();
} }
@ -411,4 +421,61 @@ namespace MWRender
rotateCamera(getPitch(), getYaw(), false); 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;
}
} }

View file

@ -75,6 +75,11 @@ namespace MWRender
osg::ref_ptr<osg::NodeCallback> mUpdateCallback; osg::ref_ptr<osg::NodeCallback> mUpdateCallback;
// Used to rotate player to the direction of view after exiting preview or vanity mode.
osg::Vec3f mDeferredRotation;
bool mDeferredRotationDisabled;
void calculateDeferredRotation();
public: public:
Camera(osg::Camera* camera); Camera(osg::Camera* camera);
~Camera(); ~Camera();
@ -98,6 +103,7 @@ namespace MWRender
/// Set where the camera is looking at. Uses Morrowind (euler) angles /// Set where the camera is looking at. Uses Morrowind (euler) angles
/// \param rot Rotation angles in radians /// \param rot Rotation angles in radians
void rotateCamera(float pitch, float yaw, bool adjust); void rotateCamera(float pitch, float yaw, bool adjust);
void rotateCameraToTrackingPtr();
float getYaw() const { return mYaw; } float getYaw() const { return mYaw; }
void setYaw(float angle); void setYaw(float angle);
@ -114,6 +120,9 @@ namespace MWRender
/// @note this may be ignored if an important animation is currently playing /// @note this may be ignored if an important animation is currently playing
void togglePreviewMode(bool enable); void togglePreviewMode(bool enable);
void applyDeferredPreviewRotationToPlayer(float dt);
void disableDeferredPreviewRotation() { mDeferredRotationDisabled = true; }
/// \brief Lowers the camera for sneak. /// \brief Lowers the camera for sneak.
void setSneakOffset(float offset); void setSneakOffset(float offset);

View file

@ -58,7 +58,6 @@
#include "../mwgui/loadingscreen.hpp" #include "../mwgui/loadingscreen.hpp"
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "../mwmechanics/movement.hpp"
#include "sky.hpp" #include "sky.hpp"
#include "effectmanager.hpp" #include "effectmanager.hpp"
@ -204,8 +203,6 @@ namespace MWRender
, mNightEyeFactor(0.f) , mNightEyeFactor(0.f)
, mFieldOfViewOverridden(false) , mFieldOfViewOverridden(false)
, mFieldOfViewOverride(0.f) , mFieldOfViewOverride(0.f)
, mDeferredRotation(osg::Vec3f())
, mDeferredRotationDisabled(false)
{ {
resourceSystem->getSceneManager()->setParticleSystemMask(MWRender::Mask_ParticleSystem); resourceSystem->getSceneManager()->setParticleSystemMask(MWRender::Mask_ParticleSystem);
resourceSystem->getSceneManager()->setShaderPath(resourcePath + "/shaders"); resourceSystem->getSceneManager()->setShaderPath(resourcePath + "/shaders");
@ -656,8 +653,7 @@ namespace MWRender
if(ptr == mCamera->getTrackingPtr() && if(ptr == mCamera->getTrackingPtr() &&
!mCamera->isVanityOrPreviewModeEnabled()) !mCamera->isVanityOrPreviewModeEnabled())
{ {
mCamera->rotateCamera(-ptr.getRefData().getPosition().rot[0] - mDeferredRotation.x(), mCamera->rotateCameraToTrackingPtr();
-ptr.getRefData().getPosition().rot[2] - mDeferredRotation.z(), false);
} }
ptr.getRefData().getBaseNode()->setAttitude(rot); ptr.getRefData().getBaseNode()->setAttitude(rot);
@ -1328,50 +1324,6 @@ namespace MWRender
return true; 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) void RenderingManager::setCameraDistance(float dist, bool adjust, bool override)
{ {
if(!mCamera->isVanityOrPreviewModeEnabled() && !mCamera->isFirstPerson()) if(!mCamera->isVanityOrPreviewModeEnabled() && !mCamera->isFirstPerson())
@ -1421,14 +1373,11 @@ namespace MWRender
void RenderingManager::togglePreviewMode(bool enable) void RenderingManager::togglePreviewMode(bool enable)
{ {
mCamera->togglePreviewMode(enable); mCamera->togglePreviewMode(enable);
calculateDeferredRotation();
} }
bool RenderingManager::toggleVanityMode(bool enable) bool RenderingManager::toggleVanityMode(bool enable)
{ {
bool res = mCamera->toggleVanityMode(enable); return mCamera->toggleVanityMode(enable);
calculateDeferredRotation();
return res;
} }
void RenderingManager::allowVanityMode(bool allow) void RenderingManager::allowVanityMode(bool allow)

View file

@ -221,9 +221,6 @@ namespace MWRender
void allowVanityMode(bool allow); void allowVanityMode(bool allow);
void changeVanityModeScale(float factor); void changeVanityModeScale(float factor);
void applyDeferredPreviewRotationToPlayer(float dt);
void disableDeferredPreviewRotation() { mDeferredRotationDisabled = true; }
/// temporarily override the field of view with given value. /// temporarily override the field of view with given value.
void overrideFieldOfView(float val); void overrideFieldOfView(float val);
/// reset a previous overrideFieldOfView() call, i.e. revert to field of view specified in the settings file. /// 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 mFieldOfView;
float mFirstPersonFieldOfView; 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&); void operator = (const RenderingManager&);
RenderingManager(const RenderingManager&); RenderingManager(const RenderingManager&);
}; };

View file

@ -2407,12 +2407,12 @@ namespace MWWorld
void World::disableDeferredPreviewRotation() void World::disableDeferredPreviewRotation()
{ {
mRendering->disableDeferredPreviewRotation(); mRendering->getCamera()->disableDeferredPreviewRotation();
} }
void World::applyDeferredPreviewRotationToPlayer(float dt) void World::applyDeferredPreviewRotationToPlayer(float dt)
{ {
mRendering->applyDeferredPreviewRotationToPlayer(dt); mRendering->getCamera()->applyDeferredPreviewRotationToPlayer(dt);
} }
void World::allowVanityMode(bool allow) void World::allowVanityMode(bool allow)