Merge branch 'devel/master' into tizen
[platform/core/uifw/dali-core.git] / dali / internal / event / animation / progress-value.h
1 #ifndef DALI_INTERNAL_PROGRESS_VALUE_H
2 #define DALI_INTERNAL_PROGRESS_VALUE_H
3
4 /*
5  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // INTERNAL INCLUDES
22 #include <dali/public-api/math/angle-axis.h>
23 #include <dali/public-api/math/quaternion.h>
24 #include <dali/public-api/math/vector2.h>
25 #include <dali/public-api/math/vector3.h>
26 #include <dali/public-api/math/vector4.h>
27
28 namespace Dali
29 {
30 namespace Internal
31 {
32 /**
33  * Progress / value pair for animating channels (properties) with keyframes
34  */
35 template<typename T>
36 class ProgressValue
37 {
38 public:
39   ProgressValue(float progress, T value)
40   : mProgress(progress),
41     mValue(value)
42   {
43   }
44
45   ~ProgressValue() = default;
46
47   float GetProgress() const
48   {
49     return mProgress;
50   }
51
52   const T& GetValue() const
53   {
54     return mValue;
55   }
56
57 public:
58   float mProgress; ///< Progress this value applies to animation channel
59   T     mValue;    ///< value this animation channel should take
60 };
61
62 inline void Interpolate(Quaternion& result, const Quaternion& a, const Quaternion& b, float progress)
63 {
64   result = Quaternion::Slerp(a, b, progress);
65 }
66
67 inline void Interpolate(AngleAxis& result, const AngleAxis& a, const AngleAxis& b, float progress)
68 {
69   Quaternion q1(a.angle, a.axis);
70   Quaternion q2(b.angle, b.axis);
71
72   Quaternion iq = Quaternion::Slerp(q1, q2, progress);
73   iq.ToAxisAngle(result.axis, result.angle);
74 }
75
76 inline void Interpolate(bool& result, bool a, bool b, float progress)
77 {
78   result = progress < 0.5f ? a : b;
79 }
80
81 inline void Interpolate(int32_t& result, int a, int b, float progress)
82 {
83   result = static_cast<int>(static_cast<float>(a) + static_cast<float>(b - a) * progress + 0.5f);
84 }
85
86 inline void Interpolate(float& result, float a, float b, float progress)
87 {
88   result = a + (b - a) * progress;
89 }
90
91 inline void Interpolate(Vector2& result, const Vector2& a, const Vector2& b, float progress)
92 {
93   result = a + (b - a) * progress;
94 }
95
96 inline void Interpolate(Vector3& result, const Vector3& a, const Vector3& b, float progress)
97 {
98   result = a + (b - a) * progress;
99 }
100
101 inline void Interpolate(Vector4& result, const Vector4& a, const Vector4& b, float progress)
102 {
103   result = a + (b - a) * progress;
104 }
105
106 /* Cubic Interpolation (Catmull-Rom spline) between values p1 and p2. p0 and p3 are prev and next values
107  * and are used as control points to calculate tangent of the curve at interpolation points.
108  *
109  * f(t) = a3*t^3 + a2*t^2 + a1*t + a0
110  * Restrictions: f(0)=p1   f(1)=p2   f'(0)=(p2-p0)*0.5   f'(1)=(p3-p1)*0.5
111  */
112
113 inline void CubicInterpolate(int32_t& result, int32_t p0, int32_t p1, int32_t p2, int32_t p3, float progress)
114 {
115   float a3 = static_cast<float>(p3) * 0.5f - static_cast<float>(p2) * 1.5f + static_cast<float>(p1) * 1.5f - static_cast<float>(p0) * 0.5f;
116   float a2 = static_cast<float>(p0) - static_cast<float>(p1) * 2.5f + static_cast<float>(p2) * 2.0f - static_cast<float>(p3) * 0.5f;
117   float a1 = static_cast<float>(p2 - p0) * 0.5f;
118
119   result = static_cast<int>(a3 * progress * progress * progress + a2 * progress * progress + a1 * progress + static_cast<float>(p1) + 0.5f);
120 }
121
122 inline void CubicInterpolate(float& result, float p0, float p1, float p2, float p3, float progress)
123 {
124   float a3 = p3 * 0.5f - p2 * 1.5f + p1 * 1.5f - p0 * 0.5f;
125   float a2 = p0 - p1 * 2.5f + p2 * 2.0f - p3 * 0.5f;
126   float a1 = (p2 - p0) * 0.5f;
127
128   result = a3 * progress * progress * progress + a2 * progress * progress + a1 * progress + p1;
129 }
130
131 inline void CubicInterpolate(Vector2& result, const Vector2& p0, const Vector2& p1, const Vector2& p2, const Vector2& p3, float progress)
132 {
133   Vector2 a3 = p3 * 0.5f - p2 * 1.5f + p1 * 1.5f - p0 * 0.5f;
134   Vector2 a2 = p0 - p1 * 2.5f + p2 * 2.0f - p3 * 0.5f;
135   Vector2 a1 = (p2 - p0) * 0.5f;
136
137   result = a3 * progress * progress * progress + a2 * progress * progress + a1 * progress + p1;
138 }
139
140 inline void CubicInterpolate(Vector3& result, const Vector3& p0, const Vector3& p1, const Vector3& p2, const Vector3& p3, float progress)
141 {
142   Vector3 a3 = p3 * 0.5f - p2 * 1.5f + p1 * 1.5f - p0 * 0.5f;
143   Vector3 a2 = p0 - p1 * 2.5f + p2 * 2.0f - p3 * 0.5f;
144   Vector3 a1 = (p2 - p0) * 0.5f;
145
146   result = a3 * progress * progress * progress + a2 * progress * progress + a1 * progress + p1;
147 }
148
149 inline void CubicInterpolate(Vector4& result, const Vector4& p0, const Vector4& p1, const Vector4& p2, const Vector4& p3, float progress)
150 {
151   Vector4 a3 = p3 * 0.5f - p2 * 1.5f + p1 * 1.5f - p0 * 0.5f;
152   Vector4 a2 = p0 - p1 * 2.5f + p2 * 2.0f - p3 * 0.5f;
153   Vector4 a1 = (p2 - p0) * 0.5f;
154
155   result = a3 * progress * progress * progress + a2 * progress * progress + a1 * progress + p1;
156 }
157
158 inline void CubicInterpolate(bool& result, bool p0, bool p1, bool p2, bool p3, float progress)
159 {
160   Interpolate(result, p1, p2, progress);
161 }
162
163 inline void CubicInterpolate(Quaternion& result, const Quaternion& p0, const Quaternion& p1, const Quaternion& p2, const Quaternion& p3, float progress)
164 {
165   Interpolate(result, p1, p2, progress);
166 }
167
168 inline void CubicInterpolate(AngleAxis& result, const AngleAxis& p0, const AngleAxis& p1, const AngleAxis& p2, const AngleAxis& p3, float progress)
169 {
170   Interpolate(result, p1, p2, progress);
171 }
172
173 } // namespace Internal
174
175 } // namespace Dali
176
177 #endif // DALI_INTERNAL_PROGRESS_VALUE_H