Make transition in 'auto switch shoulder' smoother.

pull/579/head
Petr Mikheev 5 years ago
parent 51173ebcf5
commit 173c1fdabb

@ -64,7 +64,8 @@ namespace MWRender
mCameraDistance(0.f),
mFocalPointCurrentOffset(osg::Vec2d()),
mFocalPointTargetOffset(osg::Vec2d()),
mFocalPointTransitionSpeed(1.f),
mFocalPointTransitionSpeedCoef(1.f),
mPreviousTransitionInfluence(0.f),
mSmoothedSpeed(0.f),
mDynamicCameraDistanceEnabled(false),
mShowCrosshairInThirdPersonMode(false)
@ -221,16 +222,44 @@ namespace MWRender
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)
{
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;
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);
}
else
mFocalPointTransitionSpeed = 1.f;
{
mPreviousExtraOffset = osg::Vec2d();
mPreviousTransitionInfluence = 0.f;
}
mFocalPointTransitionSpeed = (mFocalPointCurrentOffset - oldOffset) / duration;
}
void Camera::toggleViewMode(bool force)

@ -58,7 +58,13 @@ namespace MWRender
osg::Vec3d mFocalPointAdjustment;
osg::Vec2d mFocalPointCurrentOffset;
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;
bool mDynamicCameraDistanceEnabled;
@ -75,8 +81,8 @@ namespace MWRender
MWWorld::Ptr getTrackingPtr() const;
void setFocalPointTransitionSpeed(float v) { mFocalPointTransitionSpeed = v; }
void setFocalPointTargetOffset(osg::Vec2d v) { mFocalPointTargetOffset = v; }
void setFocalPointTransitionSpeed(float v) { mFocalPointTransitionSpeedCoef = v; }
void setFocalPointTargetOffset(osg::Vec2d v);
void enableDynamicCameraDistance(bool v) { mDynamicCameraDistanceEnabled = v; }
void enableCrosshairInThirdPersonMode(bool v) { mShowCrosshairInThirdPersonMode = v; }

@ -28,6 +28,7 @@ namespace MWRender
mCamera->enableDynamicCameraDistance(true);
mCamera->enableCrosshairInThirdPersonMode(true);
mCamera->setFocalPointTargetOffset({mOverShoulderHorizontalOffset, mOverShoulderVerticalOffset});
}
void ViewOverShoulderController::update()
@ -35,27 +36,23 @@ namespace MWRender
if (mCamera->isVanityOrPreviewModeEnabled() || mCamera->isFirstPerson())
return;
Mode newMode = mMode;
Mode oldMode = mMode;
auto ptr = mCamera->getTrackingPtr();
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))
newMode = Mode::Swimming;
else if (mMode == Mode::Combat || mMode == Mode::Swimming)
newMode = 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;
}
mMode = Mode::Swimming;
else if (oldMode == Mode::Combat || oldMode == Mode::Swimming)
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)
mCamera->setFocalPointTransitionSpeed(5.f);
else
mCamera->setFocalPointTransitionSpeed(1.f);
osg::Vec2d focalPointTargetOffset;
switch (mMode)
{
case Mode::RightShoulder:

Loading…
Cancel
Save