1///////////////////////////////////////////////////////////////////////////////////
2/// OpenGL Mathematics (glm.g-truc.net)
3///
4/// Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net)
5/// Permission is hereby granted, free of charge, to any person obtaining a copy
6/// of this software and associated documentation files (the "Software"), to deal
7/// in the Software without restriction, including without limitation the rights
8/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9/// copies of the Software, and to permit persons to whom the Software is
10/// furnished to do so, subject to the following conditions:
11///
12/// The above copyright notice and this permission notice shall be included in
13/// all copies or substantial portions of the Software.
14///
15/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21/// THE SOFTWARE.
22///
23/// @ref core
24/// @file glm/core/type_mat3x4.inl
25/// @date 2006-08-05 / 2011-06-15
26/// @author Christophe Riccio
27///////////////////////////////////////////////////////////////////////////////////
28
29namespace glm{
30namespace detail
31{
32	template <typename T, precision P>
33	GLM_FUNC_QUALIFIER GLM_CONSTEXPR length_t tmat3x4<T, P>::length() const
34	{
35		return 3;
36	}
37
38	//////////////////////////////////////
39	// Accesses
40
41	template <typename T, precision P>
42	GLM_FUNC_QUALIFIER typename tmat3x4<T, P>::col_type &
43	tmat3x4<T, P>::operator[]
44	(
45		length_t i
46	)
47	{
48		assert(i < this->length());
49		return this->value[i];
50	}
51
52	template <typename T, precision P>
53	GLM_FUNC_QUALIFIER typename tmat3x4<T, P>::col_type const &
54	tmat3x4<T, P>::operator[]
55	(
56		length_t i
57	) const
58	{
59		assert(i < this->length());
60		return this->value[i];
61	}
62
63	//////////////////////////////////////////////////////////////
64	// Constructors
65
66	template <typename T, precision P>
67	GLM_FUNC_QUALIFIER tmat3x4<T, P>::tmat3x4()
68	{
69		this->value[0] = col_type(1, 0, 0, 0);
70		this->value[1] = col_type(0, 1, 0, 0);
71		this->value[2] = col_type(0, 0, 1, 0);
72	}
73
74	template <typename T, precision P>
75	GLM_FUNC_QUALIFIER tmat3x4<T, P>::tmat3x4
76	(
77		tmat3x4<T, P> const & m
78	)
79	{
80		this->value[0] = m.value[0];
81		this->value[1] = m.value[1];
82		this->value[2] = m.value[2];
83	}
84
85	template <typename T, precision P>
86	template <precision Q>
87	GLM_FUNC_QUALIFIER tmat3x4<T, P>::tmat3x4(
88		tmat3x4<T, Q> const & m)
89	{
90		this->value[0] = m.value[0];
91		this->value[1] = m.value[1];
92		this->value[2] = m.value[2];
93	}
94
95	template <typename T, precision P>
96	GLM_FUNC_QUALIFIER tmat3x4<T, P>::tmat3x4
97	(
98		ctor
99	)
100	{}
101
102	template <typename T, precision P>
103	GLM_FUNC_QUALIFIER tmat3x4<T, P>::tmat3x4
104	(
105		T const & s
106	)
107	{
108		value_type const Zero(0);
109		this->value[0] = col_type(s, Zero, Zero, Zero);
110		this->value[1] = col_type(Zero, s, Zero, Zero);
111		this->value[2] = col_type(Zero, Zero, s, Zero);
112	}
113
114	template <typename T, precision P>
115	GLM_FUNC_QUALIFIER tmat3x4<T, P>::tmat3x4
116	(
117		T const & x0, T const & y0, T const & z0, T const & w0,
118		T const & x1, T const & y1, T const & z1, T const & w1,
119		T const & x2, T const & y2, T const & z2, T const & w2
120	)
121	{
122		this->value[0] = col_type(x0, y0, z0, w0);
123		this->value[1] = col_type(x1, y1, z1, w1);
124		this->value[2] = col_type(x2, y2, z2, w2);
125	}
126
127	template <typename T, precision P>
128	GLM_FUNC_QUALIFIER tmat3x4<T, P>::tmat3x4
129	(
130		col_type const & v0,
131		col_type const & v1,
132		col_type const & v2
133	)
134	{
135		this->value[0] = v0;
136		this->value[1] = v1;
137		this->value[2] = v2;
138	}
139
140	//////////////////////////////////////
141	// Conversion constructors
142	template <typename T, precision P>
143	template <
144		typename X1, typename Y1, typename Z1, typename W1,
145		typename X2, typename Y2, typename Z2, typename W2,
146		typename X3, typename Y3, typename Z3, typename W3>
147	GLM_FUNC_QUALIFIER tmat3x4<T, P>::tmat3x4
148	(
149		X1 const & x1, Y1 const & y1, Z1 const & z1, W1 const & w1,
150		X2 const & x2, Y2 const & y2, Z2 const & z2, W2 const & w2,
151		X3 const & x3, Y3 const & y3, Z3 const & z3, W3 const & w3
152	)
153	{
154		this->value[0] = col_type(static_cast<T>(x1), value_type(y1), value_type(z1), value_type(w1));
155		this->value[1] = col_type(static_cast<T>(x2), value_type(y2), value_type(z2), value_type(w2));
156		this->value[2] = col_type(static_cast<T>(x3), value_type(y3), value_type(z3), value_type(w3));
157	}
158
159	template <typename T, precision P>
160	template <typename V1, typename V2, typename V3>
161	GLM_FUNC_QUALIFIER tmat3x4<T, P>::tmat3x4
162	(
163		tvec4<V1, P> const & v1,
164		tvec4<V2, P> const & v2,
165		tvec4<V3, P> const & v3
166	)
167	{
168		this->value[0] = col_type(v1);
169		this->value[1] = col_type(v2);
170		this->value[2] = col_type(v3);
171	}
172
173	// Conversion
174	template <typename T, precision P>
175	template <typename U, precision Q>
176	GLM_FUNC_QUALIFIER tmat3x4<T, P>::tmat3x4
177	(
178		tmat3x4<U, Q> const & m
179	)
180	{
181		this->value[0] = col_type(m[0]);
182		this->value[1] = col_type(m[1]);
183		this->value[2] = col_type(m[2]);
184	}
185
186	template <typename T, precision P>
187	GLM_FUNC_QUALIFIER tmat3x4<T, P>::tmat3x4
188	(
189		tmat2x2<T, P> const & m
190	)
191	{
192		this->value[0] = col_type(m[0], detail::tvec2<T, P>(0));
193		this->value[1] = col_type(m[1], detail::tvec2<T, P>(0));
194		this->value[2] = col_type(T(0), T(0), T(1), T(0));
195	}
196
197	template <typename T, precision P>
198	GLM_FUNC_QUALIFIER tmat3x4<T, P>::tmat3x4
199	(
200		tmat3x3<T, P> const & m
201	)
202	{
203		this->value[0] = col_type(m[0], T(0));
204		this->value[1] = col_type(m[1], T(0));
205		this->value[2] = col_type(m[2], T(0));
206	}
207
208	template <typename T, precision P>
209	GLM_FUNC_QUALIFIER tmat3x4<T, P>::tmat3x4
210	(
211		tmat4x4<T, P> const & m
212	)
213	{
214		this->value[0] = col_type(m[0]);
215		this->value[1] = col_type(m[1]);
216		this->value[2] = col_type(m[2]);
217	}
218
219	template <typename T, precision P>
220	GLM_FUNC_QUALIFIER tmat3x4<T, P>::tmat3x4
221	(
222		tmat2x3<T, P> const & m
223	)
224	{
225		this->value[0] = col_type(m[0], T(0));
226		this->value[1] = col_type(m[1], T(0));
227		this->value[2] = col_type(T(0), T(0), T(1), T(0));
228	}
229
230	template <typename T, precision P>
231	GLM_FUNC_QUALIFIER tmat3x4<T, P>::tmat3x4
232	(
233		tmat3x2<T, P> const & m
234	)
235	{
236		this->value[0] = col_type(m[0], detail::tvec2<T, P>(0));
237		this->value[1] = col_type(m[1], detail::tvec2<T, P>(0));
238		this->value[2] = col_type(m[2], T(0), T(1));
239	}
240
241	template <typename T, precision P>
242	GLM_FUNC_QUALIFIER tmat3x4<T, P>::tmat3x4
243	(
244		tmat2x4<T, P> const & m
245	)
246	{
247		this->value[0] = col_type(m[0]);
248		this->value[1] = col_type(m[1]);
249		this->value[2] = col_type(T(0), T(0), T(1), T(0));
250	}
251
252	template <typename T, precision P>
253	GLM_FUNC_QUALIFIER tmat3x4<T, P>::tmat3x4
254	(
255		tmat4x2<T, P> const & m
256	)
257	{
258		this->value[0] = col_type(m[0], detail::tvec2<T, P>(T(0)));
259		this->value[1] = col_type(m[1], detail::tvec2<T, P>(T(0)));
260		this->value[2] = col_type(m[2], detail::tvec2<T, P>(T(1), T(0)));
261	}
262
263	template <typename T, precision P>
264	GLM_FUNC_QUALIFIER tmat3x4<T, P>::tmat3x4
265	(
266		tmat4x3<T, P> const & m
267	)
268	{
269		this->value[0] = col_type(m[0], T(0));
270		this->value[1] = col_type(m[1], T(0));
271		this->value[2] = col_type(m[2], T(0));
272	}
273
274	//////////////////////////////////////////////////////////////
275	// Unary updatable operators
276
277	template <typename T, precision P>
278	GLM_FUNC_QUALIFIER tmat3x4<T, P>& tmat3x4<T, P>::operator= (tmat3x4<T, P> const & m)
279	{
280		this->value[0] = m[0];
281		this->value[1] = m[1];
282		this->value[2] = m[2];
283		return *this;
284	}
285
286	template <typename T, precision P>
287	template <typename U>
288	GLM_FUNC_QUALIFIER tmat3x4<T, P>& tmat3x4<T, P>::operator= (tmat3x4<U, P> const & m)
289	{
290		this->value[0] = m[0];
291		this->value[1] = m[1];
292		this->value[2] = m[2];
293		return *this;
294	}
295
296	template <typename T, precision P>
297	template <typename U>
298	GLM_FUNC_QUALIFIER tmat3x4<T, P>& tmat3x4<T, P>::operator+= (U s)
299	{
300		this->value[0] += s;
301		this->value[1] += s;
302		this->value[2] += s;
303		return *this;
304	}
305
306	template <typename T, precision P>
307	template <typename U>
308	GLM_FUNC_QUALIFIER tmat3x4<T, P>& tmat3x4<T, P>::operator+= (tmat3x4<U, P> const & m)
309	{
310		this->value[0] += m[0];
311		this->value[1] += m[1];
312		this->value[2] += m[2];
313		return *this;
314	}
315
316	template <typename T, precision P>
317	template <typename U>
318	GLM_FUNC_QUALIFIER tmat3x4<T, P>& tmat3x4<T, P>::operator-= (U s)
319	{
320		this->value[0] -= s;
321		this->value[1] -= s;
322		this->value[2] -= s;
323		return *this;
324	}
325
326	template <typename T, precision P>
327	template <typename U>
328	GLM_FUNC_QUALIFIER tmat3x4<T, P>& tmat3x4<T, P>::operator-= (tmat3x4<U, P> const & m)
329	{
330		this->value[0] -= m[0];
331		this->value[1] -= m[1];
332		this->value[2] -= m[2];
333		return *this;
334	}
335
336	template <typename T, precision P>
337	template <typename U>
338	GLM_FUNC_QUALIFIER tmat3x4<T, P>& tmat3x4<T, P>::operator*= (U s)
339	{
340		this->value[0] *= s;
341		this->value[1] *= s;
342		this->value[2] *= s;
343		return *this;
344	}
345
346	template <typename T, precision P>
347	template <typename U>
348	GLM_FUNC_QUALIFIER tmat3x4<T, P> & tmat3x4<T, P>::operator/= (U s)
349	{
350		this->value[0] /= s;
351		this->value[1] /= s;
352		this->value[2] /= s;
353		return *this;
354	}
355
356	template <typename T, precision P>
357	GLM_FUNC_QUALIFIER tmat3x4<T, P>& tmat3x4<T, P>::operator++ ()
358	{
359		++this->value[0];
360		++this->value[1];
361		++this->value[2];
362		return *this;
363	}
364
365	template <typename T, precision P>
366	GLM_FUNC_QUALIFIER tmat3x4<T, P>& tmat3x4<T, P>::operator-- ()
367	{
368		--this->value[0];
369		--this->value[1];
370		--this->value[2];
371		return *this;
372	}
373
374	template <typename T, precision P>
375	GLM_FUNC_QUALIFIER tmat3x4<T, P> tmat3x4<T, P>::operator++(int)
376	{
377		tmat3x4<T, P> Result(*this);
378		++*this;
379		return Result;
380	}
381
382	template <typename T, precision P>
383	GLM_FUNC_QUALIFIER tmat3x4<T, P> tmat3x4<T, P>::operator--(int)
384	{
385		tmat3x4<T, P> Result(*this);
386		--*this;
387		return Result;
388	}
389
390	//////////////////////////////////////////////////////////////
391	// Binary operators
392
393	template <typename T, precision P>
394	GLM_FUNC_QUALIFIER tmat3x4<T, P> operator+
395	(
396		tmat3x4<T, P> const & m,
397		T const & s
398	)
399	{
400		return tmat3x4<T, P>(
401			m[0] + s,
402			m[1] + s,
403			m[2] + s);
404	}
405
406	template <typename T, precision P>
407	GLM_FUNC_QUALIFIER tmat3x4<T, P> operator+
408	(
409		tmat3x4<T, P> const & m1,
410		tmat3x4<T, P> const & m2
411	)
412	{
413		return tmat3x4<T, P>(
414			m1[0] + m2[0],
415			m1[1] + m2[1],
416			m1[2] + m2[2]);
417	}
418
419	template <typename T, precision P>
420	GLM_FUNC_QUALIFIER tmat3x4<T, P> operator-
421	(
422		tmat3x4<T, P> const & m,
423		T const & s
424	)
425	{
426		return tmat3x4<T, P>(
427			m[0] - s,
428			m[1] - s,
429			m[2] - s);
430	}
431
432	template <typename T, precision P>
433	GLM_FUNC_QUALIFIER tmat3x4<T, P> operator-
434	(
435		tmat3x4<T, P> const & m1,
436		tmat3x4<T, P> const & m2
437	)
438	{
439		return tmat3x4<T, P>(
440			m1[0] - m2[0],
441			m1[1] - m2[1],
442			m1[2] - m2[2]);
443	}
444
445	template <typename T, precision P>
446	GLM_FUNC_QUALIFIER tmat3x4<T, P> operator*
447	(
448		tmat3x4<T, P> const & m,
449		T const & s
450	)
451	{
452		return tmat3x4<T, P>(
453			m[0] * s,
454			m[1] * s,
455			m[2] * s);
456	}
457
458	template <typename T, precision P>
459	GLM_FUNC_QUALIFIER tmat3x4<T, P> operator*
460	(
461		T const & s,
462		tmat3x4<T, P> const & m
463	)
464	{
465		return tmat3x4<T, P>(
466			m[0] * s,
467			m[1] * s,
468			m[2] * s);
469	}
470
471	template <typename T, precision P>
472	GLM_FUNC_QUALIFIER typename tmat3x4<T, P>::col_type operator*
473	(
474		tmat3x4<T, P> const & m,
475		typename tmat3x4<T, P>::row_type const & v
476	)
477	{
478		return typename tmat3x4<T, P>::col_type(
479			m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z,
480			m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z,
481			m[0][2] * v.x + m[1][2] * v.y + m[2][2] * v.z,
482			m[0][3] * v.x + m[1][3] * v.y + m[2][3] * v.z);
483	}
484
485	template <typename T, precision P>
486	GLM_FUNC_QUALIFIER typename tmat3x4<T, P>::row_type operator*
487	(
488		typename tmat3x4<T, P>::col_type const & v,
489		tmat3x4<T, P> const & m
490	)
491	{
492		return typename tmat3x4<T, P>::row_type(
493			v.x * m[0][0] + v.y * m[0][1] + v.z * m[0][2] + v.w * m[0][3],
494			v.x * m[1][0] + v.y * m[1][1] + v.z * m[1][2] + v.w * m[1][3],
495			v.x * m[2][0] + v.y * m[2][1] + v.z * m[2][2] + v.w * m[2][3]);
496	}
497
498	template <typename T, precision P>
499	GLM_FUNC_QUALIFIER tmat4x4<T, P> operator*
500	(
501		tmat3x4<T, P> const & m1,
502		tmat4x3<T, P> const & m2
503	)
504	{
505		const T SrcA00 = m1[0][0];
506		const T SrcA01 = m1[0][1];
507		const T SrcA02 = m1[0][2];
508		const T SrcA03 = m1[0][3];
509		const T SrcA10 = m1[1][0];
510		const T SrcA11 = m1[1][1];
511		const T SrcA12 = m1[1][2];
512		const T SrcA13 = m1[1][3];
513		const T SrcA20 = m1[2][0];
514		const T SrcA21 = m1[2][1];
515		const T SrcA22 = m1[2][2];
516		const T SrcA23 = m1[2][3];
517
518		const T SrcB00 = m2[0][0];
519		const T SrcB01 = m2[0][1];
520		const T SrcB02 = m2[0][2];
521		const T SrcB10 = m2[1][0];
522		const T SrcB11 = m2[1][1];
523		const T SrcB12 = m2[1][2];
524		const T SrcB20 = m2[2][0];
525		const T SrcB21 = m2[2][1];
526		const T SrcB22 = m2[2][2];
527		const T SrcB30 = m2[3][0];
528		const T SrcB31 = m2[3][1];
529		const T SrcB32 = m2[3][2];
530
531		tmat4x4<T, P> Result(tmat4x4<T, P>::_null);
532		Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01 + SrcA20 * SrcB02;
533		Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02;
534		Result[0][2] = SrcA02 * SrcB00 + SrcA12 * SrcB01 + SrcA22 * SrcB02;
535		Result[0][3] = SrcA03 * SrcB00 + SrcA13 * SrcB01 + SrcA23 * SrcB02;
536		Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11 + SrcA20 * SrcB12;
537		Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11 + SrcA21 * SrcB12;
538		Result[1][2] = SrcA02 * SrcB10 + SrcA12 * SrcB11 + SrcA22 * SrcB12;
539		Result[1][3] = SrcA03 * SrcB10 + SrcA13 * SrcB11 + SrcA23 * SrcB12;
540		Result[2][0] = SrcA00 * SrcB20 + SrcA10 * SrcB21 + SrcA20 * SrcB22;
541		Result[2][1] = SrcA01 * SrcB20 + SrcA11 * SrcB21 + SrcA21 * SrcB22;
542		Result[2][2] = SrcA02 * SrcB20 + SrcA12 * SrcB21 + SrcA22 * SrcB22;
543		Result[2][3] = SrcA03 * SrcB20 + SrcA13 * SrcB21 + SrcA23 * SrcB22;
544		Result[3][0] = SrcA00 * SrcB30 + SrcA10 * SrcB31 + SrcA20 * SrcB32;
545		Result[3][1] = SrcA01 * SrcB30 + SrcA11 * SrcB31 + SrcA21 * SrcB32;
546		Result[3][2] = SrcA02 * SrcB30 + SrcA12 * SrcB31 + SrcA22 * SrcB32;
547		Result[3][3] = SrcA03 * SrcB30 + SrcA13 * SrcB31 + SrcA23 * SrcB32;
548		return Result;
549	}
550
551	template <typename T, precision P>
552	GLM_FUNC_QUALIFIER tmat2x4<T, P> operator*
553	(
554		tmat3x4<T, P> const & m1,
555		tmat2x3<T, P> const & m2
556	)
557	{
558		return tmat2x4<T, P>(
559			m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2],
560			m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2],
561			m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2],
562			m1[0][3] * m2[0][0] + m1[1][3] * m2[0][1] + m1[2][3] * m2[0][2],
563			m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2],
564			m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2],
565			m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1] + m1[2][2] * m2[1][2],
566			m1[0][3] * m2[1][0] + m1[1][3] * m2[1][1] + m1[2][3] * m2[1][2]);
567	}
568
569	template <typename T, precision P>
570	GLM_FUNC_QUALIFIER tmat3x4<T, P> operator*
571	(
572		tmat3x4<T, P> const & m1,
573		tmat3x3<T, P> const & m2
574	)
575	{
576		return tmat3x4<T, P>(
577			m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2],
578			m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2],
579			m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2],
580			m1[0][3] * m2[0][0] + m1[1][3] * m2[0][1] + m1[2][3] * m2[0][2],
581			m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2],
582			m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2],
583			m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1] + m1[2][2] * m2[1][2],
584			m1[0][3] * m2[1][0] + m1[1][3] * m2[1][1] + m1[2][3] * m2[1][2],
585			m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1] + m1[2][0] * m2[2][2],
586			m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1] + m1[2][1] * m2[2][2],
587			m1[0][2] * m2[2][0] + m1[1][2] * m2[2][1] + m1[2][2] * m2[2][2],
588			m1[0][3] * m2[2][0] + m1[1][3] * m2[2][1] + m1[2][3] * m2[2][2]);
589	}
590
591	template <typename T, precision P>
592	GLM_FUNC_QUALIFIER tmat3x4<T, P> operator/
593	(
594		tmat3x4<T, P> const & m,
595		T const & s
596	)
597	{
598		return tmat3x4<T, P>(
599			m[0] / s,
600			m[1] / s,
601			m[2] / s);
602	}
603
604	template <typename T, precision P>
605	GLM_FUNC_QUALIFIER tmat3x4<T, P> operator/
606	(
607		T const & s,
608		tmat3x4<T, P> const & m
609	)
610	{
611		return tmat3x4<T, P>(
612			s / m[0],
613			s / m[1],
614			s / m[2]);
615	}
616
617	// Unary constant operators
618	template <typename T, precision P>
619	GLM_FUNC_QUALIFIER tmat3x4<T, P> const operator-
620	(
621		tmat3x4<T, P> const & m
622	)
623	{
624		return tmat3x4<T, P>(
625			-m[0],
626			-m[1],
627			-m[2]);
628	}
629
630	//////////////////////////////////////
631	// Boolean operators
632
633	template <typename T, precision P>
634	GLM_FUNC_QUALIFIER bool operator==
635	(
636		tmat3x4<T, P> const & m1,
637		tmat3x4<T, P> const & m2
638	)
639	{
640		return (m1[0] == m2[0]) && (m1[1] == m2[1]) && (m1[2] == m2[2]);
641	}
642
643	template <typename T, precision P>
644	GLM_FUNC_QUALIFIER bool operator!=
645	(
646		tmat3x4<T, P> const & m1,
647		tmat3x4<T, P> const & m2
648	)
649	{
650		return (m1[0] != m2[0]) || (m1[1] != m2[1]) || (m1[2] != m2[2]);
651	}
652} //namespace detail
653} //namespace glm
654