mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-18 05:58:19 +00:00
Merge pull request #9045 from KebsCS/pr-smooth-spectating
Add smooth spectating
This commit is contained in:
commit
27e29a1ba7
|
@ -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)")
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue