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 Current = m_ValueSmoothing.Evaluate(t: Progress(CurrentTime: Now));
23 Derivative = m_ValueSmoothing.Derivative(t: Progress(CurrentTime: Now));
24 }
25
26 m_ValueSmoothingTarget = Target;
27 m_ValueSmoothing = CCubicBezier::With(Start: Current, StartDerivative: Derivative, EndDerivative: 0.0f, End: m_ValueSmoothingTarget);
28 m_ValueSmoothingStart = Now;
29 m_ValueSmoothingEnd = Now + g_Config.m_EdSmoothZoomTime / 1000.0f;
30
31 m_Smoothing = true;
32}
33
34void CSmoothValue::ScaleValue(float Factor)
35{
36 const float CurrentTarget = m_Smoothing ? m_ValueSmoothingTarget : m_Value;
37 SetValue(CurrentTarget * Factor);
38}
39
40bool CSmoothValue::UpdateValue()
41{
42 if(m_Smoothing)
43 {
44 const float Time = Client()->GlobalTime();
45 const float OldLevel = m_Value;
46 if(Time >= m_ValueSmoothingEnd)
47 {
48 m_Value = m_ValueSmoothingTarget;
49 m_Smoothing = false;
50 }
51 else
52 {
53 m_Value = m_ValueSmoothing.Evaluate(t: Progress(CurrentTime: Time));
54 if((OldLevel < m_ValueSmoothingTarget && m_Value > m_ValueSmoothingTarget) || (OldLevel > m_ValueSmoothingTarget && m_Value < m_ValueSmoothingTarget))
55 {
56 m_Value = m_ValueSmoothingTarget;
57 m_Smoothing = false;
58 }
59 }
60 m_Value = std::clamp(val: m_Value, lo: m_MinValue, hi: m_MaxValue);
61
62 return true;
63 }
64
65 return false;
66}
67
68float CSmoothValue::Progress(float CurrentTime) const
69{
70 return (CurrentTime - m_ValueSmoothingStart) / (m_ValueSmoothingEnd - m_ValueSmoothingStart);
71}
72
73float CSmoothValue::GetValue() const
74{
75 return m_Value;
76}
77
78void CSmoothValue::SetValueInstant(float Target)
79{
80 m_Smoothing = false;
81 m_Value = std::clamp(val: Target, lo: m_MinValue, hi: m_MaxValue);
82}
83
84void CSmoothValue::SetValueRange(float MinValue, float MaxValue)
85{
86 m_MinValue = MinValue;
87 m_MaxValue = MaxValue;
88}
89
90float CSmoothValue::GetMinValue() const
91{
92 return m_MinValue;
93}
94
95float CSmoothValue::GetMaxValue() const
96{
97 return m_MaxValue;
98}
99