• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 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 API_BASE_MATH_MATRIX_H
17 #define API_BASE_MATH_MATRIX_H
18 
19 #include <base/containers/array_view.h>
20 #include <base/math/vector_util.h>
21 #include <base/namespace.h>
22 
23 // m00[0] m01[3] m02[6]
24 // m10[1] m11[4] m12[7]
25 // m20[2] m21[5] m22[8]
26 // m00[0] m01[4] m02[8]  m03[12]
27 // m10[1] m11[5] m12[9]  m13[13]
28 // m20[2] m21[6] m22[10] m23[14]
29 // m30[3] m31[7] m32[11] m33[15]
BASE_BEGIN_NAMESPACE()30 BASE_BEGIN_NAMESPACE()
31 namespace Math {
32 #include <base/math/disable_warning_4201_heading.h>
33 
34 /** @ingroup group_math_matrix */
35 /** Matrix 3X3 presentation in column major format */
36 class Mat3X3 final {
37 public:
38     union {
39         struct {
40             Vec3 x, y, z;
41         };
42         Vec3 base[3];
43         float data[9];
44     };
45 
46     /** Subscript operator */
47     constexpr Vec3& operator[](size_t aIndex)
48     {
49         return base[aIndex];
50     }
51 
52     /** Subscript operator */
53     constexpr const Vec3& operator[](size_t aIndex) const
54     {
55         return base[aIndex];
56     }
57 
58     // Constructors
59     /** Default constructor */
60     inline constexpr Mat3X3() noexcept : data { 0 } {}
61 
62     /** Identity constructor */
63     inline explicit constexpr Mat3X3(float id) noexcept : data { id, 0.0f, 0.0f, 0.0f, id, 0.0f, 0.0f, 0.0f, id } {}
64 
65     /** Constructor for using Vector3's */
66     inline constexpr Mat3X3(Vec3 const& v0, Vec3 const& v1, Vec3 const& v2) noexcept : x(v0), y(v1), z(v2) {}
67 
68     /** Constructor for array of floats */
69     inline constexpr Mat3X3(const float d[9]) noexcept : data { d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8] }
70     {}
71 
72     inline ~Mat3X3() = default;
73 
74     /** Multiply two matrices */
75     inline constexpr Mat3X3 operator*(const Mat3X3& rhs) const
76     {
77         const Vec3& rha { rhs.x.x, rhs.y.x, rhs.z.x };
78         const Vec3& rhb { rhs.x.y, rhs.y.y, rhs.z.y };
79         const Vec3& rhc { rhs.x.z, rhs.y.z, rhs.z.z };
80 
81         return { { Dot(x, rha), Dot(x, rhb), Dot(x, rhc) }, { Dot(y, rha), Dot(y, rhb), Dot(y, rhc) },
82             { Dot(z, rha), Dot(z, rhb), Dot(z, rhc) } };
83     }
84 
85     /** Multiply columns by float scalar value */
86     inline constexpr Mat3X3 operator*(const float& scalar) const
87     {
88         return Mat3X3(x * scalar, y * scalar, z * scalar);
89     }
90 
91     /** Equality operator, returns true if matrices are equal */
92     inline constexpr bool operator==(const Mat3X3& mat) const
93     {
94         for (size_t i = 0; i < countof(data); ++i) {
95             if (data[i] != mat.data[i]) {
96                 return false;
97             }
98         }
99         return true;
100     }
101 
102     /** Inequality operator, returns true if matrices are inequal */
103     inline constexpr bool operator!=(const Mat3X3& mat) const
104     {
105         for (size_t i = 0; i < countof(data); ++i) {
106             if (data[i] != mat.data[i]) {
107                 return true;
108             }
109         }
110         return false;
111     }
112 };
113 
114 // Assert that Mat3X3 is the same as 9 floats
115 static_assert(sizeof(Mat3X3) == 9 * sizeof(float));
116 
117 static constexpr Mat3X3 IDENTITY_3X3(1.f);
118 
119 /** @ingroup group_math_matrix */
120 /** Matrix 4X4 presentation  in column major format */
121 class Mat4X4 final {
122 public:
123     union {
124         struct {
125             Vec4 x, y, z, w;
126         };
127         Vec4 base[4]; // base[0] is X ,base [1] is Y, etc..
128         float data[16];
129     };
130 
131     // "For programming purposes, OpenGL matrices are 16-value arrays with base vectors laid out contiguously in memory.
132     // The translation components occupy the 13th, 14th, and 15th elements of the 16-element matrix."
133     // https://www.khronos.org/opengl/wiki/General_OpenGL:_Transformations#Are_OpenGL_matrices_column-major_or_row-major.3F
134     // this is also the same as with glm.
135     /** Subscript operator */
136     constexpr Vec4& operator[](size_t aIndex)
137     {
138         return base[aIndex];
139     }
140 
141     /** Subscript operator */
142     constexpr const Vec4& operator[](size_t aIndex) const
143     {
144         return base[aIndex];
145     }
146 
147     // Constructors
148     /** Zero initializer constructor */
149     inline constexpr Mat4X4() : data { 0 } {}
150 
151     /** Constructor for Vector4's */
152     inline constexpr Mat4X4(Vec4 const& v0, Vec4 const& v1, Vec4 const& v2, Vec4 const& v3) : x(v0), y(v1), z(v2), w(v3)
153     {}
154 
155     /** Constructor for array of floats */
156     inline constexpr Mat4X4(const float d[16])
157         : data { d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15] }
158     {}
159 
160     /** Constructor for floats */
161     inline constexpr Mat4X4(float d0, float d1, float d2, float d3, float d4, float d5, float d6, float d7, float d8,
162         float d9, float d10, float d11, float d12, float d13, float d14, float d15)
163         : data { d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15 }
164     {}
165 
166     /** Identity constructor */
167     inline explicit constexpr Mat4X4(float id)
168         : data { id, 0.0f, 0.0f, 0.0f, 0.0f, id, 0.0f, 0.0f, 0.0f, 0.0f, id, 0.0f, 0.0f, 0.0f, 0.0f, id }
169     {}
170 
171     /** Conversion constructor from Mat3X3 to Mat4X4 */
172     explicit inline constexpr Mat4X4(const Mat3X3& mat3X3)
173         : data { mat3X3.data[0], mat3X3.data[1], mat3X3.data[2], 0.0f, mat3X3.data[3], mat3X3.data[4], mat3X3.data[5],
174               0.0f, mat3X3.data[6], mat3X3.data[7], mat3X3.data[8], 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }
175     {}
176 
177     inline ~Mat4X4() = default;
178 
179     /** Multiply two matrices */
180     inline constexpr Mat4X4 operator*(const Mat4X4& rhs) const
181     {
182 #define d data
183         Mat4X4 res;
184         res.d[0] = d[0] * rhs.d[0] + d[4] * rhs.d[1] + d[8] * rhs.d[2] + d[12] * rhs.d[3];
185         res.d[4] = d[0] * rhs.d[4] + d[4] * rhs.d[5] + d[8] * rhs.d[6] + d[12] * rhs.d[7];
186         res.d[8] = d[0] * rhs.d[8] + d[4] * rhs.d[9] + d[8] * rhs.d[10] + d[12] * rhs.d[11];
187         res.d[12] = d[0] * rhs.d[12] + d[4] * rhs.d[13] + d[8] * rhs.d[14] + d[12] * rhs.d[15];
188 
189         res.d[1] = d[1] * rhs.d[0] + d[5] * rhs.d[1] + d[9] * rhs.d[2] + d[13] * rhs.d[3];
190         res.d[5] = d[1] * rhs.d[4] + d[5] * rhs.d[5] + d[9] * rhs.d[6] + d[13] * rhs.d[7];
191         res.d[9] = d[1] * rhs.d[8] + d[5] * rhs.d[9] + d[9] * rhs.d[10] + d[13] * rhs.d[11];
192         res.d[13] = d[1] * rhs.d[12] + d[5] * rhs.d[13] + d[9] * rhs.d[14] + d[13] * rhs.d[15];
193 
194         res.d[2] = d[2] * rhs.d[0] + d[6] * rhs.d[1] + d[10] * rhs.d[2] + d[14] * rhs.d[3];
195         res.d[6] = d[2] * rhs.d[4] + d[6] * rhs.d[5] + d[10] * rhs.d[6] + d[14] * rhs.d[7];
196         res.d[10] = d[2] * rhs.d[8] + d[6] * rhs.d[9] + d[10] * rhs.d[10] + d[14] * rhs.d[11];
197         res.d[14] = d[2] * rhs.d[12] + d[6] * rhs.d[13] + d[10] * rhs.d[14] + d[14] * rhs.d[15];
198 
199         res.d[3] = d[3] * rhs.d[0] + d[7] * rhs.d[1] + d[11] * rhs.d[2] + d[15] * rhs.d[3];
200         res.d[7] = d[3] * rhs.d[4] + d[7] * rhs.d[5] + d[11] * rhs.d[6] + d[15] * rhs.d[7];
201         res.d[11] = d[3] * rhs.d[8] + d[7] * rhs.d[9] + d[11] * rhs.d[10] + d[15] * rhs.d[11];
202         res.d[15] = d[3] * rhs.d[12] + d[7] * rhs.d[13] + d[11] * rhs.d[14] + d[15] * rhs.d[15];
203 #undef d
204         return res;
205     }
206 
207     /** Multiply columns by float scalar value */
208     inline constexpr Mat4X4 operator*(const float& scalar) const
209     {
210         return Mat4X4(x * scalar, y * scalar, z * scalar, w * scalar);
211     }
212 
213     /** Equality operator, returns true if matrices are equal */
214     inline constexpr bool operator==(const Mat4X4& mat) const
215     {
216         for (size_t i = 0; i < countof(data); ++i) {
217             if (data[i] != mat.data[i]) {
218                 return false;
219             }
220         }
221         return true;
222     }
223 
224     /** Inequality operator, returns true if matrices are inequal */
225     inline constexpr bool operator!=(const Mat4X4& mat) const
226     {
227         for (size_t i = 0; i < countof(data); ++i) {
228             if (data[i] != mat.data[i]) {
229                 return true;
230             }
231         }
232         return false;
233     }
234 };
235 
236 // Assert that Mat4X4 is the same as 16 floats
237 static_assert(sizeof(Mat4X4) == 16 * sizeof(float));
238 
239 static constexpr Mat4X4 IDENTITY_4X4(1.f);
240 
241 /*
242 m00[0] m01[4] m02[8]  m03[12]
243 m10[1] m11[5] m12[9]  m13[13]
244 m20[2] m21[6] m22[10] m23[14]
245 m30[3] m31[7] m32[11] m33[15]
246 */
247 #include <base/math/disable_warning_4201_footer.h>
248 } // namespace Math
249 BASE_END_NAMESPACE()
250 
251 #endif // API_BASE_MATH_MATRIX_H
252