Improved preview mode

pull/579/head
Petr Mikheev 5 years ago
parent c3b581131d
commit 4d206d2c67

@ -422,6 +422,8 @@ namespace MWBase
virtual void changeVanityModeScale(float factor) = 0;
virtual bool vanityRotateCamera(float * rot) = 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 renderPlayer() = 0;

@ -110,23 +110,31 @@ namespace MWInput
if (MWBase::Environment::get().getInputManager()->getControlSwitch("playerviewswitch"))
{
static const bool separatePreviewCamera = Settings::Manager::getBool("separate preview camera", "Camera");
if (mBindingsManager->actionIsActive(A_TogglePOV))
{
if (mPreviewPOVDelay <= 0.5 &&
(mPreviewPOVDelay += dt) > 0.5)
if (separatePreviewCamera)
{
mPreviewPOVDelay = 1.f;
MWBase::Environment::get().getWorld()->togglePreviewMode(true);
if (mPreviewPOVDelay <= 0.5 && (mPreviewPOVDelay += dt) > 0.5)
{
mPreviewPOVDelay = 1.f;
MWBase::Environment::get().getWorld()->togglePreviewMode(true);
}
}
else
{
if (mPreviewPOVDelay == 0)
MWBase::Environment::get().getWorld()->togglePreviewMode(true);
mPreviewPOVDelay += dt;
}
}
else
{
//disable preview mode
MWBase::Environment::get().getWorld()->togglePreviewMode(false);
if (mPreviewPOVDelay > 0.f && mPreviewPOVDelay <= 0.5)
{
if (mPreviewPOVDelay > 0 || separatePreviewCamera)
MWBase::Environment::get().getWorld()->togglePreviewMode(false);
if (mPreviewPOVDelay > 0.f && mPreviewPOVDelay <= (separatePreviewCamera ? 0.5 : 0.25))
MWBase::Environment::get().getWorld()->togglePOV();
}
mPreviewPOVDelay = 0.f;
}
}

@ -9,6 +9,7 @@
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwworld/esmstore.hpp"
@ -101,6 +102,8 @@ namespace MWInput
mMouseManager->update(dt);
mSensorManager->update(dt);
mActionManager->update(dt, controllerMove);
MWBase::Environment::get().getWorld()->applyDeferredPreviewRotationToPlayer(dt);
}
void InputManager::setDragDrop(bool dragDrop)

@ -108,6 +108,8 @@ namespace MWInput
player.yaw(x);
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
{
@ -212,12 +214,15 @@ namespace MWInput
rot[2] = xAxis * dt * 1000.0f * mCameraSensitivity * (mInvertX ? -1 : 1) / 256.f;
// 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();
player.yaw(rot[2]);
player.pitch(rot[0]);
}
else if (!controls)
MWBase::Environment::get().getWorld()->disableDeferredPreviewRotation();
MWBase::Environment::get().getInputManager()->resetIdleTime();
}

@ -254,12 +254,15 @@ namespace MWInput
rot[2] = mGyroXSpeed * dt * mGyroHSensitivity * 4 * (mInvertX ? -1 : 1);
// 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();
player.yaw(rot[2]);
player.pitch(rot[0]);
}
else if (!playerLooking)
MWBase::Environment::get().getWorld()->disableDeferredPreviewRotation();
MWBase::Environment::get().getInputManager()->resetIdleTime();
}

