Auto switch shoulder

pull/579/head
Petr Mikheev 5 years ago
parent 5675d6ce81
commit ef03f2c033

@ -270,7 +270,7 @@ namespace MWRender
focalPointTargetOffset = mOverShoulderOffset;
break;
case ThirdPersonOffsetType::LeftShoulder:
focalPointTargetOffset = mOverShoulderOffset
focalPointTargetOffset = mOverShoulderOffset;
focalPointTargetOffset.x() *= -1;
break;
case ThirdPersonOffsetType::Combat:

@ -82,8 +82,9 @@ namespace MWRender
MWWorld::Ptr getTrackingPtr() const;
void setThirdPersonViewMode(ThirdPersonViewMode mode) { mThirdPersonMode = mode; }
void setOverShoulderOffset(float horizontal, float vertical);
ThirdPersonViewMode getThirdPersonViewMode() const { return mThirdPersonMode; }
void setOverShoulderOffset(float horizontal, float vertical);
void switchToLeftShoulder();
void switchToRightShoulder();
void switchToDefaultShoulder();

@ -1869,13 +1869,44 @@ namespace MWWorld
float cameraObstacleLimit = mRendering->getNearClipDistance() * 2.5f;
float focalObstacleLimit = std::max(cameraObstacleLimit, 10.0f);
// Adjust focal point.
osg::Vec3d focal = camera->getFocalPoint();
osg::Vec3d focalOffset = camera->getFocalPointOffset();
osg::Vec3d playerPos = focal - focalOffset;
static const bool autoSwitchShoulder = Settings::Manager::getBool("auto switch shoulder", "Camera");
if (camera->getThirdPersonViewMode() == MWRender::Camera::ThirdPersonViewMode::OverShoulder
&& autoSwitchShoulder && !camera->isVanityOrPreviewModeEnabled())
{
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
auto orient = osg::Quat(camera->getYaw(), osg::Vec3d(0,0,1));
int mask = MWPhysics::CollisionType_World | MWPhysics::CollisionType_Door | MWPhysics::CollisionType_HeightMap;
MWPhysics::PhysicsSystem::RayResult rayRight = mPhysics->castRay(
playerPos + orient * osg::Vec3d(28, 0, 0),
playerPos + orient * osg::Vec3d(limitToSwitchBack, limitToSwitchBack, 0),
{}, {}, mask);
MWPhysics::PhysicsSystem::RayResult rayLeft = mPhysics->castRay(
playerPos + orient * osg::Vec3d(-28, 0, 0),
playerPos + orient * osg::Vec3d(-limitToSwitchBack, limitToSwitchBack, 0),
{}, {}, mask);
MWPhysics::PhysicsSystem::RayResult rayForward = mPhysics->castRay(
playerPos, playerPos + orient * osg::Vec3d(0, limitToSwitchBack, 0),
{}, {}, mask);
bool rightTooClose = rayRight.mHit && (rayRight.mHitPos - playerPos).length2() < limitToSwitch * limitToSwitch;
bool leftTooClose = rayLeft.mHit && (rayLeft.mHitPos - playerPos).length2() < limitToSwitch * limitToSwitch;
if (!rayRight.mHit && leftTooClose)
camera->switchToRightShoulder();
else if (!rayLeft.mHit && rightTooClose)
camera->switchToLeftShoulder();
else if (!rayRight.mHit && !rayLeft.mHit && !rayForward.mHit)
camera->switchToDefaultShoulder();
}
// Adjust focal point.
float offsetLen = focalOffset.length();
if (offsetLen > 0)
{
MWPhysics::PhysicsSystem::RayResult result = mPhysics->castSphere(focal - focalOffset, focal, focalObstacleLimit);
MWPhysics::PhysicsSystem::RayResult result = mPhysics->castSphere(playerPos, focal, focalObstacleLimit);
if (result.mHit)
{
double adjustmentCoef = -(result.mHitPos + result.mHitNormal * focalObstacleLimit - focal).length() / offsetLen;

@ -150,3 +150,15 @@ Recommened values: 30 -10 for the right shoulder, -30 -10 for the left shoulder.
This setting can only be configured by editing the settings configuration file.
auto switch shoulder
--------------------
:Type: boolean
:Range: True/False
:Default: True
This setting makes difference only in third person mode if 'view over shoulder' is enabled.
When player is close to an obstacle, automatically switches camera to the shoulder that is farther away from the obstacle.
This setting can only be configured by editing the settings configuration file.

@ -42,6 +42,9 @@ view over shoulder = false
# Makes sense only if 'view over shoulder' is true. First number is horizontal offset (negative value means offset to the left), second number is vertical offset.
view over shoulder offset = 30 -10
# Switch shoulder automatically when player is close to an obstacle.
auto switch shoulder = true
[Cells]
# Preload cells in a background thread. All settings starting with 'preload' have no effect unless this is enabled.

Loading…
Cancel
Save