1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-30 16:15:31 +00:00

Improved preview mode

This commit is contained in:
Petr Mikheev 2020-06-27 00:58:33 +02:00
parent c3b581131d
commit 4d206d2c67
13 changed files with 157 additions and 48 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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