@ -58,6 +58,7 @@ namespace MWRender
mIsNearest(false),
mHeight(124.f),
mBaseCameraDistance(Settings::Manager::getFloat("third person camera distance", "Camera")),
mUseSeparatePreviewCam(Settings::Manager::getBool("separate preview camera", "Camera")),
mVanityToggleQueued(false),
mVanityToggleQueuedValue(false),
mViewModeToggleQueued(false),
@ -126,7 +127,7 @@ namespace MWRender
osg::Vec3d Camera::getFocalPointOffset() const
{
osg::Vec3d offset(0, 0, 10.f);
if (!mPreviewMode && !mVanity.enabled)
if (!mUseSeparatePreviewCam || (!mPreviewMode && !mVanity.enabled))
{
offset.x() += mFocalPointCurrentOffset.x() * cos(getYaw());
offset.y() += mFocalPointCurrentOffset.x() * sin(getYaw());
@ -322,17 +323,19 @@ namespace MWRender
processViewChange();
float offset = mPreviewCam.offset;
if (mVanity.enabled) {
setPitch(osg::DegreesToRadians(-30.f));
mMainCam.offset = mCameraDistance;
} else {
offset = mMainCam.offset;
if (mUseSeparatePreviewCam)
{
float offset = mPreviewCam.offset;
if (mVanity.enabled)
{
setPitch(osg::DegreesToRadians(-30.f));
mMainCam.offset = mCameraDistance;
}
else
offset = mMainCam.offset;
mCameraDistance = offset;
}
mCameraDistance = offset;
return true;
}
@ -347,16 +350,18 @@ namespace MWRender
mPreviewMode = enable;
processViewChange();
float offset = mCameraDistance;
if (mPreviewMode) {
mMainCam.offset = offset;
offset = mPreviewCam.offset;
} else {
mPreviewCam.offset = offset;
offset = mMainCam.offset;
if (mUseSeparatePreviewCam)
{
float offset = mCameraDistance;
if (mPreviewMode) {
mMainCam.offset = offset;
offset = mPreviewCam.offset;
} else {
mPreviewCam.offset = offset;
offset = mMainCam.offset;
}
mCameraDistance = offset;
}
mCameraDistance = offset;
}
void Camera::setSneakOffset(float offset)
@ -366,7 +371,7 @@ namespace MWRender
float Camera::getYaw() const
{
if(mVanity.enabled || mPreviewMode)
if (mUseSeparatePreviewCam && (mVanity.enabled || mPreviewMode))
return mPreviewCam.yaw;
return mMainCam.yaw;
}
@ -378,18 +383,16 @@ namespace MWRender
} else if (angle < -osg::PI) {
angle += osg::PI*2;
}
if (mVanity.enabled || mPreviewMode) {
if (mUseSeparatePreviewCam && (mVanity.enabled || mPreviewMode))
mPreviewCam.yaw = angle;
} else {
else
mMainCam.yaw = angle;
}
}
float Camera::getPitch() const
{
if (mVanity.enabled || mPreviewMode) {
if (mUseSeparatePreviewCam && (mVanity.enabled || mPreviewMode))
return mPreviewCam.pitch;
}
return mMainCam.pitch;
}
@ -397,7 +400,7 @@ namespace MWRender
{
const float epsilon = 0.000001f;
float limit = osg::PI_2 - epsilon;
if(mPreviewMode)
if(mUseSeparatePreviewCam && mPreviewMode)
limit /= 2;
if(angle > limit)
@ -405,11 +408,10 @@ namespace MWRender
else if(angle < -limit)
angle = -limit;
if (mVanity.enabled || mPreviewMode) {
if (mUseSeparatePreviewCam && (mVanity.enabled || mPreviewMode))
mPreviewCam.pitch = angle;
} else {
else
mMainCam.pitch = angle;
}
}
float Camera::getCameraDistance() const
@ -428,7 +430,7 @@ namespace MWRender
if (adjust)
{
if (mVanity.enabled || mPreviewMode)
if (mUseSeparatePreviewCam && (mVanity.enabled || mPreviewMode))
dist += mCameraDistance;
else
dist += std::min(mCameraDistance - getCameraDistanceCorrection(), mBaseCameraDistance);
@ -443,7 +445,7 @@ namespace MWRender
mIsNearest = true;
}
if (mVanity.enabled || mPreviewMode)
if (mUseSeparatePreviewCam && (mVanity.enabled || mPreviewMode))
mPreviewCam.offset = dist;
else if (!mFirstPersonView)
{
@ -482,7 +484,7 @@ namespace MWRender
void Camera::setCameraDistance()
{
if (mVanity.enabled || mPreviewMode)
if (mUseSeparatePreviewCam && (mVanity.enabled || mPreviewMode))
mCameraDistance = mPreviewCam.offset;
else if (!mFirstPersonView)
{

@ -48,6 +48,7 @@ namespace MWRender
float mHeight, mBaseCameraDistance;
CamData mMainCam, mPreviewCam;
bool mUseSeparatePreviewCam;
bool mVanityToggleQueued;
bool mVanityToggleQueuedValue;
@ -115,6 +116,9 @@ namespace MWRender
bool toggleVanityMode(bool enable);
void allowVanityMode(bool allow);
void useSeparatePreviewCamera(bool v) { mUseSeparatePreviewCam = v; }
bool isUsingSeparatePreviewCamera() const { return mUseSeparatePreviewCam; }
/// @note this may be ignored if an important animation is currently playing
void togglePreviewMode(bool enable);
@ -152,6 +156,7 @@ namespace MWRender
void getPosition(osg::Vec3d &focal, osg::Vec3d &camera) const;
bool isVanityOrPreviewModeEnabled() const;
bool isVanityModeEnabled() const { return mVanity.enabled; }
bool isNearest() const;
};

@ -58,6 +58,7 @@
#include "../mwgui/loadingscreen.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwmechanics/movement.hpp"
#include "sky.hpp"
#include "effectmanager.hpp"
@ -203,6 +204,8 @@ 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");
@ -653,7 +656,8 @@ namespace MWRender
if(ptr == mCamera->getTrackingPtr() &&
!mCamera->isVanityOrPreviewModeEnabled())
{
mCamera->rotateCamera(-ptr.getRefData().getPosition().rot[0], -ptr.getRefData().getPosition().rot[2], false);
mCamera->rotateCamera(-ptr.getRefData().getPosition().rot[0] - mDeferredRotation.x(),
-ptr.getRefData().getPosition().rot[2] - mDeferredRotation.z(), false);
}
ptr.getRefData().getBaseNode()->setAttitude(rot);
@ -1324,6 +1328,50 @@ 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() || mCamera->isUsingSeparatePreviewCamera() || 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())
@ -1373,11 +1421,14 @@ namespace MWRender
void RenderingManager::togglePreviewMode(bool enable)
{
mCamera->togglePreviewMode(enable);
calculateDeferredRotation();
}
bool RenderingManager::toggleVanityMode(bool enable)
{
return mCamera->toggleVanityMode(enable);
bool res = mCamera->toggleVanityMode(enable);
calculateDeferredRotation();
return res;
}
void RenderingManager::allowVanityMode(bool allow)

@ -221,6 +221,9 @@ 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.
@ -310,6 +313,11 @@ 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&);
};

