Clutter Engine 0.0.1
Loading...
Searching...
No Matches
func_matrix.inl
1#include "../geometric.hpp"
2#include <limits>
3
4namespace glm{
5namespace detail
6{
7 template<length_t C, length_t R, typename T, qualifier Q, bool Aligned>
9 {
10 GLM_FUNC_QUALIFIER static mat<C, R, T, Q> call(mat<C, R, T, Q> const& x, mat<C, R, T, Q> const& y)
11 {
12 mat<C, R, T, Q> Result;
13 for(length_t i = 0; i < Result.length(); ++i)
14 Result[i] = x[i] * y[i];
15 return Result;
16 }
17 };
18
19 template<length_t C, length_t R, typename T, qualifier Q, bool Aligned>
21
22 template<typename T, qualifier Q, bool Aligned>
23 struct compute_transpose<2, 2, T, Q, Aligned>
24 {
25 GLM_FUNC_QUALIFIER static mat<2, 2, T, Q> call(mat<2, 2, T, Q> const& m)
26 {
27 mat<2, 2, T, Q> Result;
28 Result[0][0] = m[0][0];
29 Result[0][1] = m[1][0];
30 Result[1][0] = m[0][1];
31 Result[1][1] = m[1][1];
32 return Result;
33 }
34 };
35
36 template<typename T, qualifier Q, bool Aligned>
37 struct compute_transpose<2, 3, T, Q, Aligned>
38 {
39 GLM_FUNC_QUALIFIER static mat<3, 2, T, Q> call(mat<2, 3, T, Q> const& m)
40 {
41 mat<3,2, T, Q> Result;
42 Result[0][0] = m[0][0];
43 Result[0][1] = m[1][0];
44 Result[1][0] = m[0][1];
45 Result[1][1] = m[1][1];
46 Result[2][0] = m[0][2];
47 Result[2][1] = m[1][2];
48 return Result;
49 }
50 };
51
52 template<typename T, qualifier Q, bool Aligned>
53 struct compute_transpose<2, 4, T, Q, Aligned>
54 {
55 GLM_FUNC_QUALIFIER static mat<4, 2, T, Q> call(mat<2, 4, T, Q> const& m)
56 {
57 mat<4, 2, T, Q> Result;
58 Result[0][0] = m[0][0];
59 Result[0][1] = m[1][0];
60 Result[1][0] = m[0][1];
61 Result[1][1] = m[1][1];
62 Result[2][0] = m[0][2];
63 Result[2][1] = m[1][2];
64 Result[3][0] = m[0][3];
65 Result[3][1] = m[1][3];
66 return Result;
67 }
68 };
69
70 template<typename T, qualifier Q, bool Aligned>
71 struct compute_transpose<3, 2, T, Q, Aligned>
72 {
73 GLM_FUNC_QUALIFIER static mat<2, 3, T, Q> call(mat<3, 2, T, Q> const& m)
74 {
75 mat<2, 3, T, Q> Result;
76 Result[0][0] = m[0][0];
77 Result[0][1] = m[1][0];
78 Result[0][2] = m[2][0];
79 Result[1][0] = m[0][1];
80 Result[1][1] = m[1][1];
81 Result[1][2] = m[2][1];
82 return Result;
83 }
84 };
85
86 template<typename T, qualifier Q, bool Aligned>
87 struct compute_transpose<3, 3, T, Q, Aligned>
88 {
89 GLM_FUNC_QUALIFIER static mat<3, 3, T, Q> call(mat<3, 3, T, Q> const& m)
90 {
91 mat<3, 3, T, Q> Result;
92 Result[0][0] = m[0][0];
93 Result[0][1] = m[1][0];
94 Result[0][2] = m[2][0];
95
96 Result[1][0] = m[0][1];
97 Result[1][1] = m[1][1];
98 Result[1][2] = m[2][1];
99
100 Result[2][0] = m[0][2];
101 Result[2][1] = m[1][2];
102 Result[2][2] = m[2][2];
103 return Result;
104 }
105 };
106
107 template<typename T, qualifier Q, bool Aligned>
108 struct compute_transpose<3, 4, T, Q, Aligned>
109 {
110 GLM_FUNC_QUALIFIER static mat<4, 3, T, Q> call(mat<3, 4, T, Q> const& m)
111 {
112 mat<4, 3, T, Q> Result;
113 Result[0][0] = m[0][0];
114 Result[0][1] = m[1][0];
115 Result[0][2] = m[2][0];
116 Result[1][0] = m[0][1];
117 Result[1][1] = m[1][1];
118 Result[1][2] = m[2][1];
119 Result[2][0] = m[0][2];
120 Result[2][1] = m[1][2];
121 Result[2][2] = m[2][2];
122 Result[3][0] = m[0][3];
123 Result[3][1] = m[1][3];
124 Result[3][2] = m[2][3];
125 return Result;
126 }
127 };
128
129 template<typename T, qualifier Q, bool Aligned>
130 struct compute_transpose<4, 2, T, Q, Aligned>
131 {
132 GLM_FUNC_QUALIFIER static mat<2, 4, T, Q> call(mat<4, 2, T, Q> const& m)
133 {
134 mat<2, 4, T, Q> Result;
135 Result[0][0] = m[0][0];
136 Result[0][1] = m[1][0];
137 Result[0][2] = m[2][0];
138 Result[0][3] = m[3][0];
139 Result[1][0] = m[0][1];
140 Result[1][1] = m[1][1];
141 Result[1][2] = m[2][1];
142 Result[1][3] = m[3][1];
143 return Result;
144 }
145 };
146
147 template<typename T, qualifier Q, bool Aligned>
148 struct compute_transpose<4, 3, T, Q, Aligned>
149 {
150 GLM_FUNC_QUALIFIER static mat<3, 4, T, Q> call(mat<4, 3, T, Q> const& m)
151 {
152 mat<3, 4, T, Q> Result;
153 Result[0][0] = m[0][0];
154 Result[0][1] = m[1][0];
155 Result[0][2] = m[2][0];
156 Result[0][3] = m[3][0];
157 Result[1][0] = m[0][1];
158 Result[1][1] = m[1][1];
159 Result[1][2] = m[2][1];
160 Result[1][3] = m[3][1];
161 Result[2][0] = m[0][2];
162 Result[2][1] = m[1][2];
163 Result[2][2] = m[2][2];
164 Result[2][3] = m[3][2];
165 return Result;
166 }
167 };
168
169 template<typename T, qualifier Q, bool Aligned>
170 struct compute_transpose<4, 4, T, Q, Aligned>
171 {
172 GLM_FUNC_QUALIFIER static mat<4, 4, T, Q> call(mat<4, 4, T, Q> const& m)
173 {
174 mat<4, 4, T, Q> Result;
175 Result[0][0] = m[0][0];
176 Result[0][1] = m[1][0];
177 Result[0][2] = m[2][0];
178 Result[0][3] = m[3][0];
179
180 Result[1][0] = m[0][1];
181 Result[1][1] = m[1][1];
182 Result[1][2] = m[2][1];
183 Result[1][3] = m[3][1];
184
185 Result[2][0] = m[0][2];
186 Result[2][1] = m[1][2];
187 Result[2][2] = m[2][2];
188 Result[2][3] = m[3][2];
189
190 Result[3][0] = m[0][3];
191 Result[3][1] = m[1][3];
192 Result[3][2] = m[2][3];
193 Result[3][3] = m[3][3];
194 return Result;
195 }
196 };
197
198 template<length_t C, length_t R, typename T, qualifier Q, bool Aligned>
200
201 template<typename T, qualifier Q, bool Aligned>
202 struct compute_determinant<2, 2, T, Q, Aligned>
203 {
204 GLM_FUNC_QUALIFIER static T call(mat<2, 2, T, Q> const& m)
205 {
206 return m[0][0] * m[1][1] - m[1][0] * m[0][1];
207 }
208 };
209
210 template<typename T, qualifier Q, bool Aligned>
211 struct compute_determinant<3, 3, T, Q, Aligned>
212 {
213 GLM_FUNC_QUALIFIER static T call(mat<3, 3, T, Q> const& m)
214 {
215 return
216 + m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2])
217 - m[1][0] * (m[0][1] * m[2][2] - m[2][1] * m[0][2])
218 + m[2][0] * (m[0][1] * m[1][2] - m[1][1] * m[0][2]);
219 }
220 };
221
222 template<typename T, qualifier Q, bool Aligned>
223 struct compute_determinant<4, 4, T, Q, Aligned>
224 {
225 GLM_FUNC_QUALIFIER static T call(mat<4, 4, T, Q> const& m)
226 {
227 T SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
228 T SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
229 T SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
230 T SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
231 T SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
232 T SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
233
234 vec<4, T, Q> DetCof(
235 + (m[1][1] * SubFactor00 - m[1][2] * SubFactor01 + m[1][3] * SubFactor02),
236 - (m[1][0] * SubFactor00 - m[1][2] * SubFactor03 + m[1][3] * SubFactor04),
237 + (m[1][0] * SubFactor01 - m[1][1] * SubFactor03 + m[1][3] * SubFactor05),
238 - (m[1][0] * SubFactor02 - m[1][1] * SubFactor04 + m[1][2] * SubFactor05));
239
240 return
241 m[0][0] * DetCof[0] + m[0][1] * DetCof[1] +
242 m[0][2] * DetCof[2] + m[0][3] * DetCof[3];
243 }
244 };
245
246 template<length_t C, length_t R, typename T, qualifier Q, bool Aligned>
248
249 template<typename T, qualifier Q, bool Aligned>
250 struct compute_inverse<2, 2, T, Q, Aligned>
251 {
252 GLM_FUNC_QUALIFIER static mat<2, 2, T, Q> call(mat<2, 2, T, Q> const& m)
253 {
254 T OneOverDeterminant = static_cast<T>(1) / (
255 + m[0][0] * m[1][1]
256 - m[1][0] * m[0][1]);
257
258 mat<2, 2, T, Q> Inverse(
259 + m[1][1] * OneOverDeterminant,
260 - m[0][1] * OneOverDeterminant,
261 - m[1][0] * OneOverDeterminant,
262 + m[0][0] * OneOverDeterminant);
263
264 return Inverse;
265 }
266 };
267
268 template<typename T, qualifier Q, bool Aligned>
269 struct compute_inverse<3, 3, T, Q, Aligned>
270 {
271 GLM_FUNC_QUALIFIER static mat<3, 3, T, Q> call(mat<3, 3, T, Q> const& m)
272 {
273 T OneOverDeterminant = static_cast<T>(1) / (
274 + m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2])
275 - m[1][0] * (m[0][1] * m[2][2] - m[2][1] * m[0][2])
276 + m[2][0] * (m[0][1] * m[1][2] - m[1][1] * m[0][2]));
277
278 mat<3, 3, T, Q> Inverse;
279 Inverse[0][0] = + (m[1][1] * m[2][2] - m[2][1] * m[1][2]) * OneOverDeterminant;
280 Inverse[1][0] = - (m[1][0] * m[2][2] - m[2][0] * m[1][2]) * OneOverDeterminant;
281 Inverse[2][0] = + (m[1][0] * m[2][1] - m[2][0] * m[1][1]) * OneOverDeterminant;
282 Inverse[0][1] = - (m[0][1] * m[2][2] - m[2][1] * m[0][2]) * OneOverDeterminant;
283 Inverse[1][1] = + (m[0][0] * m[2][2] - m[2][0] * m[0][2]) * OneOverDeterminant;
284 Inverse[2][1] = - (m[0][0] * m[2][1] - m[2][0] * m[0][1]) * OneOverDeterminant;
285 Inverse[0][2] = + (m[0][1] * m[1][2] - m[1][1] * m[0][2]) * OneOverDeterminant;
286 Inverse[1][2] = - (m[0][0] * m[1][2] - m[1][0] * m[0][2]) * OneOverDeterminant;
287 Inverse[2][2] = + (m[0][0] * m[1][1] - m[1][0] * m[0][1]) * OneOverDeterminant;
288
289 return Inverse;
290 }
291 };
292
293 template<typename T, qualifier Q, bool Aligned>
294 struct compute_inverse<4, 4, T, Q, Aligned>
295 {
296 GLM_FUNC_QUALIFIER static mat<4, 4, T, Q> call(mat<4, 4, T, Q> const& m)
297 {
298 T Coef00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
299 T Coef02 = m[1][2] * m[3][3] - m[3][2] * m[1][3];
300 T Coef03 = m[1][2] * m[2][3] - m[2][2] * m[1][3];
301
302 T Coef04 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
303 T Coef06 = m[1][1] * m[3][3] - m[3][1] * m[1][3];
304 T Coef07 = m[1][1] * m[2][3] - m[2][1] * m[1][3];
305
306 T Coef08 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
307 T Coef10 = m[1][1] * m[3][2] - m[3][1] * m[1][2];
308 T Coef11 = m[1][1] * m[2][2] - m[2][1] * m[1][2];
309
310 T Coef12 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
311 T Coef14 = m[1][0] * m[3][3] - m[3][0] * m[1][3];
312 T Coef15 = m[1][0] * m[2][3] - m[2][0] * m[1][3];
313
314 T Coef16 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
315 T Coef18 = m[1][0] * m[3][2] - m[3][0] * m[1][2];
316 T Coef19 = m[1][0] * m[2][2] - m[2][0] * m[1][2];
317
318 T Coef20 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
319 T Coef22 = m[1][0] * m[3][1] - m[3][0] * m[1][1];
320 T Coef23 = m[1][0] * m[2][1] - m[2][0] * m[1][1];
321
322 vec<4, T, Q> Fac0(Coef00, Coef00, Coef02, Coef03);
323 vec<4, T, Q> Fac1(Coef04, Coef04, Coef06, Coef07);
324 vec<4, T, Q> Fac2(Coef08, Coef08, Coef10, Coef11);
325 vec<4, T, Q> Fac3(Coef12, Coef12, Coef14, Coef15);
326 vec<4, T, Q> Fac4(Coef16, Coef16, Coef18, Coef19);
327 vec<4, T, Q> Fac5(Coef20, Coef20, Coef22, Coef23);
328
329 vec<4, T, Q> Vec0(m[1][0], m[0][0], m[0][0], m[0][0]);
330 vec<4, T, Q> Vec1(m[1][1], m[0][1], m[0][1], m[0][1]);
331 vec<4, T, Q> Vec2(m[1][2], m[0][2], m[0][2], m[0][2]);
332 vec<4, T, Q> Vec3(m[1][3], m[0][3], m[0][3], m[0][3]);
333
334 vec<4, T, Q> Inv0(Vec1 * Fac0 - Vec2 * Fac1 + Vec3 * Fac2);
335 vec<4, T, Q> Inv1(Vec0 * Fac0 - Vec2 * Fac3 + Vec3 * Fac4);
336 vec<4, T, Q> Inv2(Vec0 * Fac1 - Vec1 * Fac3 + Vec3 * Fac5);
337 vec<4, T, Q> Inv3(Vec0 * Fac2 - Vec1 * Fac4 + Vec2 * Fac5);
338
339 vec<4, T, Q> SignA(+1, -1, +1, -1);
340 vec<4, T, Q> SignB(-1, +1, -1, +1);
341 mat<4, 4, T, Q> Inverse(Inv0 * SignA, Inv1 * SignB, Inv2 * SignA, Inv3 * SignB);
342
343 vec<4, T, Q> Row0(Inverse[0][0], Inverse[1][0], Inverse[2][0], Inverse[3][0]);
344
345 vec<4, T, Q> Dot0(m[0] * Row0);
346 T Dot1 = (Dot0.x + Dot0.y) + (Dot0.z + Dot0.w);
347
348 T OneOverDeterminant = static_cast<T>(1) / Dot1;
349
350 return Inverse * OneOverDeterminant;
351 }
352 };
353}//namespace detail
354
355 template<length_t C, length_t R, typename T, qualifier Q>
356 GLM_FUNC_QUALIFIER mat<C, R, T, Q> matrixCompMult(mat<C, R, T, Q> const& x, mat<C, R, T, Q> const& y)
357 {
358 GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'matrixCompMult' only accept floating-point inputs");
360 }
361
362 template<length_t DA, length_t DB, typename T, qualifier Q>
363 GLM_FUNC_QUALIFIER typename detail::outerProduct_trait<DA, DB, T, Q>::type outerProduct(vec<DA, T, Q> const& c, vec<DB, T, Q> const& r)
364 {
365 GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'outerProduct' only accept floating-point inputs");
366
367 typename detail::outerProduct_trait<DA, DB, T, Q>::type m;
368 for(length_t i = 0; i < m.length(); ++i)
369 m[i] = c * r[i];
370 return m;
371 }
372
373 template<length_t C, length_t R, typename T, qualifier Q>
374 GLM_FUNC_QUALIFIER typename mat<C, R, T, Q>::transpose_type transpose(mat<C, R, T, Q> const& m)
375 {
376 GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'transpose' only accept floating-point inputs");
378 }
379
380 template<length_t C, length_t R, typename T, qualifier Q>
381 GLM_FUNC_QUALIFIER T determinant(mat<C, R, T, Q> const& m)
382 {
383 GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'determinant' only accept floating-point inputs");
385 }
386
387 template<length_t C, length_t R, typename T, qualifier Q>
388 GLM_FUNC_QUALIFIER mat<C, R, T, Q> inverse(mat<C, R, T, Q> const& m)
389 {
390 GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'inverse' only accept floating-point inputs");
392 }
393}//namespace glm
394
395#if GLM_CONFIG_SIMD == GLM_ENABLE
396# include "func_matrix_simd.inl"
397#endif
398
GLM_FUNC_QUALIFIER mat< C, R, T, Q > matrixCompMult(mat< C, R, T, Q > const &x, mat< C, R, T, Q > const &y)
Definition func_matrix.inl:356
GLM_FUNC_QUALIFIER mat< C, R, T, Q > inverse(mat< C, R, T, Q > const &m)
Definition func_matrix.inl:388
GLM_FUNC_QUALIFIER T determinant(mat< C, R, T, Q > const &m)
Definition func_matrix.inl:381
detail namespace with internal helper functions
Definition json.h:249
Core features
Definition common.hpp:21
Definition func_matrix.inl:199
Definition func_matrix.inl:247
Definition func_matrix.inl:9
Definition func_matrix.inl:20
Definition qualifier.hpp:36
Definition qualifier.hpp:35