mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-21 09:23:51 +00:00
Make transition in 'auto switch shoulder' smoother.
This commit is contained in:
parent
51173ebcf5
commit
173c1fdabb
3 changed files with 53 additions and 21 deletions
|
@ -64,7 +64,8 @@ namespace MWRender
|
||||||
mCameraDistance(0.f),
|
mCameraDistance(0.f),
|
||||||
mFocalPointCurrentOffset(osg::Vec2d()),
|
mFocalPointCurrentOffset(osg::Vec2d()),
|
||||||
mFocalPointTargetOffset(osg::Vec2d()),
|
mFocalPointTargetOffset(osg::Vec2d()),
|
||||||
mFocalPointTransitionSpeed(1.f),
|
mFocalPointTransitionSpeedCoef(1.f),
|
||||||
|
mPreviousTransitionInfluence(0.f),
|
||||||
mSmoothedSpeed(0.f),
|
mSmoothedSpeed(0.f),
|
||||||
mDynamicCameraDistanceEnabled(false),
|
mDynamicCameraDistanceEnabled(false),
|
||||||
mShowCrosshairInThirdPersonMode(false)
|
mShowCrosshairInThirdPersonMode(false)
|
||||||
|
@ -221,16 +222,44 @@ namespace MWRender
|
||||||
mSmoothedSpeed += osg::clampBetween(speed - mSmoothedSpeed, -maxDelta, maxDelta);
|
mSmoothedSpeed += osg::clampBetween(speed - mSmoothedSpeed, -maxDelta, maxDelta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Camera::setFocalPointTargetOffset(osg::Vec2d v)
|
||||||
|
{
|
||||||
|
mFocalPointTargetOffset = v;
|
||||||
|
mPreviousTransitionSpeed = mFocalPointTransitionSpeed;
|
||||||
|
mPreviousTransitionInfluence = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
void Camera::updateFocalPointOffset(float duration)
|
void Camera::updateFocalPointOffset(float duration)
|
||||||
{
|
{
|
||||||
|
if (duration <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
osg::Vec2d oldOffset = mFocalPointCurrentOffset;
|
||||||
|
|
||||||
|
if (mPreviousTransitionInfluence > 0)
|
||||||
|
{
|
||||||
|
mFocalPointCurrentOffset -= mPreviousExtraOffset;
|
||||||
|
mPreviousExtraOffset = mPreviousExtraOffset / mPreviousTransitionInfluence + mPreviousTransitionSpeed * duration;
|
||||||
|
mPreviousTransitionInfluence =
|
||||||
|
std::max(0.f, mPreviousTransitionInfluence - duration * mFocalPointTransitionSpeedCoef);
|
||||||
|
mPreviousExtraOffset *= mPreviousTransitionInfluence;
|
||||||
|
mFocalPointCurrentOffset += mPreviousExtraOffset;
|
||||||
|
}
|
||||||
|
|
||||||
osg::Vec2d delta = mFocalPointTargetOffset - mFocalPointCurrentOffset;
|
osg::Vec2d delta = mFocalPointTargetOffset - mFocalPointCurrentOffset;
|
||||||
if (delta.length2() > 0)
|
if (delta.length2() > 0)
|
||||||
{
|
{
|
||||||
float coef = duration * (1.0 + 5.0 / delta.length()) * mFocalPointTransitionSpeed;
|
float coef = duration * (1.0 + 5.0 / delta.length()) *
|
||||||
|
mFocalPointTransitionSpeedCoef * (1.0f - mPreviousTransitionInfluence);
|
||||||
mFocalPointCurrentOffset += delta * std::min(coef, 1.0f);
|
mFocalPointCurrentOffset += delta * std::min(coef, 1.0f);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
mFocalPointTransitionSpeed = 1.f;
|
{
|
||||||
|
mPreviousExtraOffset = osg::Vec2d();
|
||||||
|
mPreviousTransitionInfluence = 0.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
mFocalPointTransitionSpeed = (mFocalPointCurrentOffset - oldOffset) / duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::toggleViewMode(bool force)
|
void Camera::toggleViewMode(bool force)
|
||||||
|
|
|
@ -58,7 +58,13 @@ namespace MWRender
|
||||||
osg::Vec3d mFocalPointAdjustment;
|
osg::Vec3d mFocalPointAdjustment;
|
||||||
osg::Vec2d mFocalPointCurrentOffset;
|
osg::Vec2d mFocalPointCurrentOffset;
|
||||||
osg::Vec2d mFocalPointTargetOffset;
|
osg::Vec2d mFocalPointTargetOffset;
|
||||||
float mFocalPointTransitionSpeed;
|
float mFocalPointTransitionSpeedCoef;
|
||||||
|
|
||||||
|
// This fields are used to make focal point transition smooth if previous transition was not finished.
|
||||||
|
float mPreviousTransitionInfluence;
|
||||||
|
osg::Vec2d mFocalPointTransitionSpeed;
|
||||||
|
osg::Vec2d mPreviousTransitionSpeed;
|
||||||
|
osg::Vec2d mPreviousExtraOffset;
|
||||||
|
|
||||||
float mSmoothedSpeed;
|
float mSmoothedSpeed;
|
||||||
bool mDynamicCameraDistanceEnabled;
|
bool mDynamicCameraDistanceEnabled;
|
||||||
|
@ -75,8 +81,8 @@ namespace MWRender
|
||||||
|
|
||||||
MWWorld::Ptr getTrackingPtr() const;
|
MWWorld::Ptr getTrackingPtr() const;
|
||||||
|
|
||||||
void setFocalPointTransitionSpeed(float v) { mFocalPointTransitionSpeed = v; }
|
void setFocalPointTransitionSpeed(float v) { mFocalPointTransitionSpeedCoef = v; }
|
||||||
void setFocalPointTargetOffset(osg::Vec2d v) { mFocalPointTargetOffset = v; }
|
void setFocalPointTargetOffset(osg::Vec2d v);
|
||||||
void enableDynamicCameraDistance(bool v) { mDynamicCameraDistanceEnabled = v; }
|
void enableDynamicCameraDistance(bool v) { mDynamicCameraDistanceEnabled = v; }
|
||||||
void enableCrosshairInThirdPersonMode(bool v) { mShowCrosshairInThirdPersonMode = v; }
|
void enableCrosshairInThirdPersonMode(bool v) { mShowCrosshairInThirdPersonMode = v; }
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ namespace MWRender
|
||||||
|
|
||||||
mCamera->enableDynamicCameraDistance(true);
|
mCamera->enableDynamicCameraDistance(true);
|
||||||
mCamera->enableCrosshairInThirdPersonMode(true);
|
mCamera->enableCrosshairInThirdPersonMode(true);
|
||||||
|
mCamera->setFocalPointTargetOffset({mOverShoulderHorizontalOffset, mOverShoulderVerticalOffset});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewOverShoulderController::update()
|
void ViewOverShoulderController::update()
|
||||||
|
@ -35,27 +36,23 @@ namespace MWRender
|
||||||
if (mCamera->isVanityOrPreviewModeEnabled() || mCamera->isFirstPerson())
|
if (mCamera->isVanityOrPreviewModeEnabled() || mCamera->isFirstPerson())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Mode newMode = mMode;
|
Mode oldMode = mMode;
|
||||||
auto ptr = mCamera->getTrackingPtr();
|
auto ptr = mCamera->getTrackingPtr();
|
||||||
if (ptr.getClass().isActor() && ptr.getClass().getCreatureStats(ptr).getDrawState() != MWMechanics::DrawState_Nothing)
|
if (ptr.getClass().isActor() && ptr.getClass().getCreatureStats(ptr).getDrawState() != MWMechanics::DrawState_Nothing)
|
||||||
newMode = Mode::Combat;
|
mMode = Mode::Combat;
|
||||||
else if (MWBase::Environment::get().getWorld()->isSwimming(ptr))
|
else if (MWBase::Environment::get().getWorld()->isSwimming(ptr))
|
||||||
newMode = Mode::Swimming;
|
mMode = Mode::Swimming;
|
||||||
else if (mMode == Mode::Combat || mMode == Mode::Swimming)
|
else if (oldMode == Mode::Combat || oldMode == Mode::Swimming)
|
||||||
newMode = mDefaultShoulderIsRight ? Mode::RightShoulder : Mode::LeftShoulder;
|
mMode = mDefaultShoulderIsRight ? Mode::RightShoulder : Mode::LeftShoulder;
|
||||||
if (newMode != mMode)
|
|
||||||
{
|
|
||||||
if (newMode == Mode::Combat || mMode == Mode::Combat)
|
|
||||||
mCamera->setFocalPointTransitionSpeed(5.f);
|
|
||||||
else
|
|
||||||
mCamera->setFocalPointTransitionSpeed(1.f);
|
|
||||||
mMode = newMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mAutoSwitchShoulder && (mMode == Mode::LeftShoulder || mMode == Mode::RightShoulder))
|
if (mAutoSwitchShoulder && (mMode == Mode::LeftShoulder || mMode == Mode::RightShoulder))
|
||||||
trySwitchShoulder();
|
trySwitchShoulder();
|
||||||
|
if (oldMode == mMode) return;
|
||||||
|
|
||||||
|
if (oldMode == Mode::Combat || mMode == Mode::Combat)
|
||||||
|
mCamera->setFocalPointTransitionSpeed(5.f);
|
||||||
|
else
|
||||||
|
mCamera->setFocalPointTransitionSpeed(1.f);
|
||||||
|
|
||||||
osg::Vec2d focalPointTargetOffset;
|
|
||||||
switch (mMode)
|
switch (mMode)
|
||||||
{
|
{
|
||||||
case Mode::RightShoulder:
|
case Mode::RightShoulder:
|
||||||
|
|
Loading…
Reference in a new issue