mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-26 09:35:28 +00:00
Make transition in 'auto switch shoulder' smoother.
This commit is contained in:
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…
x
Reference in New Issue
Block a user