• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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 RENDER_SERVICE_CLIENT_CORE_COMMON_RS_MATRIX3_H
17 #define RENDER_SERVICE_CLIENT_CORE_COMMON_RS_MATRIX3_H
18 
19 #define USE_MATH_DEFINES
20 #include <cmath>
21 
22 #include "common/rs_macros.h"
23 #include "common/rs_vector2.h"
24 #include "common/rs_vector3.h"
25 
26 // column-major order
27 namespace OHOS {
28 namespace Rosen {
29 template<typename T>
30 class Matrix3 {
31 public:
32     static const Matrix3 ZERO;
33     static const Matrix3 IDENTITY;
34     Matrix3();
35     Matrix3(T m00, T m01, T m02, T m10, T m11, T m12, T m20, T m21, T m22);
36 
37     Matrix3(const Matrix3& matrix) noexcept = default;
38 
39     explicit Matrix3(const T* v);
40 
41     ~Matrix3();
42     T Trace() const;
43     static int Index(int row, int col);
44     void SetIdentity();
45     void SetZero();
46     bool IsIdentity() const;
47     Matrix3 Inverse() const;
48     Matrix3 Multiply(const Matrix3& other) const;
49 
50     Matrix3 operator+(const Matrix3& other) const;
51     Matrix3 operator-(const Matrix3& other) const;
52     Matrix3 operator-() const;
53     Matrix3 operator*(const Matrix3& other) const;
54     Vector3<T> operator*(const Vector3<T>& other) const;
55     Matrix3 operator*(T scale) const;
56     T* operator[](int col);
57     Matrix3& operator=(const Matrix3& other);
58     Matrix3& operator+=(const Matrix3& other);
59     Matrix3& operator-=(const Matrix3& other);
60     Matrix3& operator*=(const Matrix3& other);
61     Matrix3& operator*=(T scale);
62     bool operator==(const Matrix3& other) const;
63     bool operator!=(const Matrix3& other) const;
64     bool IsNearEqual(const Matrix3& other, T threshold = std::numeric_limits<T>::epsilon()) const;
65     T* GetData();
66     const T* GetConstData() const;
67     T Determinant() const;
68     Matrix3 Transpose() const;
69     Matrix3 Translate(const Vector2<T>& vec) const;
70     Matrix3 Rotate(T angle) const;
71     Matrix3 Rotate(T angle, T pivotx, T pivoty) const;
72     Matrix3 Scale(const Vector2<T>& vec) const;
73     Matrix3 Scale(const Vector2<T>& vec, T pivotx, T pivoty) const;
74     Matrix3 ShearX(T y) const;
75     Matrix3 ShearY(T x) const;
76 
77 protected:
78     T data_[9] = { 0 };
79 };
80 
81 typedef Matrix3<float> Matrix3f;
82 typedef Matrix3<double> Matrix3d;
83 
84 template<typename T>
85 const Matrix3<T> Matrix3<T>::ZERO(0, 0, 0, 0, 0, 0, 0, 0, 0);
86 
87 template<typename T>
88 const Matrix3<T> Matrix3<T>::IDENTITY(1, 0, 0, 0, 1, 0, 0, 0, 1);
89 
90 template<typename T>
Matrix3()91 Matrix3<T>::Matrix3()
92 {}
93 
94 template<typename T>
Matrix3(T m00,T m01,T m02,T m10,T m11,T m12,T m20,T m21,T m22)95 Matrix3<T>::Matrix3(T m00, T m01, T m02, T m10, T m11, T m12, T m20, T m21, T m22)
96 {
97     data_[0] = m00;
98     data_[1] = m01;
99     data_[2] = m02;
100 
101     data_[3] = m10;
102     data_[4] = m11;
103     data_[5] = m12;
104 
105     data_[6] = m20;
106     data_[7] = m21;
107     data_[8] = m22;
108 }
109 
110 template<typename T>
Matrix3(const T * v)111 Matrix3<T>::Matrix3(const T* v)
112 {
113     std::copy_n(v, std::size(data_), data_);
114 }
115 
116 template<typename T>
~Matrix3()117 Matrix3<T>::~Matrix3()
118 {}
119 
120 template<typename T>
Trace()121 T Matrix3<T>::Trace() const
122 {
123     T rTrace = 0.0;
124     rTrace += data_[0];
125     rTrace += data_[4];
126     rTrace += data_[8];
127     return rTrace;
128 }
129 
130 template<typename T>
Index(int row,int col)131 int Matrix3<T>::Index(int row, int col)
132 {
133     return (col * 3) + row;
134 }
135 
136 template<typename T>
SetIdentity()137 void Matrix3<T>::SetIdentity()
138 {
139     *this = IDENTITY;
140 }
141 
142 template<typename T>
SetZero()143 void Matrix3<T>::SetZero()
144 {
145     *this = ZERO;
146 }
147 
148 template<typename T>
IsIdentity()149 bool Matrix3<T>::IsIdentity() const
150 {
151     return (ROSEN_EQ<T>(data_[0], 1.0)) && (ROSEN_EQ<T>(data_[1], 0.0)) && (ROSEN_EQ<T>(data_[2], 0.0)) &&
152            (ROSEN_EQ<T>(data_[3], 0.0)) && (ROSEN_EQ<T>(data_[4], 1.0)) && (ROSEN_EQ<T>(data_[5], 0.0)) &&
153            (ROSEN_EQ<T>(data_[6], 0.0)) && (ROSEN_EQ<T>(data_[7], 0.0)) && (ROSEN_EQ<T>(data_[8], 1.0));
154 }
155 
156 template<typename T>
Inverse()157 Matrix3<T> Matrix3<T>::Inverse() const
158 {
159     T det = Determinant();
160     if (ROSEN_EQ<T>(det, 0.0)) {
161         return Matrix3<T>(*this);
162     }
163 
164     const T invDet = 1.0f / det;
165     const T* data = data_;
166 
167     T iX = invDet * (data[4] * data[8] - data[5] * data[7]);
168     T iY = invDet * (data[2] * data[7] - data[1] * data[8]);
169     T iZ = invDet * (data[1] * data[5] - data[2] * data[4]);
170     T jX = invDet * (data[5] * data[6] - data[3] * data[8]);
171     T jY = invDet * (data[0] * data[8] - data[2] * data[6]);
172     T jZ = invDet * (data[2] * data[3] - data[0] * data[5]);
173     T kX = invDet * (data[3] * data[7] - data[4] * data[6]);
174     T kY = invDet * (data[1] * data[6] - data[0] * data[7]);
175     T kZ = invDet * (data[0] * data[4] - data[1] * data[3]);
176 
177     return Matrix3<T>(iX, iY, iZ, jX, jY, jZ, kX, kY, kZ);
178 }
179 
180 template<typename T>
Multiply(const Matrix3<T> & other)181 Matrix3<T> Matrix3<T>::Multiply(const Matrix3<T>& other) const
182 {
183     Matrix3<T> rMulti;
184     T* rData = rMulti.data_;
185     const T* oData = other.data_;
186 
187     rData[0] = data_[0] * oData[0] + data_[3] * oData[1] + data_[6] * oData[2];
188     rData[3] = data_[0] * oData[3] + data_[3] * oData[4] + data_[6] * oData[5];
189     rData[6] = data_[0] * oData[6] + data_[3] * oData[7] + data_[6] * oData[8];
190 
191     rData[1] = data_[1] * oData[0] + data_[4] * oData[1] + data_[7] * oData[2];
192     rData[4] = data_[1] * oData[3] + data_[4] * oData[4] + data_[7] * oData[5];
193     rData[7] = data_[1] * oData[6] + data_[4] * oData[7] + data_[7] * oData[8];
194 
195     rData[2] = data_[2] * oData[0] + data_[5] * oData[1] + data_[8] * oData[2];
196     rData[5] = data_[2] * oData[3] + data_[5] * oData[4] + data_[8] * oData[5];
197     rData[8] = data_[2] * oData[6] + data_[5] * oData[7] + data_[8] * oData[8];
198     return rMulti;
199 }
200 
201 template<typename T>
202 Matrix3<T> Matrix3<T>::operator+(const Matrix3<T>& other) const
203 {
204     Matrix3<T> rMat3Add;
205     T* rMat3Data = rMat3Add.data_;
206     const T* oData = other.data_;
207 
208     rMat3Data[0] = data_[0] + oData[0];
209     rMat3Data[1] = data_[1] + oData[1];
210     rMat3Data[2] = data_[2] + oData[2];
211     rMat3Data[3] = data_[3] + oData[3];
212     rMat3Data[4] = data_[4] + oData[4];
213     rMat3Data[5] = data_[5] + oData[5];
214     rMat3Data[6] = data_[6] + oData[6];
215     rMat3Data[7] = data_[7] + oData[7];
216     rMat3Data[8] = data_[8] + oData[8];
217 
218     return rMat3Add;
219 }
220 
221 template<typename T>
222 Matrix3<T> Matrix3<T>::operator-(const Matrix3<T>& other) const
223 {
224     return *this + (-other);
225 }
226 
227 template<typename T>
228 Matrix3<T> Matrix3<T>::operator-() const
229 {
230     Matrix3<T> rMat3Sub;
231     T* rMat3Data = rMat3Sub.data_;
232 
233     rMat3Data[0] = -data_[0];
234     rMat3Data[1] = -data_[1];
235     rMat3Data[2] = -data_[2];
236     rMat3Data[3] = -data_[3];
237     rMat3Data[4] = -data_[4];
238     rMat3Data[5] = -data_[5];
239     rMat3Data[6] = -data_[6];
240     rMat3Data[7] = -data_[7];
241     rMat3Data[8] = -data_[8];
242 
243     return rMat3Sub;
244 }
245 
246 template<typename T>
247 Matrix3<T> Matrix3<T>::operator*(const Matrix3<T>& other) const
248 {
249     return Multiply(other);
250 }
251 
252 template<typename T>
253 Vector3<T> Matrix3<T>::operator*(const Vector3<T>& other) const
254 {
255     Vector3<T> rMulti;
256     T* rData = rMulti.data_;
257     const T* oData = other.data_;
258     rData[0] = data_[0] * oData[0] + data_[3] * oData[1] + data_[6] * oData[2];
259 
260     rData[1] = data_[1] * oData[0] + data_[4] * oData[1] + data_[7] * oData[2];
261 
262     rData[2] = data_[2] * oData[0] + data_[5] * oData[1] + data_[8] * oData[2];
263     return rMulti;
264 }
265 
266 template<typename T>
267 Matrix3<T> Matrix3<T>::operator*(T scale) const
268 {
269     Matrix3<T> rMulti;
270     T* rData = rMulti.data_;
271     rData[0] = data_[0] * scale;
272     rData[1] = data_[1] * scale;
273     rData[2] = data_[2] * scale;
274     rData[3] = data_[3] * scale;
275     rData[4] = data_[4] * scale;
276     rData[5] = data_[5] * scale;
277     rData[6] = data_[6] * scale;
278     rData[7] = data_[7] * scale;
279     rData[8] = data_[8] * scale;
280 
281     return rMulti;
282 }
283 
284 template<typename T>
285 T* Matrix3<T>::operator[](int col)
286 {
287     return &data_[col * 3];
288 }
289 
290 template<typename T>
291 Matrix3<T>& Matrix3<T>::operator=(const Matrix3<T>& other)
292 {
293     const T* oMat3Data = other.data_;
294     T data0 = oMat3Data[0];
295     T data1 = oMat3Data[1];
296     T data2 = oMat3Data[2];
297     T data3 = oMat3Data[3];
298     T data4 = oMat3Data[4];
299     T data5 = oMat3Data[5];
300     T data6 = oMat3Data[6];
301     T data7 = oMat3Data[7];
302     T data8 = oMat3Data[8];
303     data_[0] = data0;
304     data_[1] = data1;
305     data_[2] = data2;
306     data_[3] = data3;
307     data_[4] = data4;
308     data_[5] = data5;
309     data_[6] = data6;
310     data_[7] = data7;
311     data_[8] = data8;
312 
313     return *this;
314 }
315 
316 template<typename T>
317 Matrix3<T>& Matrix3<T>::operator+=(const Matrix3<T>& other)
318 {
319     const T* oData = other.data_;
320 
321     data_[0] += oData[0];
322     data_[1] += oData[1];
323     data_[2] += oData[2];
324     data_[3] += oData[3];
325     data_[4] += oData[4];
326     data_[5] += oData[5];
327     data_[6] += oData[6];
328     data_[7] += oData[7];
329     data_[8] += oData[8];
330 
331     return *this;
332 }
333 
334 template<typename T>
335 Matrix3<T>& Matrix3<T>::operator-=(const Matrix3<T>& other)
336 {
337     const T* oData = other.data_;
338 
339     data_[0] -= oData[0];
340     data_[1] -= oData[1];
341     data_[2] -= oData[2];
342     data_[3] -= oData[3];
343     data_[4] -= oData[4];
344     data_[5] -= oData[5];
345     data_[6] -= oData[6];
346     data_[7] -= oData[7];
347     data_[8] -= oData[8];
348 
349     return *this;
350 }
351 
352 template<typename T>
353 Matrix3<T>& Matrix3<T>::operator*=(const Matrix3<T>& other)
354 {
355     return (*this = *this * other);
356 }
357 
358 template<typename T>
359 Matrix3<T>& Matrix3<T>::operator*=(T scale)
360 {
361     data_[0] *= scale;
362     data_[1] *= scale;
363     data_[2] *= scale;
364     data_[3] *= scale;
365     data_[4] *= scale;
366     data_[5] *= scale;
367     data_[6] *= scale;
368     data_[7] *= scale;
369     data_[8] *= scale;
370     return *this;
371 }
372 
373 template<typename T>
374 bool Matrix3<T>::operator==(const Matrix3& other) const
375 {
376     const T* oData = other.data_;
377 
378     return (ROSEN_EQ<T>(data_[0], oData[0])) && (ROSEN_EQ<T>(data_[1], oData[1])) &&
379            (ROSEN_EQ<T>(data_[2], oData[2])) && (ROSEN_EQ<T>(data_[3], oData[3])) &&
380            (ROSEN_EQ<T>(data_[4], oData[4])) && (ROSEN_EQ<T>(data_[5], oData[5])) &&
381            (ROSEN_EQ<T>(data_[6], oData[6])) && (ROSEN_EQ<T>(data_[7], oData[7])) && (ROSEN_EQ<T>(data_[8], oData[8]));
382 }
383 
384 template<typename T>
385 bool Matrix3<T>::operator!=(const Matrix3& other) const
386 {
387     return !operator==(other);
388 }
389 
390 template<typename T>
IsNearEqual(const Matrix3 & other,T threshold)391 bool Matrix3<T>::IsNearEqual(const Matrix3& other, T threshold) const
392 {
393     const T* otherData = other.data_;
394     auto result = std::equal(data_, data_ + 8, otherData,
395         [&threshold](const T& left, const T& right) { return ROSEN_EQ<T>(left, right, threshold); });
396     return result;
397 }
398 
399 template<typename T>
GetData()400 inline T* Matrix3<T>::GetData()
401 {
402     return data_;
403 }
404 
405 template<typename T>
GetConstData()406 const T* Matrix3<T>::GetConstData() const
407 {
408     return data_;
409 }
410 
411 template<typename T>
Determinant()412 T Matrix3<T>::Determinant() const
413 {
414     T x = data_[0] * ((data_[4] * data_[8]) - (data_[5] * data_[7]));
415     T y = data_[1] * ((data_[3] * data_[8]) - (data_[5] * data_[6]));
416     T z = data_[2] * ((data_[3] * data_[7]) - (data_[4] * data_[6]));
417     return x - y + z;
418 }
419 
420 template<typename T>
Transpose()421 Matrix3<T> Matrix3<T>::Transpose() const
422 {
423     Matrix3<T> rTrans;
424     T* rData = rTrans.data_;
425     rData[0] = data_[0];
426     rData[1] = data_[3];
427     rData[2] = data_[6];
428     rData[3] = data_[1];
429     rData[4] = data_[4];
430     rData[5] = data_[7];
431     rData[6] = data_[2];
432     rData[7] = data_[5];
433     rData[8] = data_[8];
434     return rTrans;
435 }
436 
437 template<typename T>
Translate(const Vector2<T> & vec)438 Matrix3<T> Matrix3<T>::Translate(const Vector2<T>& vec) const
439 {
440     Matrix3<T> rTrans(*this);
441     T* rData = rTrans.data_;
442 
443     rData[6] = data_[0] * vec[0] + data_[3] * vec[1] + data_[6];
444     rData[7] = data_[1] * vec[0] + data_[4] * vec[1] + data_[7];
445     rData[8] = data_[2] * vec[0] + data_[5] * vec[1] + data_[8];
446     return rTrans;
447 }
448 
449 template<typename T>
Rotate(T angle)450 Matrix3<T> Matrix3<T>::Rotate(T angle) const
451 {
452     T a = angle;
453     T c = cos(a);
454     T s = sin(a);
455 
456     Matrix3<T> rRotate(*this);
457     T* rData = rRotate.data_;
458     rData[0] = data_[0] * c + data_[3] * s;
459     rData[1] = data_[1] * c + data_[4] * s;
460     rData[2] = data_[2] * c + data_[5] * s;
461 
462     rData[3] = data_[0] * -s + data_[3] * c;
463     rData[4] = data_[1] * -s + data_[4] * c;
464     rData[5] = data_[2] * -s + data_[5] * c;
465     return rRotate;
466 }
467 
468 template<typename T>
Rotate(T angle,T pivotx,T pivoty)469 Matrix3<T> Matrix3<T>::Rotate(T angle, T pivotx, T pivoty) const
470 {
471     T a = angle;
472     T c = cos(a);
473     T s = sin(a);
474     T dx = s * pivoty + (1 - c) * pivotx;
475     T dy = -s * pivotx + (1 - c) * pivoty;
476 
477     Matrix3<T> rRotate(*this);
478     T* rData = rRotate.data_;
479     rData[0] = data_[0] * c + data_[3] * s;
480     rData[1] = data_[1] * c + data_[4] * s;
481     rData[2] = data_[2] * c + data_[5] * s;
482 
483     rData[3] = data_[0] * -s + data_[3] * c;
484     rData[4] = data_[1] * -s + data_[4] * c;
485     rData[5] = data_[2] * -s + data_[5] * c;
486 
487     rData[6] = data_[0] * dx + data_[3] * dy + data_[6];
488     rData[7] = data_[1] * dx + data_[4] * dy + data_[7];
489     rData[8] = data_[2] * dx + data_[5] * dy + data_[8];
490     return rRotate;
491 }
492 
493 template<typename T>
Scale(const Vector2<T> & vec)494 Matrix3<T> Matrix3<T>::Scale(const Vector2<T>& vec) const
495 {
496     Matrix3<T> rScale(*this);
497     T* rData = rScale.data_;
498     rData[0] = data_[0] * vec[0];
499     rData[1] = data_[1] * vec[0];
500     rData[2] = data_[2] * vec[0];
501 
502     rData[3] = data_[3] * vec[1];
503     rData[4] = data_[4] * vec[1];
504     rData[5] = data_[5] * vec[1];
505     return rScale;
506 }
507 
508 template<typename T>
Scale(const Vector2<T> & vec,T pivotx,T pivoty)509 Matrix3<T> Matrix3<T>::Scale(const Vector2<T>& vec, T pivotx, T pivoty) const
510 {
511     T dx = pivotx - vec[0] * pivotx;
512     T dy = pivoty - vec[1] * pivoty;
513 
514     Matrix3<T> rScale(*this);
515     T* rData = rScale.data_;
516     rData[0] = data_[0] * vec[0];
517     rData[1] = data_[1] * vec[0];
518     rData[2] = data_[2] * vec[0];
519 
520     rData[3] = data_[3] * vec[1];
521     rData[4] = data_[4] * vec[1];
522     rData[5] = data_[5] * vec[1];
523 
524     rData[6] = data_[0] * dx + data_[3] * dy + data_[6];
525     rData[7] = data_[1] * dx + data_[4] * dy + data_[7];
526     rData[8] = data_[2] * dx + data_[5] * dy + data_[8];
527     return rScale;
528 }
529 
530 template<typename T>
ShearX(T y)531 Matrix3<T> Matrix3<T>::ShearX(T y) const
532 {
533     Matrix3<T> rShear(Matrix3<T>::IDENTITY);
534     rShear.data_[1] = y;
535     return (*this) * rShear;
536 }
537 
538 template<typename T>
ShearY(T x)539 Matrix3<T> Matrix3<T>::ShearY(T x) const
540 {
541     Matrix3<T> rShear(Matrix3<T>::IDENTITY);
542     rShear.data_[3] = x;
543     return (*this) * rShear;
544 }
545 } // namespace Rosen
546 } // namespace OHOS
547 #endif // RENDER_SERVICE_CLIENT_CORE_COMMON_RS_MATRIX3_H
548