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:
parent
63cab4052d
commit
9f850b6ffc
5 changed files with 81 additions and 64 deletions
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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&);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue