mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 23:53:52 +00:00
Merge remote-tracking branch 'remotes/origin/master' into openxr_vr
This commit is contained in:
commit
1023ef6e49
13 changed files with 269 additions and 222 deletions
|
@ -435,6 +435,8 @@ namespace MWBase
|
||||||
virtual void changeVanityModeScale(float factor) = 0;
|
virtual void changeVanityModeScale(float factor) = 0;
|
||||||
virtual bool vanityRotateCamera(float * rot) = 0;
|
virtual bool vanityRotateCamera(float * rot) = 0;
|
||||||
virtual void setCameraDistance(float dist, bool adjust = false, bool override = true)=0;
|
virtual void setCameraDistance(float dist, bool adjust = false, bool override = true)=0;
|
||||||
|
virtual void applyDeferredPreviewRotationToPlayer(float dt) = 0;
|
||||||
|
virtual void disableDeferredPreviewRotation() = 0;
|
||||||
|
|
||||||
virtual void setupPlayer() = 0;
|
virtual void setupPlayer() = 0;
|
||||||
virtual void renderPlayer() = 0;
|
virtual void renderPlayer() = 0;
|
||||||
|
|
|
@ -110,23 +110,21 @@ namespace MWInput
|
||||||
|
|
||||||
if (MWBase::Environment::get().getInputManager()->getControlSwitch("playerviewswitch"))
|
if (MWBase::Environment::get().getInputManager()->getControlSwitch("playerviewswitch"))
|
||||||
{
|
{
|
||||||
|
const float switchLimit = 0.25;
|
||||||
|
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||||
if (mBindingsManager->actionIsActive(A_TogglePOV))
|
if (mBindingsManager->actionIsActive(A_TogglePOV))
|
||||||
{
|
{
|
||||||
if (mPreviewPOVDelay <= 0.5 &&
|
if (world->isFirstPerson() ? mPreviewPOVDelay > switchLimit : mPreviewPOVDelay == 0)
|
||||||
(mPreviewPOVDelay += dt) > 0.5)
|
world->togglePreviewMode(true);
|
||||||
{
|
mPreviewPOVDelay += dt;
|
||||||
mPreviewPOVDelay = 1.f;
|
|
||||||
MWBase::Environment::get().getWorld()->togglePreviewMode(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//disable preview mode
|
//disable preview mode
|
||||||
MWBase::Environment::get().getWorld()->togglePreviewMode(false);
|
if (mPreviewPOVDelay > 0)
|
||||||
if (mPreviewPOVDelay > 0.f && mPreviewPOVDelay <= 0.5)
|
world->togglePreviewMode(false);
|
||||||
{
|
if (mPreviewPOVDelay > 0.f && mPreviewPOVDelay <= switchLimit)
|
||||||
MWBase::Environment::get().getWorld()->togglePOV();
|
world->togglePOV();
|
||||||
}
|
|
||||||
mPreviewPOVDelay = 0.f;
|
mPreviewPOVDelay = 0.f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
|
#include "../mwbase/world.hpp"
|
||||||
|
|
||||||
#include "../mwworld/esmstore.hpp"
|
#include "../mwworld/esmstore.hpp"
|
||||||
|
|
||||||
|
@ -101,6 +102,8 @@ namespace MWInput
|
||||||
mMouseManager->update(dt);
|
mMouseManager->update(dt);
|
||||||
mSensorManager->update(dt);
|
mSensorManager->update(dt);
|
||||||
mActionManager->update(dt, controllerMove);
|
mActionManager->update(dt, controllerMove);
|
||||||
|
|
||||||
|
MWBase::Environment::get().getWorld()->applyDeferredPreviewRotationToPlayer(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputManager::setDragDrop(bool dragDrop)
|
void InputManager::setDragDrop(bool dragDrop)
|
||||||
|
|
|
@ -108,6 +108,8 @@ namespace MWInput
|
||||||
player.yaw(x);
|
player.yaw(x);
|
||||||
player.pitch(y);
|
player.pitch(y);
|
||||||
}
|
}
|
||||||
|
else if (!input->getControlSwitch("playerlooking"))
|
||||||
|
MWBase::Environment::get().getWorld()->disableDeferredPreviewRotation();
|
||||||
|
|
||||||
if (arg.zrel && input->getControlSwitch("playerviewswitch") && input->getControlSwitch("playercontrols")) //Check to make sure you are allowed to zoomout and there is a change
|
if (arg.zrel && input->getControlSwitch("playerviewswitch") && input->getControlSwitch("playercontrols")) //Check to make sure you are allowed to zoomout and there is a change
|
||||||
{
|
{
|
||||||
|
@ -207,17 +209,20 @@ namespace MWInput
|
||||||
return;
|
return;
|
||||||
|
|
||||||
float rot[3];
|
float rot[3];
|
||||||
rot[0] = yAxis * dt * 1000.0f * mCameraSensitivity * (mInvertY ? -1 : 1) * mCameraYMultiplier / 256.f;
|
rot[0] = -yAxis * dt * 1000.0f * mCameraSensitivity * (mInvertY ? -1 : 1) * mCameraYMultiplier / 256.f;
|
||||||
rot[1] = 0.0f;
|
rot[1] = 0.0f;
|
||||||
rot[2] = xAxis * dt * 1000.0f * mCameraSensitivity * (mInvertX ? -1 : 1) / 256.f;
|
rot[2] = -xAxis * dt * 1000.0f * mCameraSensitivity * (mInvertX ? -1 : 1) / 256.f;
|
||||||
|
|
||||||
// Only actually turn player when we're not in vanity mode
|
// Only actually turn player when we're not in vanity mode
|
||||||
if (!MWBase::Environment::get().getWorld()->vanityRotateCamera(rot) && MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols"))
|
bool controls = MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols");
|
||||||
|
if (!MWBase::Environment::get().getWorld()->vanityRotateCamera(rot) && controls)
|
||||||
{
|
{
|
||||||
MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer();
|
MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer();
|
||||||
player.yaw(rot[2]);
|
player.yaw(-rot[2]);
|
||||||
player.pitch(rot[0]);
|
player.pitch(-rot[0]);
|
||||||
}
|
}
|
||||||
|
else if (!controls)
|
||||||
|
MWBase::Environment::get().getWorld()->disableDeferredPreviewRotation();
|
||||||
|
|
||||||
MWBase::Environment::get().getInputManager()->resetIdleTime();
|
MWBase::Environment::get().getInputManager()->resetIdleTime();
|
||||||
}
|
}
|
||||||
|
|
|
@ -249,17 +249,20 @@ namespace MWInput
|
||||||
if (!mGuiCursorEnabled)
|
if (!mGuiCursorEnabled)
|
||||||
{
|
{
|
||||||
float rot[3];
|
float rot[3];
|
||||||
rot[0] = mGyroYSpeed * dt * mGyroVSensitivity * 4 * (mInvertY ? -1 : 1);
|
rot[0] = -mGyroYSpeed * dt * mGyroVSensitivity * 4 * (mInvertY ? -1 : 1);
|
||||||
rot[1] = 0.0f;
|
rot[1] = 0.0f;
|
||||||
rot[2] = mGyroXSpeed * dt * mGyroHSensitivity * 4 * (mInvertX ? -1 : 1);
|
rot[2] = -mGyroXSpeed * dt * mGyroHSensitivity * 4 * (mInvertX ? -1 : 1);
|
||||||
|
|
||||||
// Only actually turn player when we're not in vanity mode
|
// Only actually turn player when we're not in vanity mode
|
||||||
if (!MWBase::Environment::get().getWorld()->vanityRotateCamera(rot) && MWBase::Environment::get().getInputManager()->getControlSwitch("playerlooking"))
|
bool playerLooking = MWBase::Environment::get().getInputManager()->getControlSwitch("playerlooking");
|
||||||
|
if (!MWBase::Environment::get().getWorld()->vanityRotateCamera(rot) && playerLooking)
|
||||||
{
|
{
|
||||||
MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer();
|
MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer();
|
||||||
player.yaw(rot[2]);
|
player.yaw(-rot[2]);
|
||||||
player.pitch(rot[0]);
|
player.pitch(-rot[0]);
|
||||||
}
|
}
|
||||||
|
else if (!playerLooking)
|
||||||
|
MWBase::Environment::get().getWorld()->disableDeferredPreviewRotation();
|
||||||
|
|
||||||
MWBase::Environment::get().getInputManager()->resetIdleTime();
|
MWBase::Environment::get().getInputManager()->resetIdleTime();
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#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"
|
||||||
|
@ -59,7 +60,10 @@ namespace MWRender
|
||||||
mCamera(camera),
|
mCamera(camera),
|
||||||
mAnimation(nullptr),
|
mAnimation(nullptr),
|
||||||
mFirstPersonView(true),
|
mFirstPersonView(true),
|
||||||
mPreviewMode(false),
|
mMode(Mode::Normal),
|
||||||
|
mVanityAllowed(true),
|
||||||
|
mStandingPreviewAllowed(Settings::Manager::getBool("preview if stand still", "Camera")),
|
||||||
|
mDeferredRotationAllowed(Settings::Manager::getBool("deferred preview rotation", "Camera")),
|
||||||
mNearest(30.f),
|
mNearest(30.f),
|
||||||
mFurthest(800.f),
|
mFurthest(800.f),
|
||||||
mIsNearest(false),
|
mIsNearest(false),
|
||||||
|
@ -78,20 +82,10 @@ 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)
|
||||||
{
|
{
|
||||||
mVanity.enabled = false;
|
|
||||||
mVanity.allowed = true;
|
|
||||||
|
|
||||||
mPreviewCam.roll = 0.f;
|
|
||||||
mPreviewCam.pitch = 0.f;
|
|
||||||
mPreviewCam.yaw = 0.f;
|
|
||||||
mPreviewCam.offset = 400.f;
|
|
||||||
mMainCam.roll = 0.f;
|
|
||||||
mMainCam.pitch = 0.f;
|
|
||||||
mMainCam.yaw = 0.f;
|
|
||||||
mMainCam.offset = 400.f;
|
|
||||||
|
|
||||||
mCameraDistance = mBaseCameraDistance;
|
mCameraDistance = mBaseCameraDistance;
|
||||||
|
|
||||||
mUpdateCallback = new UpdateRenderCameraCallback(this);
|
mUpdateCallback = new UpdateRenderCameraCallback(this);
|
||||||
|
@ -103,19 +97,14 @@ namespace MWRender
|
||||||
mCamera->removeUpdateCallback(mUpdateCallback);
|
mCamera->removeUpdateCallback(mUpdateCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
MWWorld::Ptr Camera::getTrackingPtr() const
|
|
||||||
{
|
|
||||||
return mTrackingPtr;
|
|
||||||
}
|
|
||||||
|
|
||||||
osg::Vec3d Camera::getFocalPoint() const
|
osg::Vec3d Camera::getFocalPoint() const
|
||||||
{
|
{
|
||||||
const osg::Node* trackNode = mTrackingNode;
|
if (!mTrackingNode)
|
||||||
if (!trackNode)
|
|
||||||
{
|
{
|
||||||
return osg::Vec3d();
|
return osg::Vec3d();
|
||||||
}
|
}
|
||||||
osg::NodePathList nodepaths = trackNode->getParentalNodePaths();
|
|
||||||
|
osg::NodePathList nodepaths = mTrackingNode->getParentalNodePaths();
|
||||||
if (nodepaths.empty())
|
if (nodepaths.empty())
|
||||||
return osg::Vec3d();
|
return osg::Vec3d();
|
||||||
osg::Matrix worldMat = osg::computeLocalToWorld(nodepaths[0]);
|
osg::Matrix worldMat = osg::computeLocalToWorld(nodepaths[0]);
|
||||||
|
@ -147,12 +136,9 @@ namespace MWRender
|
||||||
osg::Vec3d Camera::getFocalPointOffset() const
|
osg::Vec3d Camera::getFocalPointOffset() const
|
||||||
{
|
{
|
||||||
osg::Vec3d offset(0, 0, 10.f);
|
osg::Vec3d offset(0, 0, 10.f);
|
||||||
if (!mPreviewMode && !mVanity.enabled)
|
offset.x() += mFocalPointCurrentOffset.x() * cos(getYaw());
|
||||||
{
|
offset.y() += mFocalPointCurrentOffset.x() * sin(getYaw());
|
||||||
offset.x() += mFocalPointCurrentOffset.x() * cos(getYaw());
|
offset.z() += mFocalPointCurrentOffset.y();
|
||||||
offset.y() += mFocalPointCurrentOffset.x() * sin(getYaw());
|
|
||||||
offset.z() += mFocalPointCurrentOffset.y();
|
|
||||||
}
|
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,9 +156,6 @@ namespace MWRender
|
||||||
|
|
||||||
void Camera::updateCamera(osg::Camera *cam)
|
void Camera::updateCamera(osg::Camera *cam)
|
||||||
{
|
{
|
||||||
if (mTrackingPtr.isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
osg::Quat orient = osg::Quat(getPitch(), osg::Vec3d(1,0,0)) * osg::Quat(getRoll(), osg::Vec3d(0, 1, 0)) * osg::Quat(getYaw(), osg::Vec3d(0,0,1));
|
osg::Quat orient = osg::Quat(getPitch(), osg::Vec3d(1,0,0)) * osg::Quat(getRoll(), osg::Vec3d(0, 1, 0)) * osg::Quat(getYaw(), osg::Vec3d(0,0,1));
|
||||||
osg::Vec3d focal, position;
|
osg::Vec3d focal, position;
|
||||||
getPosition(focal, position);
|
getPosition(focal, position);
|
||||||
|
@ -183,7 +166,6 @@ namespace MWRender
|
||||||
{
|
{
|
||||||
position += inputManager->headOffset();
|
position += inputManager->headOffset();
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
osg::Vec3d forward = orient * osg::Vec3d(0,1,0);
|
osg::Vec3d forward = orient * osg::Vec3d(0,1,0);
|
||||||
|
@ -213,11 +195,6 @@ namespace MWRender
|
||||||
setRoll(roll);
|
setRoll(roll);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::attachTo(const MWWorld::Ptr &ptr)
|
|
||||||
{
|
|
||||||
mTrackingPtr = ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Camera::update(float duration, bool paused)
|
void Camera::update(float duration, bool paused)
|
||||||
{
|
{
|
||||||
if (mAnimation->upperBodyReady())
|
if (mAnimation->upperBodyReady())
|
||||||
|
@ -230,7 +207,6 @@ namespace MWRender
|
||||||
}
|
}
|
||||||
if (mViewModeToggleQueued)
|
if (mViewModeToggleQueued)
|
||||||
{
|
{
|
||||||
|
|
||||||
togglePreviewMode(false);
|
togglePreviewMode(false);
|
||||||
toggleViewMode();
|
toggleViewMode();
|
||||||
mViewModeToggleQueued = false;
|
mViewModeToggleQueued = false;
|
||||||
|
@ -242,13 +218,11 @@ namespace MWRender
|
||||||
|
|
||||||
// only show the crosshair in game mode
|
// only show the crosshair in game mode
|
||||||
MWBase::WindowManager *wm = MWBase::Environment::get().getWindowManager();
|
MWBase::WindowManager *wm = MWBase::Environment::get().getWindowManager();
|
||||||
wm->showCrosshair(!wm->isGuiMode() && !mVanity.enabled && !mPreviewMode
|
wm->showCrosshair(!wm->isGuiMode() && mMode != Mode::Preview && mMode != Mode::Vanity
|
||||||
&& (mFirstPersonView || mShowCrosshairInThirdPersonMode));
|
&& (mFirstPersonView || mShowCrosshairInThirdPersonMode));
|
||||||
|
|
||||||
if(mVanity.enabled)
|
if(mMode == Mode::Vanity)
|
||||||
{
|
|
||||||
rotateCamera(0.f, 0.f, osg::DegreesToRadians(3.f * duration), true);
|
rotateCamera(0.f, 0.f, osg::DegreesToRadians(3.f * duration), true);
|
||||||
}
|
|
||||||
|
|
||||||
updateFocalPointOffset(duration);
|
updateFocalPointOffset(duration);
|
||||||
|
|
||||||
|
@ -258,6 +232,24 @@ namespace MWRender
|
||||||
mSmoothedSpeed += osg::clampBetween(speed - mSmoothedSpeed, -maxDelta, maxDelta);
|
mSmoothedSpeed += osg::clampBetween(speed - mSmoothedSpeed, -maxDelta, maxDelta);
|
||||||
|
|
||||||
mMaxNextCameraDistance = mCameraDistance + duration * (100.f + mBaseCameraDistance);
|
mMaxNextCameraDistance = mCameraDistance + duration * (100.f + mBaseCameraDistance);
|
||||||
|
updateStandingPreviewMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::updateStandingPreviewMode()
|
||||||
|
{
|
||||||
|
if (!mStandingPreviewAllowed)
|
||||||
|
return;
|
||||||
|
float speed = mTrackingPtr.getClass().getSpeed(mTrackingPtr);
|
||||||
|
bool combat = mTrackingPtr.getClass().isActor() &&
|
||||||
|
mTrackingPtr.getClass().getCreatureStats(mTrackingPtr).getDrawState() != MWMechanics::DrawState_Nothing;
|
||||||
|
bool standingStill = speed == 0 && !combat && !mFirstPersonView;
|
||||||
|
if (!standingStill && mMode == Mode::StandingPreview)
|
||||||
|
{
|
||||||
|
mMode = Mode::Normal;
|
||||||
|
calculateDeferredRotation();
|
||||||
|
}
|
||||||
|
else if (standingStill && mMode == Mode::Normal)
|
||||||
|
mMode = Mode::StandingPreview;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::setFocalPointTargetOffset(osg::Vec2d v)
|
void Camera::setFocalPointTargetOffset(osg::Vec2d v)
|
||||||
|
@ -324,14 +316,19 @@ namespace MWRender
|
||||||
mTrackingPtr.getClass().getCreatureStats(mTrackingPtr).setSideMovementAngle(0);
|
mTrackingPtr.getClass().getCreatureStats(mTrackingPtr).setSideMovementAngle(0);
|
||||||
|
|
||||||
mFirstPersonView = !mFirstPersonView;
|
mFirstPersonView = !mFirstPersonView;
|
||||||
|
updateStandingPreviewMode();
|
||||||
|
instantTransition();
|
||||||
processViewChange();
|
processViewChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::allowVanityMode(bool allow)
|
void Camera::allowVanityMode(bool allow)
|
||||||
{
|
{
|
||||||
if (!allow && mVanity.enabled)
|
if (!allow && mMode == Mode::Vanity)
|
||||||
|
{
|
||||||
|
disableDeferredPreviewRotation();
|
||||||
toggleVanityMode(false);
|
toggleVanityMode(false);
|
||||||
mVanity.allowed = allow;
|
}
|
||||||
|
mVanityAllowed = allow;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Camera::toggleVanityMode(bool enable)
|
bool Camera::toggleVanityMode(bool enable)
|
||||||
|
@ -349,26 +346,18 @@ namespace MWRender
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!mVanity.allowed && enable)
|
if (!mVanityAllowed && enable)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(mVanity.enabled == enable)
|
if ((mMode == Mode::Vanity) == enable)
|
||||||
return true;
|
return true;
|
||||||
mVanity.enabled = enable;
|
mMode = enable ? Mode::Vanity : Mode::Normal;
|
||||||
|
if (!mDeferredRotationAllowed)
|
||||||
|
disableDeferredPreviewRotation();
|
||||||
|
if (!enable)
|
||||||
|
calculateDeferredRotation();
|
||||||
|
|
||||||
processViewChange();
|
processViewChange();
|
||||||
|
|
||||||
float offset = mPreviewCam.offset;
|
|
||||||
|
|
||||||
if (mVanity.enabled) {
|
|
||||||
setPitch(osg::DegreesToRadians(-30.f));
|
|
||||||
mMainCam.offset = mCameraDistance;
|
|
||||||
} else {
|
|
||||||
offset = mMainCam.offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
mCameraDistance = offset;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -377,22 +366,21 @@ namespace MWRender
|
||||||
if (mFirstPersonView && !mAnimation->upperBodyReady())
|
if (mFirstPersonView && !mAnimation->upperBodyReady())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(mPreviewMode == enable)
|
if((mMode == Mode::Preview) == enable)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mPreviewMode = enable;
|
mMode = enable ? Mode::Preview : Mode::Normal;
|
||||||
processViewChange();
|
if (mMode == Mode::Normal)
|
||||||
|
updateStandingPreviewMode();
|
||||||
float offset = mCameraDistance;
|
else if (mFirstPersonView)
|
||||||
if (mPreviewMode) {
|
instantTransition();
|
||||||
mMainCam.offset = offset;
|
if (mMode == Mode::Normal)
|
||||||
offset = mPreviewCam.offset;
|
{
|
||||||
} else {
|
if (!mDeferredRotationAllowed)
|
||||||
mPreviewCam.offset = offset;
|
disableDeferredPreviewRotation();
|
||||||
offset = mMainCam.offset;
|
calculateDeferredRotation();
|
||||||
}
|
}
|
||||||
|
processViewChange();
|
||||||
mCameraDistance = offset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::setSneakOffset(float offset)
|
void Camera::setSneakOffset(float offset)
|
||||||
|
@ -400,13 +388,6 @@ namespace MWRender
|
||||||
mAnimation->setFirstPersonOffset(osg::Vec3f(0,0,-offset));
|
mAnimation->setFirstPersonOffset(osg::Vec3f(0,0,-offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
float Camera::getYaw() const
|
|
||||||
{
|
|
||||||
if(mVanity.enabled || mPreviewMode)
|
|
||||||
return mPreviewCam.yaw;
|
|
||||||
return mMainCam.yaw;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Camera::setYaw(float angle)
|
void Camera::setYaw(float angle)
|
||||||
{
|
{
|
||||||
if (angle > osg::PI) {
|
if (angle > osg::PI) {
|
||||||
|
@ -414,18 +395,7 @@ namespace MWRender
|
||||||
} else if (angle < -osg::PI) {
|
} else if (angle < -osg::PI) {
|
||||||
angle += osg::PI*2;
|
angle += osg::PI*2;
|
||||||
}
|
}
|
||||||
if (mVanity.enabled || mPreviewMode) {
|
mYaw = angle;
|
||||||
mPreviewCam.yaw = angle;
|
|
||||||
} else {
|
|
||||||
mMainCam.yaw = angle;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
float Camera::getRoll()
|
|
||||||
{
|
|
||||||
if (mVanity.enabled || mPreviewMode)
|
|
||||||
return mPreviewCam.roll;
|
|
||||||
return mMainCam.roll;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::setRoll(float angle)
|
void Camera::setRoll(float angle)
|
||||||
|
@ -437,46 +407,19 @@ namespace MWRender
|
||||||
else if (angle < -osg::PI) {
|
else if (angle < -osg::PI) {
|
||||||
angle += osg::PI * 2;
|
angle += osg::PI * 2;
|
||||||
}
|
}
|
||||||
if (mVanity.enabled || mPreviewMode) {
|
mRoll = angle;
|
||||||
mPreviewCam.roll = angle;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
mMainCam.roll = angle;
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
// It seems OpenMW saves roll data, causing the camera to get tilted
|
// It seems OpenMW saves roll data, causing the camera to get tilted
|
||||||
// when loading a VR save in non-VR.
|
// when loading a VR save in non-VR.
|
||||||
mMainCam.roll = mPreviewCam.roll = 0.f;
|
mRoll = 0.f;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
float Camera::getPitch() const
|
|
||||||
{
|
|
||||||
if (mVanity.enabled || mPreviewMode) {
|
|
||||||
return mPreviewCam.pitch;
|
|
||||||
}
|
|
||||||
return mMainCam.pitch;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Camera::setPitch(float angle)
|
void Camera::setPitch(float angle)
|
||||||
{
|
{
|
||||||
const float epsilon = 0.000001f;
|
const float epsilon = 0.000001f;
|
||||||
float limit = osg::PI_2 - epsilon;
|
float limit = osg::PI_2 - epsilon;
|
||||||
if(mPreviewMode)
|
mPitch = osg::clampBetween(angle, -limit, limit);
|
||||||
limit /= 2;
|
|
||||||
|
|
||||||
#ifndef USE_OPENXR
|
|
||||||
if(angle > limit)
|
|
||||||
angle = limit;
|
|
||||||
else if(angle < -limit)
|
|
||||||
angle = -limit;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (mVanity.enabled || mPreviewMode) {
|
|
||||||
mPreviewCam.pitch = angle;
|
|
||||||
} else {
|
|
||||||
mMainCam.pitch = angle;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float Camera::getCameraDistance() const
|
float Camera::getCameraDistance() const
|
||||||
|
@ -488,50 +431,25 @@ namespace MWRender
|
||||||
|
|
||||||
void Camera::updateBaseCameraDistance(float dist, bool adjust)
|
void Camera::updateBaseCameraDistance(float dist, bool adjust)
|
||||||
{
|
{
|
||||||
if(mFirstPersonView && !mPreviewMode && !mVanity.enabled)
|
if (isFirstPerson())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mIsNearest = false;
|
|
||||||
|
|
||||||
if (adjust)
|
if (adjust)
|
||||||
{
|
dist += std::min(mCameraDistance - getCameraDistanceCorrection(), mBaseCameraDistance);
|
||||||
if (mVanity.enabled || mPreviewMode)
|
|
||||||
dist += mCameraDistance;
|
|
||||||
else
|
|
||||||
dist += std::min(mCameraDistance - getCameraDistanceCorrection(), mBaseCameraDistance);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
mIsNearest = dist <= mNearest;
|
||||||
if (dist >= mFurthest)
|
mBaseCameraDistance = osg::clampBetween(dist, mNearest, mFurthest);
|
||||||
dist = mFurthest;
|
Settings::Manager::setFloat("third person camera distance", "Camera", mBaseCameraDistance);
|
||||||
else if (dist <= mNearest)
|
|
||||||
{
|
|
||||||
dist = mNearest;
|
|
||||||
mIsNearest = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mVanity.enabled || mPreviewMode)
|
|
||||||
mPreviewCam.offset = dist;
|
|
||||||
else if (!mFirstPersonView)
|
|
||||||
{
|
|
||||||
mBaseCameraDistance = dist;
|
|
||||||
Settings::Manager::setFloat("third person camera distance", "Camera", dist);
|
|
||||||
}
|
|
||||||
setCameraDistance();
|
setCameraDistance();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::setCameraDistance(float dist, bool adjust)
|
void Camera::setCameraDistance(float dist, bool adjust)
|
||||||
{
|
{
|
||||||
if(mFirstPersonView && !mPreviewMode && !mVanity.enabled)
|
if (isFirstPerson())
|
||||||
return;
|
return;
|
||||||
|
if (adjust)
|
||||||
if (adjust) dist += mCameraDistance;
|
dist += mCameraDistance;
|
||||||
|
mCameraDistance = osg::clampBetween(dist, 10.f, mFurthest);
|
||||||
if (dist >= mFurthest)
|
|
||||||
dist = mFurthest;
|
|
||||||
else if (dist < 10.f)
|
|
||||||
dist = 10.f;
|
|
||||||
mCameraDistance = dist;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float Camera::getCameraDistanceCorrection() const
|
float Camera::getCameraDistanceCorrection() const
|
||||||
|
@ -549,21 +467,17 @@ namespace MWRender
|
||||||
|
|
||||||
void Camera::setCameraDistance()
|
void Camera::setCameraDistance()
|
||||||
{
|
{
|
||||||
if (mVanity.enabled || mPreviewMode)
|
|
||||||
mCameraDistance = mPreviewCam.offset;
|
|
||||||
else if (!mFirstPersonView)
|
|
||||||
{
|
|
||||||
mCameraDistance = mBaseCameraDistance + getCameraDistanceCorrection();
|
|
||||||
if (mDynamicCameraDistanceEnabled)
|
|
||||||
mCameraDistance = std::min(mCameraDistance, mMaxNextCameraDistance);
|
|
||||||
}
|
|
||||||
mFocalPointAdjustment = osg::Vec3d();
|
mFocalPointAdjustment = osg::Vec3d();
|
||||||
|
if (isFirstPerson())
|
||||||
|
return;
|
||||||
|
mCameraDistance = mBaseCameraDistance + getCameraDistanceCorrection();
|
||||||
|
if (mDynamicCameraDistanceEnabled)
|
||||||
|
mCameraDistance = std::min(mCameraDistance, mMaxNextCameraDistance);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::setAnimation(NpcAnimation *anim)
|
void Camera::setAnimation(NpcAnimation *anim)
|
||||||
{
|
{
|
||||||
mAnimation = anim;
|
mAnimation = anim;
|
||||||
|
|
||||||
processViewChange();
|
processViewChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -602,13 +516,74 @@ namespace MWRender
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Camera::isVanityOrPreviewModeEnabled() const
|
void Camera::applyDeferredPreviewRotationToPlayer(float dt)
|
||||||
{
|
{
|
||||||
return mPreviewMode || mVanity.enabled;
|
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;
|
||||||
|
|
||||||
|
if (mDeferredRotationDisabled)
|
||||||
|
{
|
||||||
|
mDeferredRotationDisabled = delta > 0.0001;
|
||||||
|
rotateCameraToTrackingPtr();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Camera::isNearest() const
|
void Camera::rotateCameraToTrackingPtr()
|
||||||
{
|
{
|
||||||
return mIsNearest;
|
setPitch(-mTrackingPtr.getRefData().getPosition().rot[0] - mDeferredRotation.x());
|
||||||
|
setYaw(-mTrackingPtr.getRefData().getPosition().rot[2] - mDeferredRotation.z());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Camera::instantTransition()
|
||||||
|
{
|
||||||
|
mSkipFocalPointTransition = true;
|
||||||
|
mDeferredRotationDisabled = false;
|
||||||
|
mDeferredRotation = osg::Vec3f();
|
||||||
|
rotateCameraToTrackingPtr();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::calculateDeferredRotation()
|
||||||
|
{
|
||||||
|
MWWorld::Ptr ptr = mTrackingPtr;
|
||||||
|
if (isVanityOrPreviewModeEnabled() || ptr.isEmpty())
|
||||||
|
return;
|
||||||
|
if (mFirstPersonView)
|
||||||
|
{
|
||||||
|
instantTransition();
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,11 +23,10 @@ namespace MWRender
|
||||||
/// \brief Camera control
|
/// \brief Camera control
|
||||||
class Camera
|
class Camera
|
||||||
{
|
{
|
||||||
private:
|
public:
|
||||||
struct CamData {
|
enum class Mode { Normal, Vanity, Preview, StandingPreview };
|
||||||
float roll, pitch, yaw, offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
private:
|
||||||
MWWorld::Ptr mTrackingPtr;
|
MWWorld::Ptr mTrackingPtr;
|
||||||
osg::ref_ptr<const osg::Node> mTrackingNode;
|
osg::ref_ptr<const osg::Node> mTrackingNode;
|
||||||
float mHeightScale;
|
float mHeightScale;
|
||||||
|
@ -37,17 +36,17 @@ namespace MWRender
|
||||||
NpcAnimation *mAnimation;
|
NpcAnimation *mAnimation;
|
||||||
|
|
||||||
bool mFirstPersonView;
|
bool mFirstPersonView;
|
||||||
bool mPreviewMode;
|
Mode mMode;
|
||||||
|
bool mVanityAllowed;
|
||||||
|
bool mStandingPreviewAllowed;
|
||||||
|
bool mDeferredRotationAllowed;
|
||||||
|
|
||||||
float mNearest;
|
float mNearest;
|
||||||
float mFurthest;
|
float mFurthest;
|
||||||
bool mIsNearest;
|
bool mIsNearest;
|
||||||
|
|
||||||
struct {
|
|
||||||
bool enabled, allowed;
|
|
||||||
} mVanity;
|
|
||||||
|
|
||||||
float mHeight, mBaseCameraDistance;
|
float mHeight, mBaseCameraDistance;
|
||||||
CamData mMainCam, mPreviewCam;
|
float mPitch, mYaw, mRoll;
|
||||||
|
|
||||||
bool mVanityToggleQueued;
|
bool mVanityToggleQueued;
|
||||||
bool mVanityToggleQueuedValue;
|
bool mVanityToggleQueuedValue;
|
||||||
|
@ -78,15 +77,23 @@ 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();
|
||||||
|
void updateStandingPreviewMode();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Camera(osg::Camera* camera);
|
Camera(osg::Camera* camera);
|
||||||
~Camera();
|
~Camera();
|
||||||
|
|
||||||
MWWorld::Ptr getTrackingPtr() const;
|
/// Attach camera to object
|
||||||
|
void attachTo(const MWWorld::Ptr &ptr) { mTrackingPtr = ptr; }
|
||||||
|
MWWorld::Ptr getTrackingPtr() const { return mTrackingPtr; }
|
||||||
|
|
||||||
void setFocalPointTransitionSpeed(float v) { mFocalPointTransitionSpeedCoef = v; }
|
void setFocalPointTransitionSpeed(float v) { mFocalPointTransitionSpeedCoef = v; }
|
||||||
void setFocalPointTargetOffset(osg::Vec2d v);
|
void setFocalPointTargetOffset(osg::Vec2d v);
|
||||||
void skipFocalPointTransition() { mSkipFocalPointTransition = true; }
|
void instantTransition();
|
||||||
void enableDynamicCameraDistance(bool v) { mDynamicCameraDistanceEnabled = v; }
|
void enableDynamicCameraDistance(bool v) { mDynamicCameraDistanceEnabled = v; }
|
||||||
void enableCrosshairInThirdPersonMode(bool v) { mShowCrosshairInThirdPersonMode = v; }
|
void enableCrosshairInThirdPersonMode(bool v) { mShowCrosshairInThirdPersonMode = v; }
|
||||||
|
|
||||||
|
@ -102,18 +109,16 @@ 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 roll, float yaw, bool adjust);
|
void rotateCamera(float pitch, float roll, float yaw, bool adjust);
|
||||||
|
void rotateCameraToTrackingPtr();
|
||||||
|
|
||||||
float getYaw() const;
|
float getYaw() const { return mYaw; }
|
||||||
void setYaw(float angle);
|
void setYaw(float angle);
|
||||||
|
|
||||||
float getRoll();
|
float getPitch() const { return mPitch; }
|
||||||
void setRoll(float angle);
|
|
||||||
|
|
||||||
float getPitch() const;
|
|
||||||
void setPitch(float angle);
|
void setPitch(float angle);
|
||||||
|
|
||||||
/// Attach camera to object
|
float getRoll() { return mRoll; }
|
||||||
void attachTo(const MWWorld::Ptr &);
|
void setRoll(float angle);
|
||||||
|
|
||||||
/// @param Force view mode switch, even if currently not allowed by the animation.
|
/// @param Force view mode switch, even if currently not allowed by the animation.
|
||||||
void toggleViewMode(bool force=false);
|
void toggleViewMode(bool force=false);
|
||||||
|
@ -124,11 +129,13 @@ 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);
|
||||||
|
|
||||||
bool isFirstPerson() const
|
bool isFirstPerson() const { return mFirstPersonView && mMode == Mode::Normal; }
|
||||||
{ return !(mVanity.enabled || mPreviewMode || !mFirstPersonView); }
|
|
||||||
|
|
||||||
void processViewChange();
|
void processViewChange();
|
||||||
|
|
||||||
|
@ -159,9 +166,10 @@ namespace MWRender
|
||||||
/// Stores focal and camera world positions in passed arguments
|
/// Stores focal and camera world positions in passed arguments
|
||||||
void getPosition(osg::Vec3d &focal, osg::Vec3d &camera) const;
|
void getPosition(osg::Vec3d &focal, osg::Vec3d &camera) const;
|
||||||
|
|
||||||
bool isVanityOrPreviewModeEnabled() const;
|
bool isVanityOrPreviewModeEnabled() const { return mMode != Mode::Normal; }
|
||||||
|
Mode getMode() const { return mMode; }
|
||||||
|
|
||||||
bool isNearest() const;
|
bool isNearest() const { return mIsNearest; }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -660,7 +660,7 @@ namespace MWRender
|
||||||
if(ptr == mCamera->getTrackingPtr() &&
|
if(ptr == mCamera->getTrackingPtr() &&
|
||||||
!mCamera->isVanityOrPreviewModeEnabled())
|
!mCamera->isVanityOrPreviewModeEnabled())
|
||||||
{
|
{
|
||||||
mCamera->rotateCamera(-ptr.getRefData().getPosition().rot[0], -ptr.getRefData().getPosition().rot[1], -ptr.getRefData().getPosition().rot[2], false);
|
mCamera->rotateCameraToTrackingPtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr.getRefData().getBaseNode()->setAttitude(rot);
|
ptr.getRefData().getBaseNode()->setAttitude(rot);
|
||||||
|
|
|
@ -33,12 +33,13 @@ namespace MWRender
|
||||||
|
|
||||||
void ViewOverShoulderController::update()
|
void ViewOverShoulderController::update()
|
||||||
{
|
{
|
||||||
if (mCamera->isVanityOrPreviewModeEnabled() || mCamera->isFirstPerson())
|
if (mCamera->isFirstPerson())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Mode oldMode = mMode;
|
Mode oldMode = mMode;
|
||||||
auto ptr = mCamera->getTrackingPtr();
|
auto ptr = mCamera->getTrackingPtr();
|
||||||
if (ptr.getClass().isActor() && ptr.getClass().getCreatureStats(ptr).getDrawState() != MWMechanics::DrawState_Nothing)
|
bool combat = ptr.getClass().isActor() && ptr.getClass().getCreatureStats(ptr).getDrawState() != MWMechanics::DrawState_Nothing;
|
||||||
|
if (combat && !mCamera->isVanityOrPreviewModeEnabled())
|
||||||
mMode = Mode::Combat;
|
mMode = Mode::Combat;
|
||||||
else if (MWBase::Environment::get().getWorld()->isSwimming(ptr))
|
else if (MWBase::Environment::get().getWorld()->isSwimming(ptr))
|
||||||
mMode = Mode::Swimming;
|
mMode = Mode::Swimming;
|
||||||
|
@ -46,12 +47,18 @@ namespace MWRender
|
||||||
mMode = mDefaultShoulderIsRight ? Mode::RightShoulder : Mode::LeftShoulder;
|
mMode = mDefaultShoulderIsRight ? Mode::RightShoulder : Mode::LeftShoulder;
|
||||||
if (mAutoSwitchShoulder && (mMode == Mode::LeftShoulder || mMode == Mode::RightShoulder))
|
if (mAutoSwitchShoulder && (mMode == Mode::LeftShoulder || mMode == Mode::RightShoulder))
|
||||||
trySwitchShoulder();
|
trySwitchShoulder();
|
||||||
if (oldMode == mMode) return;
|
|
||||||
|
|
||||||
if (oldMode == Mode::Combat || mMode == Mode::Combat)
|
if (oldMode == mMode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (mCamera->getMode() == Camera::Mode::Vanity)
|
||||||
|
// Player doesn't touch controls for a long time. Transition should be very slow.
|
||||||
|
mCamera->setFocalPointTransitionSpeed(0.2f);
|
||||||
|
else if ((oldMode == Mode::Combat || mMode == Mode::Combat) && mCamera->getMode() == Camera::Mode::Normal)
|
||||||
|
// Transition to/from combat mode and we are not it preview mode. Should be fast.
|
||||||
mCamera->setFocalPointTransitionSpeed(5.f);
|
mCamera->setFocalPointTransitionSpeed(5.f);
|
||||||
else
|
else
|
||||||
mCamera->setFocalPointTransitionSpeed(1.f);
|
mCamera->setFocalPointTransitionSpeed(1.f); // Default transition speed.
|
||||||
|
|
||||||
switch (mMode)
|
switch (mMode)
|
||||||
{
|
{
|
||||||
|
@ -70,6 +77,9 @@ namespace MWRender
|
||||||
|
|
||||||
void ViewOverShoulderController::trySwitchShoulder()
|
void ViewOverShoulderController::trySwitchShoulder()
|
||||||
{
|
{
|
||||||
|
if (mCamera->getMode() != Camera::Mode::Normal)
|
||||||
|
return;
|
||||||
|
|
||||||
const float limitToSwitch = 120; // switch to other shoulder if wall is closer than this limit
|
const float limitToSwitch = 120; // switch to other shoulder if wall is closer than this limit
|
||||||
const float limitToSwitchBack = 300; // switch back to default shoulder if there is no walls at this distance
|
const float limitToSwitchBack = 300; // switch back to default shoulder if there is no walls at this distance
|
||||||
|
|
||||||
|
@ -93,4 +103,4 @@ namespace MWRender
|
||||||
mMode = mDefaultShoulderIsRight ? Mode::RightShoulder : Mode::LeftShoulder;
|
mMode = mDefaultShoulderIsRight ? Mode::RightShoulder : Mode::LeftShoulder;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -954,7 +954,7 @@ namespace MWWorld
|
||||||
removeContainerScripts(getPlayerPtr());
|
removeContainerScripts(getPlayerPtr());
|
||||||
mWorldScene->changeToInteriorCell(cellName, position, adjustPlayerPos, changeEvent);
|
mWorldScene->changeToInteriorCell(cellName, position, adjustPlayerPos, changeEvent);
|
||||||
addContainerScripts(getPlayerPtr(), getPlayerPtr().getCell());
|
addContainerScripts(getPlayerPtr(), getPlayerPtr().getCell());
|
||||||
mRendering->getCamera()->skipFocalPointTransition();
|
mRendering->getCamera()->instantTransition();
|
||||||
|
|
||||||
#ifdef USE_OPENXR
|
#ifdef USE_OPENXR
|
||||||
auto* xrInput = MWVR::Environment::get().getInputManager();
|
auto* xrInput = MWVR::Environment::get().getInputManager();
|
||||||
|
@ -976,7 +976,7 @@ namespace MWWorld
|
||||||
removeContainerScripts(getPlayerPtr());
|
removeContainerScripts(getPlayerPtr());
|
||||||
mWorldScene->changeToExteriorCell(position, adjustPlayerPos, changeEvent);
|
mWorldScene->changeToExteriorCell(position, adjustPlayerPos, changeEvent);
|
||||||
addContainerScripts(getPlayerPtr(), getPlayerPtr().getCell());
|
addContainerScripts(getPlayerPtr(), getPlayerPtr().getCell());
|
||||||
mRendering->getCamera()->skipFocalPointTransition();
|
mRendering->getCamera()->instantTransition();
|
||||||
|
|
||||||
#ifdef USE_OPENXR
|
#ifdef USE_OPENXR
|
||||||
auto* xrInput = MWVR::Environment::get().getInputManager();
|
auto* xrInput = MWVR::Environment::get().getInputManager();
|
||||||
|
@ -2446,6 +2446,16 @@ namespace MWWorld
|
||||||
return mRendering->toggleVanityMode(enable);
|
return mRendering->toggleVanityMode(enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void World::disableDeferredPreviewRotation()
|
||||||
|
{
|
||||||
|
mRendering->getCamera()->disableDeferredPreviewRotation();
|
||||||
|
}
|
||||||
|
|
||||||
|
void World::applyDeferredPreviewRotationToPlayer(float dt)
|
||||||
|
{
|
||||||
|
mRendering->getCamera()->applyDeferredPreviewRotationToPlayer(dt);
|
||||||
|
}
|
||||||
|
|
||||||
void World::allowVanityMode(bool allow)
|
void World::allowVanityMode(bool allow)
|
||||||
{
|
{
|
||||||
mRendering->allowVanityMode(allow);
|
mRendering->allowVanityMode(allow);
|
||||||
|
|
|
@ -540,6 +540,9 @@ namespace MWWorld
|
||||||
bool vanityRotateCamera(float * rot) override;
|
bool vanityRotateCamera(float * rot) override;
|
||||||
void setCameraDistance(float dist, bool adjust = false, bool override = true) override;
|
void setCameraDistance(float dist, bool adjust = false, bool override = true) override;
|
||||||
|
|
||||||
|
void applyDeferredPreviewRotationToPlayer(float dt) override;
|
||||||
|
void disableDeferredPreviewRotation() override;
|
||||||
|
|
||||||
void setupPlayer() override;
|
void setupPlayer() override;
|
||||||
void renderPlayer() override;
|
void renderPlayer() override;
|
||||||
|
|
||||||
|
|
|
@ -174,3 +174,27 @@ Slightly pulls camera away (or closer in case of negative value) when the charac
|
||||||
|
|
||||||
This setting can only be configured by editing the settings configuration file.
|
This setting can only be configured by editing the settings configuration file.
|
||||||
|
|
||||||
|
preview if stand still
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
:Type: boolean
|
||||||
|
:Range: True/False
|
||||||
|
:Default: False
|
||||||
|
|
||||||
|
If enabled then the character rotation is not synchonized with the camera rotation while the character doesn't move and not in combat mode.
|
||||||
|
|
||||||
|
This setting can only be configured by editing the settings configuration file.
|
||||||
|
|
||||||
|
deferred preview rotation
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
:Type: boolean
|
||||||
|
:Range: True/False
|
||||||
|
:Default: True
|
||||||
|
|
||||||
|
Makes difference only in third person mode.
|
||||||
|
If enabled then the character smoothly rotates to the view direction after exiting preview or vanity mode.
|
||||||
|
If disabled then the camera rotates rather than the character.
|
||||||
|
|
||||||
|
This setting can only be configured by editing the settings configuration file.
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,12 @@ auto switch shoulder = true
|
||||||
# Slightly pulls camera away when the character moves. Works only in 'view over shoulder' mode. Set to 0 to disable.
|
# Slightly pulls camera away when the character moves. Works only in 'view over shoulder' mode. Set to 0 to disable.
|
||||||
zoom out when move coef = 20
|
zoom out when move coef = 20
|
||||||
|
|
||||||
|
# Automatically enable preview mode when player doesn't move.
|
||||||
|
preview if stand still = false
|
||||||
|
|
||||||
|
# Rotate the character to the view direction after exiting preview mode.
|
||||||
|
deferred preview rotation = true
|
||||||
|
|
||||||
[Cells]
|
[Cells]
|
||||||
|
|
||||||
# Preload cells in a background thread. All settings starting with 'preload' have no effect unless this is enabled.
|
# Preload cells in a background thread. All settings starting with 'preload' have no effect unless this is enabled.
|
||||||
|
|
Loading…
Reference in a new issue