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