Merge pull request #9045 from KebsCS/pr-smooth-spectating

Add smooth spectating
This commit is contained in:
Dennis Felsing 2024-09-28 11:55:01 +00:00 committed by GitHub
commit 27e29a1ba7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 100 additions and 0 deletions

View file

@ -99,6 +99,7 @@ MACRO_CONFIG_INT(ClMultiViewSensitivity, cl_multiview_sensitivity, 100, 0, 200,
MACRO_CONFIG_INT(ClMultiViewZoomSmoothness, cl_multiview_zoom_smoothness, 1300, 50, 5000, CFGFLAG_CLIENT | CFGFLAG_INSENSITIVE, "Set the smoothness of the multi-view zoom (in ms, higher = slower)")
MACRO_CONFIG_INT(ClSpectatorMouseclicks, cl_spectator_mouseclicks, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Enables left-click to toggle between spectating the closest player and free-view")
MACRO_CONFIG_INT(ClSmoothSpectatingTime, cl_smooth_spectating_time, 300, 0, 5000, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Time of smooth camera switch animation when spectating in ms (0 for off)")
MACRO_CONFIG_INT(EdAutosaveInterval, ed_autosave_interval, 10, 0, 240, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Interval in minutes at which a copy of the current editor map is automatically saved to the 'auto' folder (0 for off)")
MACRO_CONFIG_INT(EdAutosaveMax, ed_autosave_max, 10, 0, 1000, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Maximum number of autosaves that are kept per map name (0 = no limit)")

View file

@ -30,6 +30,16 @@ CCamera::CCamera()
mem_zero(m_aLastPos, sizeof(m_aLastPos));
m_PrevCenter = vec2(0, 0);
m_Center = vec2(0, 0);
m_PrevSpecId = -1;
m_WasSpectating = false;
m_CameraSmoothing = false;
}
float CCamera::CameraSmoothingProgress(float CurrentTime) const
{
return (CurrentTime - m_CameraSmoothingStart) / (m_CameraSmoothingEnd - m_CameraSmoothingStart);
}
float CCamera::ZoomProgress(float CurrentTime) const
@ -101,6 +111,33 @@ void CCamera::OnRender()
m_Zoom = clamp(m_Zoom, MinZoomLevel(), MaxZoomLevel());
}
if(m_CameraSmoothing)
{
if(!m_pClient->m_Snap.m_SpecInfo.m_Active)
{
m_Center = m_CameraSmoothingTarget;
m_CameraSmoothing = false;
}
else
{
float Time = Client()->LocalTime();
if(Time >= m_CameraSmoothingEnd)
{
m_Center = m_CameraSmoothingTarget;
m_CameraSmoothing = false;
}
else
{
m_CameraSmoothingCenter = vec2(m_CameraSmoothingBezierX.Evaluate(CameraSmoothingProgress(Time)), m_CameraSmoothingBezierY.Evaluate(CameraSmoothingProgress(Time)));
if(distance(m_CameraSmoothingCenter, m_CameraSmoothingTarget) <= 0.1f)
{
m_Center = m_CameraSmoothingTarget;
m_CameraSmoothing = false;
}
}
}
}
if(!ZoomAllowed())
{
m_ZoomSet = false;
@ -187,7 +224,53 @@ void CCamera::OnRender()
else
m_ForceFreeviewPos = m_Center;
const int SpecId = m_pClient->m_Snap.m_SpecInfo.m_SpectatorId;
// start smoothing from the current position when the target changes
if(m_CameraSmoothing && SpecId != m_PrevSpecId)
m_CameraSmoothing = false;
if(m_pClient->m_Snap.m_SpecInfo.m_Active &&
(SpecId != m_PrevSpecId ||
(m_CameraSmoothing && m_CameraSmoothingTarget != m_Center)) && // the target is moving during camera smoothing
!(!m_WasSpectating && m_Center != m_PrevCenter) && // dont smooth when starting to spectate
m_CamType != CAMTYPE_SPEC &&
!GameClient()->m_MultiViewActivated)
{
float Now = Client()->LocalTime();
if(!m_CameraSmoothing)
m_CenterBeforeSmoothing = m_PrevCenter;
vec2 Derivative = {0.f, 0.f};
if(m_CameraSmoothing)
{
float Progress = CameraSmoothingProgress(Now);
Derivative.x = m_CameraSmoothingBezierX.Derivative(Progress);
Derivative.y = m_CameraSmoothingBezierY.Derivative(Progress);
}
m_CameraSmoothingTarget = m_Center;
m_CameraSmoothingBezierX = CCubicBezier::With(m_CenterBeforeSmoothing.x, Derivative.x, 0, m_CameraSmoothingTarget.x);
m_CameraSmoothingBezierY = CCubicBezier::With(m_CenterBeforeSmoothing.y, Derivative.y, 0, m_CameraSmoothingTarget.y);
if(!m_CameraSmoothing)
{
m_CameraSmoothingStart = Now;
m_CameraSmoothingEnd = Now + (float)g_Config.m_ClSmoothSpectatingTime / 1000.0f;
}
if(!m_CameraSmoothing)
m_CameraSmoothingCenter = m_PrevCenter;
m_CameraSmoothing = true;
}
if(m_CameraSmoothing)
m_Center = m_CameraSmoothingCenter;
m_PrevCenter = m_Center;
m_PrevSpecId = SpecId;
m_WasSpectating = m_pClient->m_Snap.m_SpecInfo.m_Active;
}
void CCamera::OnConsoleInit()
@ -203,6 +286,8 @@ void CCamera::OnConsoleInit()
void CCamera::OnReset()
{
m_CameraSmoothing = false;
m_Zoom = std::pow(CCamera::ZOOM_STEP, g_Config.m_ClDefaultZoom - 10);
m_Zooming = false;
}

View file

@ -25,6 +25,20 @@ class CCamera : public CComponent
vec2 m_aLastPos[NUM_DUMMIES];
vec2 m_PrevCenter;
int m_PrevSpecId;
bool m_WasSpectating;
bool m_CameraSmoothing;
vec2 m_CameraSmoothingCenter;
vec2 m_CameraSmoothingTarget;
CCubicBezier m_CameraSmoothingBezierX;
CCubicBezier m_CameraSmoothingBezierY;
float m_CameraSmoothingStart;
float m_CameraSmoothingEnd;
vec2 m_CenterBeforeSmoothing;
float CameraSmoothingProgress(float CurrentTime) const;
CCubicBezier m_ZoomSmoothing;
float m_ZoomSmoothingStart;
float m_ZoomSmoothingEnd;