• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef OHOS_ROSEN_WM_MATH_H
17 #define OHOS_ROSEN_WM_MATH_H
18 
19 #include <chrono>
20 #include <cmath>
21 #include <limits>
22 
23 namespace OHOS::Rosen {
24 namespace MathHelper {
25 constexpr float PI = 3.14159265f;
26 constexpr float INF = std::numeric_limits<float>::infinity();
27 constexpr float NAG_INF = -std::numeric_limits<float>::infinity();
28 constexpr float POS_ZERO = 0.001f;
29 constexpr float NAG_ZERO = -POS_ZERO;
NearZero(float val)30 inline bool NearZero(float val)
31 {
32     return val < POS_ZERO && val > NAG_ZERO;
33 }
34 
NearEqual(float left,float right)35 inline bool NearEqual(float left, float right) { return std::abs(left - right) < POS_ZERO; }
36 
ToRadians(float degrees)37 inline float ToRadians(float degrees)
38 {
39     return degrees * PI / 180.0f;
40 }
41 
ToDegrees(float radians)42 inline float ToDegrees(float radians)
43 {
44     return radians * 180.0f / PI;
45 }
46 
LessNotEqual(double left,double right)47 inline bool LessNotEqual(double left, double right)
48 {
49     static constexpr double eps = -0.001f;
50     return (left - right) < eps;
51 }
52 
GreatNotEqual(double left,double right)53 inline bool GreatNotEqual(double left, double right)
54 {
55     static constexpr double eps = 0.001f;
56     return (left - right) > eps;
57 }
58 
59 template <typename T>
Max(const T & a,const T & b)60 T Max(const T& a, const T& b)
61 {
62     return (a < b ? b : a);
63 }
64 
65 template <typename T, typename... Ts>
Max(const T & a,const Ts &...bs)66 T Max(const T& a, const Ts&... bs)
67 {
68     return Max(a, Max(bs...));
69 }
70 
71 template <typename T>
Min(const T & a,const T & b)72 T Min(const T& a, const T& b)
73 {
74     return (a < b ? a : b);
75 }
76 
77 template <typename T, typename... Ts>
Min(const T & a,const Ts &...bs)78 T Min(const T& a, const Ts&... bs)
79 {
80     return Min(a, Min(bs...));
81 }
82 
83 template <typename T>
Clamp(const T & value,const T & lower,const T & upper)84 T Clamp(const T& value, const T& lower, const T& upper)
85 {
86     return Min(upper, Max(lower, value));
87 }
88 
NonZero(float val)89 inline float NonZero(float val)
90 {
91     if (!NearZero(val)) {
92         return val;
93     }
94     return val > 0 ? POS_ZERO : NAG_ZERO;
95 }
96 
Floor(float val)97 inline int32_t Floor(float val)
98 {
99     return static_cast<int32_t>(std::floor(val));
100 }
101 
Ceil(float val)102 inline int32_t Ceil(float val)
103 {
104     return static_cast<int32_t>(std::ceil(val));
105 }
106 } // namespace MathHelper
107 
108 namespace TimeHelper {
GetDuration(std::chrono::time_point<std::chrono::high_resolution_clock> t0,std::chrono::time_point<std::chrono::high_resolution_clock> t1)109 inline float GetDuration(std::chrono::time_point<std::chrono::high_resolution_clock> t0,
110     std::chrono::time_point<std::chrono::high_resolution_clock> t1)
111 {
112     return static_cast<float>(std::chrono::duration<float, std::milli>(t1 - t0).count());
113 }
114 }
115 
116 namespace TransformHelper {
117 struct Vector2 {
118     float x_, y_;
Vector2Vector2119     Vector2() : x_(0.0f), y_(0.0f) {}
Vector2Vector2120     Vector2(float inX, float inY)
121         : x_(inX), y_(inY) {}
122     friend Vector2 operator-(const Vector2& v)
123     {
124         return Vector2 { -v.x_, -v.y_ };
125     }
126     friend Vector2 operator+(const Vector2& a, const Vector2& b)
127     {
128         return Vector2 { a.x_ + b.x_, a.y_ + b.y_ };
129     }
130     friend Vector2 operator-(const Vector2& a, const Vector2& b)
131     {
132         return Vector2 { a.x_ - b.x_, a.y_ - b.y_ };
133     }
LengthSqVector2134     float LengthSq() const
135     {
136         return (x_ * x_ + y_ * y_);
137     }
LengthVector2138     float Length() const
139     {
140         return (std::sqrt(LengthSq()));
141     }
142 };
143 
144 struct Vector3 {
145     float x_, y_, z_;
Vector3Vector3146     Vector3() : x_(0.0f), y_(0.0f), z_(0.0f) {}
Vector3Vector3147     Vector3(float inX, float inY, float inZ)
148         : x_(inX), y_(inY), z_(inZ) {}
149     friend Vector3 operator-(const Vector3& v)
150     {
151         return Vector3 { -v.x_, -v.y_, -v.z_ };
152     }
153     friend Vector3 operator+(const Vector3& a, const Vector3& b)
154     {
155         return Vector3 { a.x_ + b.x_, a.y_ + b.y_, a.z_ + b.z_ };
156     }
157     friend Vector3 operator-(const Vector3& a, const Vector3& b)
158     {
159         return Vector3 { a.x_ - b.x_, a.y_ - b.y_, a.z_ - b.z_ };
160     }
161     // Scalar multiplication
162     friend Vector3 operator*(const Vector3& vec, float scalar)
163     {
164         return Vector3(vec.x_ * scalar, vec.y_ * scalar, vec.z_ * scalar);
165     }
166     // Scalar multiplication
167     friend Vector3 operator*(float scalar, const Vector3& vec)
168     {
169         return Vector3(vec.x_ * scalar, vec.y_ * scalar, vec.z_ * scalar);
170     }
171     // Scalar *=
172     Vector3& operator*=(float scalar)
173     {
174         x_ *= scalar;
175         y_ *= scalar;
176         z_ *= scalar;
177         return *this;
178     }
LengthSqVector3179     float LengthSq() const
180     {
181         return (x_ * x_ + y_ * y_ + z_ * z_);
182     }
LengthVector3183     float Length() const
184     {
185         return (std::sqrt(LengthSq()));
186     }
NormalizeVector3187     void Normalize()
188     {
189         float length = Length();
190         if (length > MathHelper::POS_ZERO) {
191             x_ /= length;
192             y_ /= length;
193             z_ /= length;
194         }
195     }
NormalizeVector3196     static Vector3 Normalize(const Vector3& vec)
197     {
198         Vector3 temp = vec;
199         temp.Normalize();
200         return temp;
201     }
DotVector3202     static float Dot(const Vector3& a, const Vector3& b)
203     {
204         return (a.x_ * b.x_ + a.y_ * b.y_ + a.z_ * b.z_);
205     }
CrossVector3206     static Vector3 Cross(const Vector3& a, const Vector3& b)
207     {
208         Vector3 temp;
209         temp.x_ = a.y_ * b.z_ - a.z_ * b.y_;
210         temp.y_ = a.z_ * b.x_ - a.x_ * b.z_;
211         temp.z_ = a.x_ * b.y_ - a.y_ * b.x_;
212         return temp;
213     }
214 };
215 
216 struct Matrix3 {
217     float mat_[3][3];
218 
219     friend Matrix3 operator*(const Matrix3& left, const Matrix3& right);
220     Matrix3& operator*=(const Matrix3& right);
221     static const Matrix3 Identity;
222 };
223 
224 struct Matrix4 {
225     float mat_[4][4];
226 
227     friend Matrix4 operator*(const Matrix4& left, const Matrix4& right);
228     Matrix4& operator*=(const Matrix4& right);
229     void SwapRow(int row1, int row2);
230     // Inverse matrix with Gauss-Jordan method
231     void Invert();
232     // Extract the scale component from the matrix
233     Vector3 GetScale() const;
234     // Get the translation component of the matrix
235     Vector3 GetTranslation() const;
236     static const Matrix4 Identity;
237     static constexpr int MAT_SIZE = 4;
238 };
239 
240 // Create a scale matrix with x and y scales(in xy-plane)
241 Matrix3 CreateScale(float xScale, float yScale);
242 // Create a rotation matrix about the Z axis
243 // theta is in radians
244 Matrix3 CreateRotation(float theta);
245 // Create a translation matrix (on the xy-plane)
246 Matrix3 CreateTranslation(const Vector2& trans);
247 // Create a scale matrix with x, y, and z scales
248 Matrix4 CreateScale(float xScale, float yScale, float zScale);
249 // Create a rotation matrix about X axis
250 // theta is in radians
251 Matrix4 CreateRotationX(float theta);
252 // Create a rotation matrix about Y axis
253 // theta is in radians
254 Matrix4 CreateRotationY(float theta);
255 // Create a rotation matrix about Z axis
256 // theta is in radians
257 Matrix4 CreateRotationZ(float theta);
258 // Create a 3D translation matrix
259 Matrix4 CreateTranslation(const Vector3& trans);
260 Matrix4 CreateLookAt(const Vector3& eye, const Vector3& target, const Vector3& up);
261 Matrix4 CreatePerspective(const Vector3& camera);
262 // Transform a Vector2 in xy-plane by matrix3
263 Vector2 Transform(const Vector2& vec, const Matrix3& mat);
264 // Transform a Vector3 in 3D world by matrix4
265 Vector3 Transform(const Vector3& vec, const Matrix4& mat);
266 // Transform the vector and renormalize the w component
267 Vector3 TransformWithPerspDiv(const Vector3& vec, const Matrix4& mat, float w = 1.0f);
268 // Given a screen point, unprojects it into origin position at screen,
269 // based on the current transform matrix
270 Vector2 GetOriginScreenPoint(const Vector2& p, const Matrix4& mat);
271 } // namespace TransformHelper
272 } // namespace OHOS::Rosen
273 #endif // OHOS_ROSEN_WM_MATH_H