1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-26 09:35:28 +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 "../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;
}
}

View File

@ -75,6 +75,11 @@ namespace MWRender
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:
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);

View File

@ -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)

View File

@ -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&);
};

View File

@ -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)