master
ブランチ master
VulkanExample / dep / include / glm / detail / type_mat4x4.inl
24.6 KB、621行 生 Blame 履歴
1#include "../matrix.hpp"
2#include "../geometric.hpp"
3
4namespace glm
5{
6 // -- Constructors --
7
8# if GLM_CONFIG_CTOR_INIT == GLM_ENABLE
9 template<typename T, qualifier Q>
10 GLM_DEFAULTED_DEFAULT_CTOR_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat()
11 : value{col_type(1, 0, 0, 0), col_type(0, 1, 0, 0), col_type(0, 0, 1, 0), col_type(0, 0, 0, 1)}
12 {}
13# endif
14
15 template<typename T, qualifier Q>
16 template<qualifier P>
17 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(mat<4, 4, T, P> const& m)
18 : value{col_type(m[0]), col_type(m[1]), col_type(m[2]), col_type(m[3])}
19 {}
20
21 template<typename T, qualifier Q>
22 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(T s)
23 : value{col_type(s, 0, 0, 0), col_type(0, s, 0, 0), col_type(0, 0, s, 0), col_type(0, 0, 0, s)}
24 {}
25
26 template<typename T, qualifier Q>
27 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat
28 (
29 T const& x0, T const& y0, T const& z0, T const& w0,
30 T const& x1, T const& y1, T const& z1, T const& w1,
31 T const& x2, T const& y2, T const& z2, T const& w2,
32 T const& x3, T const& y3, T const& z3, T const& w3
33 )
34 : value{
35 col_type(x0, y0, z0, w0),
36 col_type(x1, y1, z1, w1),
37 col_type(x2, y2, z2, w2),
38 col_type(x3, y3, z3, w3)}
39 {}
40
41 template<typename T, qualifier Q>
42 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(col_type const& v0, col_type const& v1, col_type const& v2, col_type const& v3)
43 : value{col_type(v0), col_type(v1), col_type(v2), col_type(v3)}
44 {}
45
46 template<typename T, qualifier Q>
47 template<typename U, qualifier P>
48 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(mat<4, 4, U, P> const& m)
49 : value{col_type(m[0]), col_type(m[1]), col_type(m[2]), col_type(m[3])}
50 {}
51
52 // -- Conversions --
53
54 template<typename T, qualifier Q>
55 template<
56 typename X1, typename Y1, typename Z1, typename W1,
57 typename X2, typename Y2, typename Z2, typename W2,
58 typename X3, typename Y3, typename Z3, typename W3,
59 typename X4, typename Y4, typename Z4, typename W4>
60 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat
61 (
62 X1 const& x1, Y1 const& y1, Z1 const& z1, W1 const& w1,
63 X2 const& x2, Y2 const& y2, Z2 const& z2, W2 const& w2,
64 X3 const& x3, Y3 const& y3, Z3 const& z3, W3 const& w3,
65 X4 const& x4, Y4 const& y4, Z4 const& z4, W4 const& w4
66 )
67 : value{col_type(x1, y1, z1, w1), col_type(x2, y2, z2, w2), col_type(x3, y3, z3, w3), col_type(x4, y4, z4, w4)}
68 {
69 static_assert(std::numeric_limits<X1>::is_iec559 || std::numeric_limits<X1>::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 1st parameter type invalid.");
70 static_assert(std::numeric_limits<Y1>::is_iec559 || std::numeric_limits<Y1>::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 2nd parameter type invalid.");
71 static_assert(std::numeric_limits<Z1>::is_iec559 || std::numeric_limits<Z1>::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 3rd parameter type invalid.");
72 static_assert(std::numeric_limits<W1>::is_iec559 || std::numeric_limits<W1>::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 4th parameter type invalid.");
73
74 static_assert(std::numeric_limits<X2>::is_iec559 || std::numeric_limits<X2>::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 5th parameter type invalid.");
75 static_assert(std::numeric_limits<Y2>::is_iec559 || std::numeric_limits<Y2>::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 6th parameter type invalid.");
76 static_assert(std::numeric_limits<Z2>::is_iec559 || std::numeric_limits<Z2>::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 7th parameter type invalid.");
77 static_assert(std::numeric_limits<W2>::is_iec559 || std::numeric_limits<W2>::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 8th parameter type invalid.");
78
79 static_assert(std::numeric_limits<X3>::is_iec559 || std::numeric_limits<X3>::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 9th parameter type invalid.");
80 static_assert(std::numeric_limits<Y3>::is_iec559 || std::numeric_limits<Y3>::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 10th parameter type invalid.");
81 static_assert(std::numeric_limits<Z3>::is_iec559 || std::numeric_limits<Z3>::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 11th parameter type invalid.");
82 static_assert(std::numeric_limits<W3>::is_iec559 || std::numeric_limits<W3>::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 12th parameter type invalid.");
83
84 static_assert(std::numeric_limits<X4>::is_iec559 || std::numeric_limits<X4>::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 13th parameter type invalid.");
85 static_assert(std::numeric_limits<Y4>::is_iec559 || std::numeric_limits<Y4>::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 14th parameter type invalid.");
86 static_assert(std::numeric_limits<Z4>::is_iec559 || std::numeric_limits<Z4>::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 15th parameter type invalid.");
87 static_assert(std::numeric_limits<W4>::is_iec559 || std::numeric_limits<W4>::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 16th parameter type invalid.");
88 }
89
90 template<typename T, qualifier Q>
91 template<typename V1, typename V2, typename V3, typename V4>
92 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(vec<4, V1, Q> const& v1, vec<4, V2, Q> const& v2, vec<4, V3, Q> const& v3, vec<4, V4, Q> const& v4)
93 : value{col_type(v1), col_type(v2), col_type(v3), col_type(v4)}
94 {
95 static_assert(std::numeric_limits<V1>::is_iec559 || std::numeric_limits<V1>::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 1st parameter type invalid.");
96 static_assert(std::numeric_limits<V2>::is_iec559 || std::numeric_limits<V2>::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 2nd parameter type invalid.");
97 static_assert(std::numeric_limits<V3>::is_iec559 || std::numeric_limits<V3>::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 3rd parameter type invalid.");
98 static_assert(std::numeric_limits<V4>::is_iec559 || std::numeric_limits<V4>::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 4th parameter type invalid.");
99 }
100
101 // -- Matrix conversions --
102
103 template<typename T, qualifier Q>
104 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(mat<2, 2, T, Q> const& m)
105 : value{col_type(m[0], 0, 0), col_type(m[1], 0, 0), col_type(0, 0, 1, 0), col_type(0, 0, 0, 1)}
106 {}
107
108 template<typename T, qualifier Q>
109 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(mat<3, 3, T, Q> const& m)
110 : value{col_type(m[0], 0), col_type(m[1], 0), col_type(m[2], 0), col_type(0, 0, 0, 1)}
111 {}
112
113 template<typename T, qualifier Q>
114 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(mat<2, 3, T, Q> const& m)
115 : value{col_type(m[0], 0), col_type(m[1], 0), col_type(0, 0, 1, 0), col_type(0, 0, 0, 1)}
116 {}
117
118 template<typename T, qualifier Q>
119 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(mat<3, 2, T, Q> const& m)
120 : value{col_type(m[0], 0, 0), col_type(m[1], 0, 0), col_type(m[2], 1, 0), col_type(0, 0, 0, 1)}
121 {}
122
123 template<typename T, qualifier Q>
124 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(mat<2, 4, T, Q> const& m)
125 : value{col_type(m[0]), col_type(m[1]), col_type(0, 0, 1, 0), col_type(0, 0, 0, 1)}
126 {}
127
128 template<typename T, qualifier Q>
129 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(mat<4, 2, T, Q> const& m)
130 : value{col_type(m[0], 0, 0), col_type(m[1], 0, 0), col_type(0, 0, 1, 0), col_type(0, 0, 0, 1)}
131 {}
132
133 template<typename T, qualifier Q>
134 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(mat<3, 4, T, Q> const& m)
135 : value{col_type(m[0]), col_type(m[1]), col_type(m[2]), col_type(0, 0, 0, 1)}
136 {}
137
138 template<typename T, qualifier Q>
139 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(mat<4, 3, T, Q> const& m)
140 : value{col_type(m[0], 0), col_type(m[1], 0), col_type(m[2], 0), col_type(m[3], 1)}
141 {}
142
143 // -- Accesses --
144
145 template<typename T, qualifier Q>
146 GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<4, 4, T, Q>::col_type & mat<4, 4, T, Q>::operator[](typename mat<4, 4, T, Q>::length_type i) noexcept
147 {
148 GLM_ASSERT_LENGTH(i, this->length());
149 return this->value[i];
150 }
151
152 template<typename T, qualifier Q>
153 GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<4, 4, T, Q>::col_type const& mat<4, 4, T, Q>::operator[](typename mat<4, 4, T, Q>::length_type i) const noexcept
154 {
155 GLM_ASSERT_LENGTH(i, this->length());
156 return this->value[i];
157 }
158
159 // -- Unary arithmetic operators --
160
161 template<typename T, qualifier Q>
162 template<typename U>
163 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>& mat<4, 4, T, Q>::operator=(mat<4, 4, U, Q> const& m)
164 {
165 //memcpy could be faster
166 //memcpy(&this->value, &m.value, 16 * sizeof(valType));
167 this->value[0] = m[0];
168 this->value[1] = m[1];
169 this->value[2] = m[2];
170 this->value[3] = m[3];
171 return *this;
172 }
173
174 template<typename T, qualifier Q>
175 template<typename U>
176 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>& mat<4, 4, T, Q>::operator+=(U s)
177 {
178 this->value[0] += s;
179 this->value[1] += s;
180 this->value[2] += s;
181 this->value[3] += s;
182 return *this;
183 }
184
185 template<typename T, qualifier Q>
186 template<typename U>
187 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>& mat<4, 4, T, Q>::operator+=(mat<4, 4, U, Q> const& m)
188 {
189 this->value[0] += m[0];
190 this->value[1] += m[1];
191 this->value[2] += m[2];
192 this->value[3] += m[3];
193 return *this;
194 }
195
196 template<typename T, qualifier Q>
197 template<typename U>
198 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q> & mat<4, 4, T, Q>::operator-=(U s)
199 {
200 this->value[0] -= s;
201 this->value[1] -= s;
202 this->value[2] -= s;
203 this->value[3] -= s;
204 return *this;
205 }
206
207 template<typename T, qualifier Q>
208 template<typename U>
209 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q> & mat<4, 4, T, Q>::operator-=(mat<4, 4, U, Q> const& m)
210 {
211 this->value[0] -= m[0];
212 this->value[1] -= m[1];
213 this->value[2] -= m[2];
214 this->value[3] -= m[3];
215 return *this;
216 }
217
218 template<typename T, qualifier Q>
219 template<typename U>
220 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q> & mat<4, 4, T, Q>::operator*=(U s)
221 {
222 this->value[0] *= s;
223 this->value[1] *= s;
224 this->value[2] *= s;
225 this->value[3] *= s;
226 return *this;
227 }
228
229 template<typename T, qualifier Q>
230 template<typename U>
231 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q> & mat<4, 4, T, Q>::operator*=(mat<4, 4, U, Q> const& m)
232 {
233 return (*this = *this * m);
234 }
235
236 template<typename T, qualifier Q>
237 template<typename U>
238 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q> & mat<4, 4, T, Q>::operator/=(U s)
239 {
240 this->value[0] /= s;
241 this->value[1] /= s;
242 this->value[2] /= s;
243 this->value[3] /= s;
244 return *this;
245 }
246
247 template<typename T, qualifier Q>
248 template<typename U>
249 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q> & mat<4, 4, T, Q>::operator/=(mat<4, 4, U, Q> const& m)
250 {
251 return *this *= inverse(m);
252 }
253
254 // -- Increment and decrement operators --
255
256 template<typename T, qualifier Q>
257 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q> & mat<4, 4, T, Q>::operator++()
258 {
259 ++this->value[0];
260 ++this->value[1];
261 ++this->value[2];
262 ++this->value[3];
263 return *this;
264 }
265
266 template<typename T, qualifier Q>
267 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q> & mat<4, 4, T, Q>::operator--()
268 {
269 --this->value[0];
270 --this->value[1];
271 --this->value[2];
272 --this->value[3];
273 return *this;
274 }
275
276 template<typename T, qualifier Q>
277 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q> mat<4, 4, T, Q>::operator++(int)
278 {
279 mat<4, 4, T, Q> Result(*this);
280 ++*this;
281 return Result;
282 }
283
284 template<typename T, qualifier Q>
285 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q> mat<4, 4, T, Q>::operator--(int)
286 {
287 mat<4, 4, T, Q> Result(*this);
288 --*this;
289 return Result;
290 }
291
292 // -- Unary constant operators --
293
294 template<typename T, qualifier Q>
295 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q> operator+(mat<4, 4, T, Q> const& m)
296 {
297 return m;
298 }
299
300 template<typename T, qualifier Q>
301 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q> operator-(mat<4, 4, T, Q> const& m)
302 {
303 return mat<4, 4, T, Q>(
304 -m[0],
305 -m[1],
306 -m[2],
307 -m[3]);
308 }
309
310 // -- Binary arithmetic operators --
311
312 template<typename T, qualifier Q>
313 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q> operator+(mat<4, 4, T, Q> const& m, T scalar)
314 {
315 return mat<4, 4, T, Q>(
316 m[0] + scalar,
317 m[1] + scalar,
318 m[2] + scalar,
319 m[3] + scalar);
320 }
321
322 template<typename T, qualifier Q>
323 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q> operator+(T scalar, mat<4, 4, T, Q> const& m)
324 {
325 return mat<4, 4, T, Q>(
326 m[0] + scalar,
327 m[1] + scalar,
328 m[2] + scalar,
329 m[3] + scalar);
330 }
331
332 template<typename T, qualifier Q>
333 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q> operator+(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2)
334 {
335 return mat<4, 4, T, Q>(
336 m1[0] + m2[0],
337 m1[1] + m2[1],
338 m1[2] + m2[2],
339 m1[3] + m2[3]);
340 }
341
342 template<typename T, qualifier Q>
343 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q> operator-(mat<4, 4, T, Q> const& m, T scalar)
344 {
345 return mat<4, 4, T, Q>(
346 m[0] - scalar,
347 m[1] - scalar,
348 m[2] - scalar,
349 m[3] - scalar);
350 }
351
352 template<typename T, qualifier Q>
353 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q> operator-(T scalar, mat<4, 4, T, Q> const& m)
354 {
355 return mat<4, 4, T, Q>(
356 scalar - m[0],
357 scalar - m[1],
358 scalar - m[2],
359 scalar - m[3]);
360 }
361
362 template<typename T, qualifier Q>
363 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q> operator-(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2)
364 {
365 return mat<4, 4, T, Q>(
366 m1[0] - m2[0],
367 m1[1] - m2[1],
368 m1[2] - m2[2],
369 m1[3] - m2[3]);
370 }
371
372 template<typename T, qualifier Q>
373 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q> operator*(mat<4, 4, T, Q> const& m, T scalar)
374 {
375 return mat<4, 4, T, Q>(
376 m[0] * scalar,
377 m[1] * scalar,
378 m[2] * scalar,
379 m[3] * scalar);
380 }
381
382 template<typename T, qualifier Q>
383 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q> operator*(T scalar, mat<4, 4, T, Q> const& m)
384 {
385 return mat<4, 4, T, Q>(
386 m[0] * scalar,
387 m[1] * scalar,
388 m[2] * scalar,
389 m[3] * scalar);
390 }
391
392 template<typename T, qualifier Q>
393 GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<4, 4, T, Q>::col_type operator*
394 (
395 mat<4, 4, T, Q> const& m,
396 typename mat<4, 4, T, Q>::row_type const& v
397 )
398 {
399/*
400 __m128 v0 = _mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(0, 0, 0, 0));
401 __m128 v1 = _mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(1, 1, 1, 1));
402 __m128 v2 = _mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(2, 2, 2, 2));
403 __m128 v3 = _mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(3, 3, 3, 3));
404
405 __m128 m0 = _mm_mul_ps(m[0].data, v0);
406 __m128 m1 = _mm_mul_ps(m[1].data, v1);
407 __m128 a0 = _mm_add_ps(m0, m1);
408
409 __m128 m2 = _mm_mul_ps(m[2].data, v2);
410 __m128 m3 = _mm_mul_ps(m[3].data, v3);
411 __m128 a1 = _mm_add_ps(m2, m3);
412
413 __m128 a2 = _mm_add_ps(a0, a1);
414
415 return typename mat<4, 4, T, Q>::col_type(a2);
416*/
417
418 typename mat<4, 4, T, Q>::col_type const Mov0(v[0]);
419 typename mat<4, 4, T, Q>::col_type const Mov1(v[1]);
420 typename mat<4, 4, T, Q>::col_type const Mul0 = m[0] * Mov0;
421 typename mat<4, 4, T, Q>::col_type const Mul1 = m[1] * Mov1;
422 typename mat<4, 4, T, Q>::col_type const Add0 = Mul0 + Mul1;
423 typename mat<4, 4, T, Q>::col_type const Mov2(v[2]);
424 typename mat<4, 4, T, Q>::col_type const Mov3(v[3]);
425 typename mat<4, 4, T, Q>::col_type const Mul2 = m[2] * Mov2;
426 typename mat<4, 4, T, Q>::col_type const Mul3 = m[3] * Mov3;
427 typename mat<4, 4, T, Q>::col_type const Add1 = Mul2 + Mul3;
428 typename mat<4, 4, T, Q>::col_type const Add2 = Add0 + Add1;
429 return Add2;
430
431/*
432 return typename mat<4, 4, T, Q>::col_type(
433 m[0][0] * v[0] + m[1][0] * v[1] + m[2][0] * v[2] + m[3][0] * v[3],
434 m[0][1] * v[0] + m[1][1] * v[1] + m[2][1] * v[2] + m[3][1] * v[3],
435 m[0][2] * v[0] + m[1][2] * v[1] + m[2][2] * v[2] + m[3][2] * v[3],
436 m[0][3] * v[0] + m[1][3] * v[1] + m[2][3] * v[2] + m[3][3] * v[3]);
437*/
438 }
439
440 template<typename T, qualifier Q>
441 GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<4, 4, T, Q>::row_type operator*
442 (
443 typename mat<4, 4, T, Q>::col_type const& v,
444 mat<4, 4, T, Q> const& m
445 )
446 {
447 return typename mat<4, 4, T, Q>::row_type(
448 glm::dot(m[0], v),
449 glm::dot(m[1], v),
450 glm::dot(m[2], v),
451 glm::dot(m[3], v));
452 }
453
454 template<typename T, qualifier Q>
455 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q> operator*(mat<4, 4, T, Q> const& m1, mat<2, 4, T, Q> const& m2)
456 {
457 return mat<2, 4, T, Q>(
458 m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2] + m1[3][0] * m2[0][3],
459 m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2] + m1[3][1] * m2[0][3],
460 m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2] + m1[3][2] * m2[0][3],
461 m1[0][3] * m2[0][0] + m1[1][3] * m2[0][1] + m1[2][3] * m2[0][2] + m1[3][3] * m2[0][3],
462 m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2] + m1[3][0] * m2[1][3],
463 m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2] + m1[3][1] * m2[1][3],
464 m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1] + m1[2][2] * m2[1][2] + m1[3][2] * m2[1][3],
465 m1[0][3] * m2[1][0] + m1[1][3] * m2[1][1] + m1[2][3] * m2[1][2] + m1[3][3] * m2[1][3]);
466 }
467
468 template<typename T, qualifier Q>
469 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q> operator*(mat<4, 4, T, Q> const& m1, mat<3, 4, T, Q> const& m2)
470 {
471 return mat<3, 4, T, Q>(
472 m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2] + m1[3][0] * m2[0][3],
473 m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2] + m1[3][1] * m2[0][3],
474 m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2] + m1[3][2] * m2[0][3],
475 m1[0][3] * m2[0][0] + m1[1][3] * m2[0][1] + m1[2][3] * m2[0][2] + m1[3][3] * m2[0][3],
476 m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2] + m1[3][0] * m2[1][3],
477 m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2] + m1[3][1] * m2[1][3],
478 m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1] + m1[2][2] * m2[1][2] + m1[3][2] * m2[1][3],
479 m1[0][3] * m2[1][0] + m1[1][3] * m2[1][1] + m1[2][3] * m2[1][2] + m1[3][3] * m2[1][3],
480 m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1] + m1[2][0] * m2[2][2] + m1[3][0] * m2[2][3],
481 m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1] + m1[2][1] * m2[2][2] + m1[3][1] * m2[2][3],
482 m1[0][2] * m2[2][0] + m1[1][2] * m2[2][1] + m1[2][2] * m2[2][2] + m1[3][2] * m2[2][3],
483 m1[0][3] * m2[2][0] + m1[1][3] * m2[2][1] + m1[2][3] * m2[2][2] + m1[3][3] * m2[2][3]);
484 }
485
486 namespace detail
487 {
488 template<typename T, qualifier Q, bool is_aligned>
489 struct mul4x4 {};
490
491 template<typename T, qualifier Q>
492 struct mul4x4<T, Q, true>
493 {
494 GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat<4, 4, T, Q> call(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2)
495 {
496 typename mat<4, 4, T, Q>::col_type const SrcA0 = m1[0];
497 typename mat<4, 4, T, Q>::col_type const SrcA1 = m1[1];
498 typename mat<4, 4, T, Q>::col_type const SrcA2 = m1[2];
499 typename mat<4, 4, T, Q>::col_type const SrcA3 = m1[3];
500
501 typename mat<4, 4, T, Q>::col_type const SrcB0 = m2[0];
502 typename mat<4, 4, T, Q>::col_type const SrcB1 = m2[1];
503 typename mat<4, 4, T, Q>::col_type const SrcB2 = m2[2];
504 typename mat<4, 4, T, Q>::col_type const SrcB3 = m2[3];
505
506 typename mat<4, 4, T, Q>::col_type const tmp0 = glm::fma(SrcA3, splatW(SrcB0), glm::fma(SrcA2, splatZ(SrcB0), glm::fma(SrcA1, splatY(SrcB0), SrcA0 * splatX(SrcB0))));
507 typename mat<4, 4, T, Q>::col_type const tmp1 = glm::fma(SrcA3, splatW(SrcB1), glm::fma(SrcA2, splatZ(SrcB1), glm::fma(SrcA1, splatY(SrcB1), SrcA0 * splatX(SrcB1))));
508 typename mat<4, 4, T, Q>::col_type const tmp2 = glm::fma(SrcA3, splatW(SrcB2), glm::fma(SrcA2, splatZ(SrcB2), glm::fma(SrcA1, splatY(SrcB2), SrcA0 * splatX(SrcB2))));
509 typename mat<4, 4, T, Q>::col_type const tmp3 = glm::fma(SrcA3, splatW(SrcB3), glm::fma(SrcA2, splatZ(SrcB3), glm::fma(SrcA1, splatY(SrcB3), SrcA0 * splatX(SrcB3))));
510
511 return mat < 4, 4, T, Q > (tmp0, tmp1, tmp2, tmp3);
512 }
513 };
514
515 template<typename T, qualifier Q>
516 struct mul4x4<T, Q, false>
517 {
518 GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat<4, 4, T, Q> call(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2)
519 {
520 typename mat<4, 4, T, Q>::col_type const& SrcA0 = m1[0];
521 typename mat<4, 4, T, Q>::col_type const& SrcA1 = m1[1];
522 typename mat<4, 4, T, Q>::col_type const& SrcA2 = m1[2];
523 typename mat<4, 4, T, Q>::col_type const& SrcA3 = m1[3];
524
525 typename mat<4, 4, T, Q>::col_type const& SrcB0 = m2[0];
526 typename mat<4, 4, T, Q>::col_type const& SrcB1 = m2[1];
527 typename mat<4, 4, T, Q>::col_type const& SrcB2 = m2[2];
528 typename mat<4, 4, T, Q>::col_type const& SrcB3 = m2[3];
529
530 // note: the following lines are decomposed to have consistent results between simd and non simd code (prevent rounding error because of operation order)
531 //Result[0] = SrcA3 * SrcB0.w + SrcA2 * SrcB0.z + SrcA1 * SrcB0.y + SrcA0 * SrcB0.x;
532 //Result[1] = SrcA3 * SrcB1.w + SrcA2 * SrcB1.z + SrcA1 * SrcB1.y + SrcA0 * SrcB1.x;
533 //Result[2] = SrcA3 * SrcB2.w + SrcA2 * SrcB2.z + SrcA1 * SrcB2.y + SrcA0 * SrcB2.x;
534 //Result[3] = SrcA3 * SrcB3.w + SrcA2 * SrcB3.z + SrcA1 * SrcB3.y + SrcA0 * SrcB3.x;
535
536 typename mat<4, 4, T, Q>::col_type tmp0 = SrcA0 * SrcB0.x;
537 tmp0 += SrcA1 * SrcB0.y;
538 tmp0 += SrcA2 * SrcB0.z;
539 tmp0 += SrcA3 * SrcB0.w;
540 typename mat<4, 4, T, Q>::col_type tmp1 = SrcA0 * SrcB1.x;
541 tmp1 += SrcA1 * SrcB1.y;
542 tmp1 += SrcA2 * SrcB1.z;
543 tmp1 += SrcA3 * SrcB1.w;
544 typename mat<4, 4, T, Q>::col_type tmp2 = SrcA0 * SrcB2.x;
545 tmp2 += SrcA1 * SrcB2.y;
546 tmp2 += SrcA2 * SrcB2.z;
547 tmp2 += SrcA3 * SrcB2.w;
548 typename mat<4, 4, T, Q>::col_type tmp3 = SrcA0 * SrcB3.x;
549 tmp3 += SrcA1 * SrcB3.y;
550 tmp3 += SrcA2 * SrcB3.z;
551 tmp3 += SrcA3 * SrcB3.w;
552
553 return mat<4, 4, T, Q>(tmp0, tmp1, tmp2, tmp3);
554 }
555 };
556 }
557
558
559 template<typename T, qualifier Q>
560 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q> operator*(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2)
561 {
562 return detail::mul4x4<T, Q, detail::is_aligned<Q>::value>::call(m1, m2);
563 }
564
565 template<typename T, qualifier Q>
566 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q> operator/(mat<4, 4, T, Q> const& m, T scalar)
567 {
568 return mat<4, 4, T, Q>(
569 m[0] / scalar,
570 m[1] / scalar,
571 m[2] / scalar,
572 m[3] / scalar);
573 }
574
575 template<typename T, qualifier Q>
576 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q> operator/(T scalar, mat<4, 4, T, Q> const& m)
577 {
578 return mat<4, 4, T, Q>(
579 scalar / m[0],
580 scalar / m[1],
581 scalar / m[2],
582 scalar / m[3]);
583 }
584
585 template<typename T, qualifier Q>
586 GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<4, 4, T, Q>::col_type operator/(mat<4, 4, T, Q> const& m, typename mat<4, 4, T, Q>::row_type const& v)
587 {
588 return inverse(m) * v;
589 }
590
591 template<typename T, qualifier Q>
592 GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<4, 4, T, Q>::row_type operator/(typename mat<4, 4, T, Q>::col_type const& v, mat<4, 4, T, Q> const& m)
593 {
594 return v * inverse(m);
595 }
596
597 template<typename T, qualifier Q>
598 GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q> operator/(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2)
599 {
600 mat<4, 4, T, Q> m1_copy(m1);
601 return m1_copy /= m2;
602 }
603
604 // -- Boolean operators --
605
606 template<typename T, qualifier Q>
607 GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator==(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2)
608 {
609 return (m1[0] == m2[0]) && (m1[1] == m2[1]) && (m1[2] == m2[2]) && (m1[3] == m2[3]);
610 }
611
612 template<typename T, qualifier Q>
613 GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator!=(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2)
614 {
615 return (m1[0] != m2[0]) || (m1[1] != m2[1]) || (m1[2] != m2[2]) || (m1[3] != m2[3]);
616 }
617}//namespace glm
618
619#if GLM_CONFIG_SIMD == GLM_ENABLE
620# include "type_mat4x4_simd.inl"
621#endif