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