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 <cmath>
20 #include <limits>
21
22 namespace OHOS::Rosen {
23 namespace MathHelper {
24 constexpr float PI = 3.14159265f;
25 constexpr float INF = std::numeric_limits<float>::infinity();
26 constexpr float NAG_INF = -std::numeric_limits<float>::infinity();
27 constexpr float POS_ZERO = 0.001f;
28 constexpr float NAG_ZERO = -POS_ZERO;
NearZero(float val)29 inline bool NearZero(float val)
30 {
31 return val < POS_ZERO && val > NAG_ZERO;
32 }
33
ToRadians(float degrees)34 inline float ToRadians(float degrees)
35 {
36 return degrees * PI / 180.0f;
37 }
38
ToDegrees(float radians)39 inline float ToDegrees(float radians)
40 {
41 return radians * 180.0f / PI;
42 }
43
LessNotEqual(double left,double right)44 inline bool LessNotEqual(double left, double right)
45 {
46 static constexpr double eps = -0.001f;
47 return (left - right) < eps;
48 }
49
GreatNotEqual(double left,double right)50 inline bool GreatNotEqual(double left, double right)
51 {
52 static constexpr double eps = 0.001f;
53 return (left - right) > eps;
54 }
55
56 template <typename T>
Max(const T & a,const T & b)57 T Max(const T& a, const T& b)
58 {
59 return (a < b ? b : a);
60 }
61
62 template <typename T, typename... Ts>
Max(const T & a,const Ts &...bs)63 T Max(const T& a, const Ts&... bs)
64 {
65 return Max(a, Max(bs...));
66 }
67
68 template <typename T>
Min(const T & a,const T & b)69 T Min(const T& a, const T& b)
70 {
71 return (a < b ? a : b);
72 }
73
74 template <typename T, typename... Ts>
Min(const T & a,const Ts &...bs)75 T Min(const T& a, const Ts&... bs)
76 {
77 return Min(a, Min(bs...));
78 }
79
80 template <typename T>
Clamp(const T & value,const T & lower,const T & upper)81 T Clamp(const T& value, const T& lower, const T& upper)
82 {
83 return Min(upper, Max(lower, value));
84 }
85 } // namespace MathHelper
86
87 namespace TransformHelper {
88 struct Vector2 {
89 float x_, y_;
Vector2Vector290 Vector2() : x_(0.0f), y_(0.0f) {}
Vector2Vector291 Vector2(float inX, float inY)
92 : x_(inX), y_(inY) {}
93 friend Vector2 operator-(const Vector2& v)
94 {
95 return Vector2 { -v.x_, -v.y_ };
96 }
97 friend Vector2 operator+(const Vector2& a, const Vector2& b)
98 {
99 return Vector2 { a.x_ + b.x_, a.y_ + b.y_ };
100 }
101 friend Vector2 operator-(const Vector2& a, const Vector2& b)
102 {
103 return Vector2 { a.x_ - b.x_, a.y_ - b.y_ };
104 }
LengthSqVector2105 float LengthSq() const
106 {
107 return (x_ * x_ + y_ * y_);
108 }
LengthVector2109 float Length() const
110 {
111 return (std::sqrt(LengthSq()));
112 }
113 };
114
115 struct Vector3 {
116 float x_, y_, z_;
Vector3Vector3117 Vector3() : x_(0.0f), y_(0.0f), z_(0.0f) {}
Vector3Vector3118 Vector3(float inX, float inY, float inZ)
119 : x_(inX), y_(inY), z_(inZ) {}
120 friend Vector3 operator-(const Vector3& v)
121 {
122 return Vector3 { -v.x_, -v.y_, -v.z_ };
123 }
124 friend Vector3 operator+(const Vector3& a, const Vector3& b)
125 {
126 return Vector3 { a.x_ + b.x_, a.y_ + b.y_, a.z_ + b.z_ };
127 }
128 friend Vector3 operator-(const Vector3& a, const Vector3& b)
129 {
130 return Vector3 { a.x_ - b.x_, a.y_ - b.y_, a.z_ - b.z_ };
131 }
132 // Scalar multiplication
133 friend Vector3 operator*(const Vector3& vec, float scalar)
134 {
135 return Vector3(vec.x_ * scalar, vec.y_ * scalar, vec.z_ * scalar);
136 }
137 // Scalar multiplication
138 friend Vector3 operator*(float scalar, const Vector3& vec)
139 {
140 return Vector3(vec.x_ * scalar, vec.y_ * scalar, vec.z_ * scalar);
141 }
142 // Scalar *=
143 Vector3& operator*=(float scalar)
144 {
145 x_ *= scalar;
146 y_ *= scalar;
147 z_ *= scalar;
148 return *this;
149 }
LengthSqVector3150 float LengthSq() const
151 {
152 return (x_ * x_ + y_ * y_ + z_ * z_);
153 }
LengthVector3154 float Length() const
155 {
156 return (std::sqrt(LengthSq()));
157 }
NormalizeVector3158 void Normalize()
159 {
160 float length = Length();
161 if (length > MathHelper::POS_ZERO) {
162 x_ /= length;
163 y_ /= length;
164 z_ /= length;
165 }
166 }
NormalizeVector3167 static Vector3 Normalize(const Vector3& vec)
168 {
169 Vector3 temp = vec;
170 temp.Normalize();
171 return temp;
172 }
DotVector3173 static float Dot(const Vector3& a, const Vector3& b)
174 {
175 return (a.x_ * b.x_ + a.y_ * b.y_ + a.z_ * b.z_);
176 }
CrossVector3177 static Vector3 Cross(const Vector3& a, const Vector3& b)
178 {
179 Vector3 temp;
180 temp.x_ = a.y_ * b.z_ - a.z_ * b.y_;
181 temp.y_ = a.z_ * b.x_ - a.x_ * b.z_;
182 temp.z_ = a.x_ * b.y_ - a.y_ * b.x_;
183 return temp;
184 }
185 };
186
187 struct Matrix3 {
188 float mat_[3][3];
189
190 friend Matrix3 operator*(const Matrix3& left, const Matrix3& right);
191 Matrix3& operator*=(const Matrix3& right);
192 static const Matrix3 Identity;
193 };
194
195 struct Matrix4 {
196 float mat_[4][4];
197
198 friend Matrix4 operator*(const Matrix4& left, const Matrix4& right);
199 Matrix4& operator*=(const Matrix4& right);
200 void SwapRow(int row1, int row2);
201 // Inverse matrix with Gauss-Jordan method
202 void Invert();
203 // Extract the scale component from the matrix
204 Vector3 GetScale() const;
205 // Get the translation component of the matrix
206 Vector3 GetTranslation() const;
207 static const Matrix4 Identity;
208 static constexpr int MAT_SIZE = 4;
209 };
210
211 // Create a scale matrix with x and y scales(in xy-plane)
212 Matrix3 CreateScale(float xScale, float yScale);
213 // Create a rotation matrix about the Z axis
214 // theta is in radians
215 Matrix3 CreateRotation(float theta);
216 // Create a translation matrix (on the xy-plane)
217 Matrix3 CreateTranslation(const Vector2& trans);
218 // Create a scale matrix with x, y, and z scales
219 Matrix4 CreateScale(float xScale, float yScale, float zScale);
220 // Create a rotation matrix about X axis
221 // theta is in radians
222 Matrix4 CreateRotationX(float theta);
223 // Create a rotation matrix about Y axis
224 // theta is in radians
225 Matrix4 CreateRotationY(float theta);
226 // Create a rotation matrix about Z axis
227 // theta is in radians
228 Matrix4 CreateRotationZ(float theta);
229 // Create a 3D translation matrix
230 Matrix4 CreateTranslation(const Vector3& trans);
231 Matrix4 CreateLookAt(const Vector3& eye, const Vector3& target, const Vector3& up);
232 Matrix4 CreatePerspective(const Vector3& camera);
233 // Transform a Vector2 in xy-plane by matrix3
234 Vector2 Transform(const Vector2& vec, const Matrix3& mat);
235 // Transform a Vector3 in 3D world by matrix4
236 Vector3 Transform(const Vector3& vec, const Matrix4& mat);
237 // Transform the vector and renormalize the w component
238 Vector3 TransformWithPerspDiv(const Vector3& vec, const Matrix4& mat, float w = 1.0f);
239 // Given a screen point, unprojects it into origin position at screen,
240 // based on the current transform matrix
241 Vector2 GetOriginScreenPoint(const Vector2& p, const Matrix4& mat);
242 } // namespace TransformHelper
243 } // namespace OHOS::Rosen
244 #endif // OHOS_ROSEN_WM_MATH_H