mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-26 02:38:04 +00:00
New settings 'preview if stand still' and 'deferred preview rotation'.
This commit is contained in:
parent
9f850b6ffc
commit
2e6aa155a3
@ -55,6 +55,8 @@ namespace MWRender
|
|||||||
mFirstPersonView(true),
|
mFirstPersonView(true),
|
||||||
mMode(Mode::Normal),
|
mMode(Mode::Normal),
|
||||||
mVanityAllowed(true),
|
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),
|
||||||
@ -200,6 +202,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)
|
||||||
@ -266,6 +286,7 @@ namespace MWRender
|
|||||||
mTrackingPtr.getClass().getCreatureStats(mTrackingPtr).setSideMovementAngle(0);
|
mTrackingPtr.getClass().getCreatureStats(mTrackingPtr).setSideMovementAngle(0);
|
||||||
|
|
||||||
mFirstPersonView = !mFirstPersonView;
|
mFirstPersonView = !mFirstPersonView;
|
||||||
|
updateStandingPreviewMode();
|
||||||
processViewChange();
|
processViewChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,6 +317,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 (!mDeferredRotationAllowed)
|
||||||
|
disableDeferredPreviewRotation();
|
||||||
if (!enable)
|
if (!enable)
|
||||||
calculateDeferredRotation();
|
calculateDeferredRotation();
|
||||||
|
|
||||||
@ -312,8 +335,14 @@ namespace MWRender
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
mMode = enable ? Mode::Preview : Mode::Normal;
|
mMode = enable ? Mode::Preview : Mode::Normal;
|
||||||
if (!enable)
|
if (mMode == Mode::Normal)
|
||||||
|
updateStandingPreviewMode();
|
||||||
|
if (mMode == Mode::Normal)
|
||||||
|
{
|
||||||
|
if (!mDeferredRotationAllowed)
|
||||||
|
disableDeferredPreviewRotation();
|
||||||
calculateDeferredRotation();
|
calculateDeferredRotation();
|
||||||
|
}
|
||||||
processViewChange();
|
processViewChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -432,6 +461,13 @@ namespace MWRender
|
|||||||
rot *= delta;
|
rot *= delta;
|
||||||
mDeferredRotation -= rot;
|
mDeferredRotation -= rot;
|
||||||
|
|
||||||
|
if (mDeferredRotationDisabled)
|
||||||
|
{
|
||||||
|
mDeferredRotationDisabled = delta > 0.0001;
|
||||||
|
rotateCameraToTrackingPtr();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto& movement = mTrackingPtr.getClass().getMovementSettings(mTrackingPtr);
|
auto& movement = mTrackingPtr.getClass().getMovementSettings(mTrackingPtr);
|
||||||
movement.mRotation[0] += rot.x();
|
movement.mRotation[0] += rot.x();
|
||||||
movement.mRotation[1] += rot.y();
|
movement.mRotation[1] += rot.y();
|
||||||
@ -453,16 +489,22 @@ namespace MWRender
|
|||||||
setYaw(-mTrackingPtr.getRefData().getPosition().rot[2] - mDeferredRotation.z());
|
setYaw(-mTrackingPtr.getRefData().getPosition().rot[2] - mDeferredRotation.z());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Camera::instantTransition()
|
||||||
|
{
|
||||||
|
mSkipFocalPointTransition = true;
|
||||||
|
mDeferredRotationDisabled = false;
|
||||||
|
mDeferredRotation = osg::Vec3f();
|
||||||
|
rotateCameraToTrackingPtr();
|
||||||
|
}
|
||||||
|
|
||||||
void Camera::calculateDeferredRotation()
|
void Camera::calculateDeferredRotation()
|
||||||
{
|
{
|
||||||
MWWorld::Ptr ptr = mTrackingPtr;
|
MWWorld::Ptr ptr = mTrackingPtr;
|
||||||
if (isVanityOrPreviewModeEnabled() || ptr.isEmpty())
|
if (isVanityOrPreviewModeEnabled() || ptr.isEmpty())
|
||||||
return;
|
return;
|
||||||
if (isFirstPerson() || mDeferredRotationDisabled)
|
if (mFirstPersonView)
|
||||||
{
|
{
|
||||||
mDeferredRotationDisabled = false;
|
instantTransition();
|
||||||
mDeferredRotation = osg::Vec3f();
|
|
||||||
rotateCameraToTrackingPtr();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ namespace MWRender
|
|||||||
class Camera
|
class Camera
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum class Mode { Normal, Vanity, Preview };
|
enum class Mode { Normal, Vanity, Preview, StandingPreview };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MWWorld::Ptr mTrackingPtr;
|
MWWorld::Ptr mTrackingPtr;
|
||||||
@ -38,6 +38,8 @@ namespace MWRender
|
|||||||
bool mFirstPersonView;
|
bool mFirstPersonView;
|
||||||
Mode mMode;
|
Mode mMode;
|
||||||
bool mVanityAllowed;
|
bool mVanityAllowed;
|
||||||
|
bool mStandingPreviewAllowed;
|
||||||
|
bool mDeferredRotationAllowed;
|
||||||
|
|
||||||
float mNearest;
|
float mNearest;
|
||||||
float mFurthest;
|
float mFurthest;
|
||||||
@ -79,6 +81,7 @@ namespace MWRender
|
|||||||
osg::Vec3f mDeferredRotation;
|
osg::Vec3f mDeferredRotation;
|
||||||
bool mDeferredRotationDisabled;
|
bool mDeferredRotationDisabled;
|
||||||
void calculateDeferredRotation();
|
void calculateDeferredRotation();
|
||||||
|
void updateStandingPreviewMode();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Camera(osg::Camera* camera);
|
Camera(osg::Camera* camera);
|
||||||
@ -90,7 +93,7 @@ namespace MWRender
|
|||||||
|
|
||||||
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; }
|
||||||
|
|
||||||
|
@ -77,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
|
||||||
|
|
||||||
|
@ -945,7 +945,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();
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::changeToExteriorCell (const ESM::Position& position, bool adjustPlayerPos, bool changeEvent)
|
void World::changeToExteriorCell (const ESM::Position& position, bool adjustPlayerPos, bool changeEvent)
|
||||||
@ -961,7 +961,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();
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::changeToCell (const ESM::CellId& cellId, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent)
|
void World::changeToCell (const ESM::CellId& cellId, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent)
|
||||||
|
@ -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…
x
Reference in New Issue
Block a user