1#include "smooth_value.h"
2
3#include <engine/client.h>
4#include <engine/shared/config.h>
5
6CSmoothValue::CSmoothValue(float InitialValue, float MinValue, float MaxValue) :
7 m_Smoothing(false), m_Value(InitialValue), m_MinValue(MinValue), m_MaxValue(MaxValue) {}
8
9void CSmoothValue::SetValue(float Target)
10{
11 Target = std::clamp(val: Target, lo: m_MinValue, hi: m_MaxValue);
12 if(m_Value == Target)
13 {
14 return;
15 }
16
17 const float Now = Client()->GlobalTime();
18 float Current = m_Value;
19 float Derivative = 0.0f;
20 if(m_Smoothing)
21 {
22 const float Progress = ZoomProgress(CurrentTime: Now);
23 Current = m_ValueSmoothing.Evaluate(t: Progress);
24 Derivative = m_ValueSmoothing.Derivative(t: Progress);
25 }
26
27 m_ValueSmoothingTarget = Target;
28 m_ValueSmoothing = CCubicBezier::With(Start: Current, StartDerivative: Derivative, EndDerivative: 0.0f, End: m_ValueSmoothingTarget);
29 m_ValueSmoothingStart = Now;
30 m_ValueSmoothingEnd = Now + g_Config.m_EdSmoothZoomTime / 1000.0f;
31
32 m_Smoothing = true;
33}
34
35void CSmoothValue::ChangeValue(float Amount)
36{
37 const float CurrentTarget = m_Smoothing ? m_ValueSmoothingTarget : m_Value;
38 SetValue(CurrentTarget + Amount);
39}
40
41bool CSmoothValue::UpdateValue()
42{
43 if(m_Smoothing)
44 {
45 const float Time = Client()->GlobalTime();
46 const float OldLevel = m_Value;
47 if(Time >= m_ValueSmoothingEnd)
48 {
49 m_Value = m_ValueSmoothingTarget;
50 m_Smoothing = false;
51 }
52 else
53 {
54 m_Value = m_ValueSmoothing.Evaluate(t: ZoomProgress(CurrentTime: Time));
55 if((OldLevel < m_ValueSmoothingTarget && m_Value > m_ValueSmoothingTarget) || (OldLevel > m_ValueSmoothingTarget && m_Value < m_ValueSmoothingTarget))
56 {
57 m_Value = m_ValueSmoothingTarget;
58 m_Smoothing = false;
59 }
60 }
61 m_Value = std::clamp(val: m_Value, lo: m_MinValue, hi: m_MaxValue);
62
63 return true;
64 }
65
66 return false;
67}
68
69float CSmoothValue::ZoomProgress(float CurrentTime) const
70{
71 return (CurrentTime - m_ValueSmoothingStart) / (m_ValueSmoothingEnd - m_ValueSmoothingStart);
72}
73
74float CSmoothValue::GetValue() const
75{
76 return m_Value;
77}
78
79void CSmoothValue::SetValueInstant(float Target)
80{
81 m_Smoothing = false;
82 m_Value = std::clamp(val: Target, lo: m_MinValue, hi: m_MaxValue);
83}
84
85void CSmoothValue::SetValueRange(float MinValue, float MaxValue)
86{
87 m_MinValue = MinValue;
88 m_MaxValue = MaxValue;
89}
90
91float CSmoothValue::GetMinValue() const
92{
93 return m_MinValue;
94}
95
96float CSmoothValue::GetMaxValue() const
97{
98 return m_MaxValue;
99}
100