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_mat2x4.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 tmat2x4<T, P>::length() const
34	{
35		return 2;
36	}
37
38	//////////////////////////////////////
39	// Accesses
40
41	template <typename T, precision P>
42	GLM_FUNC_QUALIFIER typename tmat2x4<T, P>::col_type &
43	tmat2x4<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 tmat2x4<T, P>::col_type const &
54	tmat2x4<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 tmat2x4<T, P>::tmat2x4()
68	{
69		value_type const Zero(0);
70		value_type const One(1);
71		this->value[0] = col_type(One, Zero, Zero, Zero);
72		this->value[1] = col_type(Zero, One, Zero, Zero);
73	}
74
75	template <typename T, precision P>
76	GLM_FUNC_QUALIFIER tmat2x4<T, P>::tmat2x4
77	(
78		tmat2x4<T, P> const & m
79	)
80	{
81		this->value[0] = m.value[0];
82		this->value[1] = m.value[1];
83	}
84
85	template <typename T, precision P>
86	template <precision Q>
87	GLM_FUNC_QUALIFIER tmat2x4<T, P>::tmat2x4(
88		tmat2x4<T, Q> const & m)
89	{
90		this->value[0] = m.value[0];
91		this->value[1] = m.value[1];
92	}
93
94	template <typename T, precision P>
95	GLM_FUNC_QUALIFIER tmat2x4<T, P>::tmat2x4
96	(
97		ctor
98	)
99	{}
100
101	template <typename T, precision P>
102	GLM_FUNC_QUALIFIER tmat2x4<T, P>::tmat2x4
103	(
104		T const & s
105	)
106	{
107		value_type const Zero(0);
108		this->value[0] = col_type(s, Zero, Zero, Zero);
109		this->value[1] = col_type(Zero, s, Zero, Zero);
110	}
111
112	template <typename T, precision P>
113	GLM_FUNC_QUALIFIER tmat2x4<T, P>::tmat2x4
114	(
115		T const & x0, T const & y0, T const & z0, T const & w0,
116		T const & x1, T const & y1, T const & z1, T const & w1
117	)
118	{
119		this->value[0] = col_type(x0, y0, z0, w0);
120		this->value[1] = col_type(x1, y1, z1, w1);
121	}
122
123	template <typename T, precision P>
124	GLM_FUNC_QUALIFIER tmat2x4<T, P>::tmat2x4
125	(
126		col_type const & v0,
127		col_type const & v1
128	)
129	{
130		this->value[0] = v0;
131		this->value[1] = v1;
132	}
133
134	//////////////////////////////////////
135	// Conversion constructors
136	template <typename T, precision P>
137	template <
138		typename X1, typename Y1, typename Z1, typename W1,
139		typename X2, typename Y2, typename Z2, typename W2>
140	GLM_FUNC_QUALIFIER tmat2x4<T, P>::tmat2x4
141	(
142		X1 const & x1, Y1 const & y1, Z1 const & z1, W1 const & w1,
143		X2 const & x2, Y2 const & y2, Z2 const & z2, W2 const & w2
144	)
145	{
146		this->value[0] = col_type(static_cast<T>(x1), value_type(y1), value_type(z1), value_type(w1));
147		this->value[1] = col_type(static_cast<T>(x2), value_type(y2), value_type(z2), value_type(w2));
148	}
149
150	template <typename T, precision P>
151	template <typename V1, typename V2>
152	GLM_FUNC_QUALIFIER tmat2x4<T, P>::tmat2x4
153	(
154		tvec4<V1, P> const & v1,
155		tvec4<V2, P> const & v2
156	)
157	{
158		this->value[0] = col_type(v1);
159		this->value[1] = col_type(v2);
160	}
161
162	//////////////////////////////////////
163	// Matrix conversions
164
165	template <typename T, precision P>
166	template <typename U, precision Q>
167	GLM_FUNC_QUALIFIER tmat2x4<T, P>::tmat2x4
168	(
169		tmat2x4<U, Q> const & m
170	)
171	{
172		this->value[0] = col_type(m[0]);
173		this->value[1] = col_type(m[1]);
174	}
175
176	template <typename T, precision P>
177	GLM_FUNC_QUALIFIER tmat2x4<T, P>::tmat2x4
178	(
179		tmat2x2<T, P> const & m
180	)
181	{
182		this->value[0] = col_type(m[0], detail::tvec2<T, P>(0));
183		this->value[1] = col_type(m[1], detail::tvec2<T, P>(0));
184	}
185
186	template <typename T, precision P>
187	GLM_FUNC_QUALIFIER tmat2x4<T, P>::tmat2x4
188	(
189		tmat3x3<T, P> const & m
190	)
191	{
192		this->value[0] = col_type(m[0], T(0));
193		this->value[1] = col_type(m[1], T(0));
194	}
195
196	template <typename T, precision P>
197	GLM_FUNC_QUALIFIER tmat2x4<T, P>::tmat2x4
198	(
199		tmat4x4<T, P> const & m
200	)
201	{
202		this->value[0] = col_type(m[0]);
203		this->value[1] = col_type(m[1]);
204	}
205
206	template <typename T, precision P>
207	GLM_FUNC_QUALIFIER tmat2x4<T, P>::tmat2x4
208	(
209		tmat2x3<T, P> const & m
210	)
211	{
212		this->value[0] = col_type(m[0], T(0));
213		this->value[1] = col_type(m[1], T(0));
214	}
215
216	template <typename T, precision P>
217	GLM_FUNC_QUALIFIER tmat2x4<T, P>::tmat2x4
218	(
219		tmat3x2<T, P> const & m
220	)
221	{
222		this->value[0] = col_type(m[0], detail::tvec2<T, P>(0));
223		this->value[1] = col_type(m[1], detail::tvec2<T, P>(0));
224	}
225
226	template <typename T, precision P>
227	GLM_FUNC_QUALIFIER tmat2x4<T, P>::tmat2x4
228	(
229		tmat3x4<T, P> const & m
230	)
231	{
232		this->value[0] = m[0];
233		this->value[1] = m[1];
234	}
235
236	template <typename T, precision P>
237	GLM_FUNC_QUALIFIER tmat2x4<T, P>::tmat2x4
238	(
239		tmat4x2<T, P> const & m
240	)
241	{
242		this->value[0] = col_type(m[0], detail::tvec2<T, P>(T(0)));
243		this->value[1] = col_type(m[1], detail::tvec2<T, P>(T(0)));
244	}
245
246	template <typename T, precision P>
247	GLM_FUNC_QUALIFIER tmat2x4<T, P>::tmat2x4
248	(
249		tmat4x3<T, P> const & m
250	)
251	{
252		this->value[0] = col_type(m[0], T(0));
253		this->value[1] = col_type(m[1], T(0));
254	}
255
256	//////////////////////////////////////////////////////////////
257	// Unary updatable operators
258
259	template <typename T, precision P>
260	GLM_FUNC_QUALIFIER tmat2x4<T, P>& tmat2x4<T, P>::operator= (tmat2x4<T, P> const & m)
261	{
262		this->value[0] = m[0];
263		this->value[1] = m[1];
264		return *this;
265	}
266
267	template <typename T, precision P>
268	template <typename U>
269	GLM_FUNC_QUALIFIER tmat2x4<T, P>& tmat2x4<T, P>::operator= (tmat2x4<U, P> const & m)
270	{
271		this->value[0] = m[0];
272		this->value[1] = m[1];
273		return *this;
274	}
275
276	template <typename T, precision P>
277	template <typename U>
278	GLM_FUNC_QUALIFIER tmat2x4<T, P>& tmat2x4<T, P>::operator+= (U s)
279	{
280		this->value[0] += s;
281		this->value[1] += s;
282		return *this;
283	}
284
285	template <typename T, precision P>
286	template <typename U>
287	GLM_FUNC_QUALIFIER tmat2x4<T, P>& tmat2x4<T, P>::operator+= (tmat2x4<U, P> const & m)
288	{
289		this->value[0] += m[0];
290		this->value[1] += m[1];
291		return *this;
292	}
293
294	template <typename T, precision P>
295	template <typename U>
296	GLM_FUNC_QUALIFIER tmat2x4<T, P>& tmat2x4<T, P>::operator-= (U s)
297	{
298		this->value[0] -= s;
299		this->value[1] -= s;
300		return *this;
301	}
302
303	template <typename T, precision P>
304	template <typename U>
305	GLM_FUNC_QUALIFIER tmat2x4<T, P>& tmat2x4<T, P>::operator-= (tmat2x4<U, P> const & m)
306	{
307		this->value[0] -= m[0];
308		this->value[1] -= m[1];
309		return *this;
310	}
311
312	template <typename T, precision P>
313	template <typename U>
314	GLM_FUNC_QUALIFIER tmat2x4<T, P>& tmat2x4<T, P>::operator*= (U s)
315	{
316		this->value[0] *= s;
317		this->value[1] *= s;
318		return *this;
319	}
320
321	template <typename T, precision P>
322	template <typename U>
323	GLM_FUNC_QUALIFIER tmat2x4<T, P> & tmat2x4<T, P>::operator/= (U s)
324	{
325		this->value[0] /= s;
326		this->value[1] /= s;
327		return *this;
328	}
329
330	template <typename T, precision P>
331	GLM_FUNC_QUALIFIER tmat2x4<T, P>& tmat2x4<T, P>::operator++()
332	{
333		++this->value[0];
334		++this->value[1];
335		return *this;
336	}
337
338	template <typename T, precision P>
339	GLM_FUNC_QUALIFIER tmat2x4<T, P>& tmat2x4<T, P>::operator--()
340	{
341		--this->value[0];
342		--this->value[1];
343		return *this;
344	}
345
346	template <typename T, precision P>
347	GLM_FUNC_QUALIFIER tmat2x4<T, P> tmat2x4<T, P>::operator++(int)
348	{
349		tmat2x4<T, P> Result(*this);
350		++*this;
351		return Result;
352	}
353
354	template <typename T, precision P>
355	GLM_FUNC_QUALIFIER tmat2x4<T, P> tmat2x4<T, P>::operator--(int)
356	{
357		tmat2x4<T, P> Result(*this);
358		--*this;
359		return Result;
360	}
361
362	//////////////////////////////////////////////////////////////
363	// Binary operators
364
365	template <typename T, precision P>
366	GLM_FUNC_QUALIFIER tmat2x4<T, P> operator+
367	(
368		tmat2x4<T, P> const & m,
369		T const & s
370	)
371	{
372		return tmat2x4<T, P>(
373			m[0] + s,
374			m[1] + s);
375	}
376
377	template <typename T, precision P>
378	GLM_FUNC_QUALIFIER tmat2x4<T, P> operator+
379	(
380		tmat2x4<T, P> const & m1,
381		tmat2x4<T, P> const & m2
382	)
383	{
384		return tmat2x4<T, P>(
385			m1[0] + m2[0],
386			m1[1] + m2[1]);
387	}
388
389	template <typename T, precision P>
390	GLM_FUNC_QUALIFIER tmat2x4<T, P> operator-
391	(
392		tmat2x4<T, P> const & m,
393		T const & s
394	)
395	{
396		return tmat2x4<T, P>(
397			m[0] - s,
398			m[1] - s);
399	}
400
401	template <typename T, precision P>
402	GLM_FUNC_QUALIFIER tmat2x4<T, P> operator-
403	(
404		tmat2x4<T, P> const & m1,
405		tmat2x4<T, P> const & m2
406	)
407	{
408		return tmat2x4<T, P>(
409			m1[0] - m2[0],
410			m1[1] - m2[1]);
411	}
412
413	template <typename T, precision P>
414	GLM_FUNC_QUALIFIER tmat2x4<T, P> operator*
415	(
416		tmat2x4<T, P> const & m,
417		T const & s
418	)
419	{
420		return tmat2x4<T, P>(
421			m[0] * s,
422			m[1] * s);
423	}
424
425	template <typename T, precision P>
426	GLM_FUNC_QUALIFIER tmat2x4<T, P> operator*
427	(
428		T const & s,
429		tmat2x4<T, P> const & m
430	)
431	{
432		return tmat2x4<T, P>(
433			m[0] * s,
434			m[1] * s);
435	}
436
437	template <typename T, precision P>
438	GLM_FUNC_QUALIFIER typename tmat2x4<T, P>::col_type operator*
439	(
440		tmat2x4<T, P> const & m,
441		typename tmat2x4<T, P>::row_type const & v
442	)
443	{
444		return typename tmat2x4<T, P>::col_type(
445			m[0][0] * v.x + m[1][0] * v.y,
446			m[0][1] * v.x + m[1][1] * v.y,
447			m[0][2] * v.x + m[1][2] * v.y,
448			m[0][3] * v.x + m[1][3] * v.y);
449	}
450
451	template <typename T, precision P>
452	GLM_FUNC_QUALIFIER typename tmat2x4<T, P>::row_type operator*
453	(
454		typename tmat2x4<T, P>::col_type const & v,
455		tmat2x4<T, P> const & m
456	)
457	{
458		return typename tmat2x4<T, P>::row_type(
459			v.x * m[0][0] + v.y * m[0][1] + v.z * m[0][2] + v.w * m[0][3],
460			v.x * m[1][0] + v.y * m[1][1] + v.z * m[1][2] + v.w * m[1][3]);
461	}
462
463	template <typename T, precision P>
464	GLM_FUNC_QUALIFIER tmat4x4<T, P> operator*
465	(
466		tmat2x4<T, P> const & m1,
467		tmat4x2<T, P> const & m2
468	)
469	{
470		T SrcA00 = m1[0][0];
471		T SrcA01 = m1[0][1];
472		T SrcA02 = m1[0][2];
473		T SrcA03 = m1[0][3];
474		T SrcA10 = m1[1][0];
475		T SrcA11 = m1[1][1];
476		T SrcA12 = m1[1][2];
477		T SrcA13 = m1[1][3];
478
479		T SrcB00 = m2[0][0];
480		T SrcB01 = m2[0][1];
481		T SrcB10 = m2[1][0];
482		T SrcB11 = m2[1][1];
483		T SrcB20 = m2[2][0];
484		T SrcB21 = m2[2][1];
485		T SrcB30 = m2[3][0];
486		T SrcB31 = m2[3][1];
487
488		tmat4x4<T, P> Result(tmat4x4<T, P>::_null);
489		Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01;
490		Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01;
491		Result[0][2] = SrcA02 * SrcB00 + SrcA12 * SrcB01;
492		Result[0][3] = SrcA03 * SrcB00 + SrcA13 * SrcB01;
493		Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11;
494		Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11;
495		Result[1][2] = SrcA02 * SrcB10 + SrcA12 * SrcB11;
496		Result[1][3] = SrcA03 * SrcB10 + SrcA13 * SrcB11;
497		Result[2][0] = SrcA00 * SrcB20 + SrcA10 * SrcB21;
498		Result[2][1] = SrcA01 * SrcB20 + SrcA11 * SrcB21;
499		Result[2][2] = SrcA02 * SrcB20 + SrcA12 * SrcB21;
500		Result[2][3] = SrcA03 * SrcB20 + SrcA13 * SrcB21;
501		Result[3][0] = SrcA00 * SrcB30 + SrcA10 * SrcB31;
502		Result[3][1] = SrcA01 * SrcB30 + SrcA11 * SrcB31;
503		Result[3][2] = SrcA02 * SrcB30 + SrcA12 * SrcB31;
504		Result[3][3] = SrcA03 * SrcB30 + SrcA13 * SrcB31;
505		return Result;
506	}
507
508	template <typename T, precision P>
509	GLM_FUNC_QUALIFIER tmat2x4<T, P> operator*
510	(
511		tmat2x4<T, P> const & m1,
512		tmat2x2<T, P> const & m2
513	)
514	{
515		return tmat2x4<T, P>(
516			m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1],
517			m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1],
518			m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1],
519			m1[0][3] * m2[0][0] + m1[1][3] * m2[0][1],
520			m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1],
521			m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1],
522			m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1],
523			m1[0][3] * m2[1][0] + m1[1][3] * m2[1][1]);
524	}
525
526	template <typename T, precision P>
527	GLM_FUNC_QUALIFIER tmat3x4<T, P> operator*
528	(
529		tmat2x4<T, P> const & m1,
530		tmat3x2<T, P> const & m2
531	)
532	{
533		return tmat3x4<T, P>(
534			m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1],
535			m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1],
536			m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1],
537			m1[0][3] * m2[0][0] + m1[1][3] * m2[0][1],
538			m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1],
539			m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1],
540			m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1],
541			m1[0][3] * m2[1][0] + m1[1][3] * m2[1][1],
542			m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1],
543			m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1],
544			m1[0][2] * m2[2][0] + m1[1][2] * m2[2][1],
545			m1[0][3] * m2[2][0] + m1[1][3] * m2[2][1]);
546	}
547
548	template <typename T, precision P>
549	GLM_FUNC_QUALIFIER tmat2x4<T, P> operator/
550	(
551		tmat2x4<T, P> const & m,
552		T const & s
553	)
554	{
555		return tmat2x4<T, P>(
556			m[0] / s,
557			m[1] / s);
558	}
559
560	template <typename T, precision P>
561	GLM_FUNC_QUALIFIER tmat2x4<T, P> operator/
562	(
563		T const & s,
564		tmat2x4<T, P> const & m
565	)
566	{
567		return tmat2x4<T, P>(
568			s / m[0],
569			s / m[1]);
570	}
571
572	// Unary constant operators
573	template <typename T, precision P>
574	GLM_FUNC_QUALIFIER tmat2x4<T, P> const operator-
575	(
576		tmat2x4<T, P> const & m
577	)
578	{
579		return tmat2x4<T, P>(
580			-m[0],
581			-m[1]);
582	}
583
584	//////////////////////////////////////
585	// Boolean operators
586
587	template <typename T, precision P>
588	GLM_FUNC_QUALIFIER bool operator==
589	(
590		tmat2x4<T, P> const & m1,
591		tmat2x4<T, P> const & m2
592	)
593	{
594		return (m1[0] == m2[0]) && (m1[1] == m2[1]);
595	}
596
597	template <typename T, precision P>
598	GLM_FUNC_QUALIFIER bool operator!=
599	(
600		tmat2x4<T, P> const & m1,
601		tmat2x4<T, P> const & m2
602	)
603	{
604		return (m1[0] != m2[0]) || (m1[1] != m2[1]);
605	}
606} //namespace detail
607} //namespace glm
608