mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-04 03:40:14 +00:00
Auto switch shoulder
This commit is contained in:
parent
5675d6ce81
commit
ef03f2c033
@ -270,7 +270,7 @@ namespace MWRender
|
|||||||
focalPointTargetOffset = mOverShoulderOffset;
|
focalPointTargetOffset = mOverShoulderOffset;
|
||||||
break;
|
break;
|
||||||
case ThirdPersonOffsetType::LeftShoulder:
|
case ThirdPersonOffsetType::LeftShoulder:
|
||||||
focalPointTargetOffset = mOverShoulderOffset
|
focalPointTargetOffset = mOverShoulderOffset;
|
||||||
focalPointTargetOffset.x() *= -1;
|
focalPointTargetOffset.x() *= -1;
|
||||||
break;
|
break;
|
||||||
case ThirdPersonOffsetType::Combat:
|
case ThirdPersonOffsetType::Combat:
|
||||||
|
@ -82,8 +82,9 @@ namespace MWRender
|
|||||||
MWWorld::Ptr getTrackingPtr() const;
|
MWWorld::Ptr getTrackingPtr() const;
|
||||||
|
|
||||||
void setThirdPersonViewMode(ThirdPersonViewMode mode) { mThirdPersonMode = mode; }
|
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 switchToLeftShoulder();
|
||||||
void switchToRightShoulder();
|
void switchToRightShoulder();
|
||||||
void switchToDefaultShoulder();
|
void switchToDefaultShoulder();
|
||||||
|
@ -1869,13 +1869,44 @@ namespace MWWorld
|
|||||||
float cameraObstacleLimit = mRendering->getNearClipDistance() * 2.5f;
|
float cameraObstacleLimit = mRendering->getNearClipDistance() * 2.5f;
|
||||||
float focalObstacleLimit = std::max(cameraObstacleLimit, 10.0f);
|
float focalObstacleLimit = std::max(cameraObstacleLimit, 10.0f);
|
||||||
|
|
||||||
// Adjust focal point.
|
|
||||||
osg::Vec3d focal = camera->getFocalPoint();
|
osg::Vec3d focal = camera->getFocalPoint();
|
||||||
osg::Vec3d focalOffset = camera->getFocalPointOffset();
|
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();
|
float offsetLen = focalOffset.length();
|
||||||
if (offsetLen > 0)
|
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)
|
if (result.mHit)
|
||||||
{
|
{
|
||||||
double adjustmentCoef = -(result.mHitPos + result.mHitNormal * focalObstacleLimit - focal).length() / offsetLen;
|
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.
|
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.
|
# 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
|
view over shoulder offset = 30 -10
|
||||||
|
|
||||||
|
# Switch shoulder automatically when player is close to an obstacle.
|
||||||
|
auto switch shoulder = 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