@ -33,12 +33,13 @@ namespace MWRender
void ViewOverShoulderController::update()
{
if (mCamera->isVanityOrPreviewModeEnabled() || mCamera->isFirstPerson())
if (mCamera->isFirstPerson())
return;
Mode oldMode = mMode;
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;
else if (MWBase::Environment::get().getWorld()->isSwimming(ptr))
mMode = Mode::Swimming;
@ -46,9 +47,13 @@ namespace MWRender
mMode = mDefaultShoulderIsRight ? Mode::RightShoulder : Mode::LeftShoulder;
if (mAutoSwitchShoulder && (mMode == Mode::LeftShoulder || mMode == Mode::RightShoulder))
trySwitchShoulder();
if (oldMode == mMode) return;
if (oldMode == Mode::Combat || mMode == Mode::Combat)
if (oldMode == mMode)
return;
if (mCamera->isVanityOrPreviewModeEnabled())
mCamera->setFocalPointTransitionSpeed(mCamera->isVanityModeEnabled() ? 0.2 : 1);
else if (oldMode == Mode::Combat || mMode == Mode::Combat)
mCamera->setFocalPointTransitionSpeed(5.f);
else
mCamera->setFocalPointTransitionSpeed(1.f);

@ -2405,6 +2405,16 @@ namespace MWWorld
return mRendering->toggleVanityMode(enable);
}
void World::disableDeferredPreviewRotation()
{
mRendering->disableDeferredPreviewRotation();
}
void World::applyDeferredPreviewRotationToPlayer(float dt)
{
mRendering->applyDeferredPreviewRotationToPlayer(dt);
}
void World::allowVanityMode(bool allow)
{
mRendering->allowVanityMode(allow);

@ -536,6 +536,9 @@ namespace MWWorld
bool vanityRotateCamera(float * rot) override;
void setCameraDistance(float dist, bool adjust = false, bool override = true) override;
void applyDeferredPreviewRotationToPlayer(float dt) override;
void disableDeferredPreviewRotation() override;
void setupPlayer() override;
void renderPlayer() override;

@ -33,6 +33,10 @@ field of view = 60.0
# Best to leave this at the default since vanilla assets are not complete enough to adapt to high FoV's. Too low FoV would clip the hands off screen.
first person field of view = 60.0
# true - standard bahaviour of preview and vanity camera
# false - smooth preview mode
separate preview camera = true
# Distance from the camera to the character in third person mode.
third person camera distance = 192

Loading…
Cancel
Save