1/// @ref core
2/// @file glm/detail/type_mat2x2.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 tmat2x2<T, P>::tmat2x2()
13		{
14#			ifndef GLM_FORCE_NO_CTOR_INIT
15				this->value[0] = col_type(1, 0);
16				this->value[1] = col_type(0, 1);
17#			endif
18		}
19#	endif
20
21#	if !GLM_HAS_DEFAULTED_FUNCTIONS
22		template <typename T, precision P>
23		GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2(tmat2x2<T, P> const & m)
24		{
25			this->value[0] = m.value[0];
26			this->value[1] = m.value[1];
27		}
28#	endif//!GLM_HAS_DEFAULTED_FUNCTIONS
29
30	template <typename T, precision P>
31	template <precision Q>
32	GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2(tmat2x2<T, Q> const & m)
33	{
34		this->value[0] = m.value[0];
35		this->value[1] = m.value[1];
36	}
37
38	template <typename T, precision P>
39	GLM_FUNC_QUALIFIER GLM_CONSTEXPR_CTOR tmat2x2<T, P>::tmat2x2(ctor)
40	{}
41
42	template <typename T, precision P>
43	GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2(T scalar)
44	{
45		this->value[0] = col_type(scalar, 0);
46		this->value[1] = col_type(0, scalar);
47	}
48
49	template <typename T, precision P>
50	GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2
51	(
52		T const & x0, T const & y0,
53		T const & x1, T const & y1
54	)
55	{
56		this->value[0] = col_type(x0, y0);
57		this->value[1] = col_type(x1, y1);
58	}
59
60	template <typename T, precision P>
61	GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2(col_type const & v0, col_type const & v1)
62	{
63		this->value[0] = v0;
64		this->value[1] = v1;
65	}
66
67	// -- Conversion constructors --
68
69	template <typename T, precision P>
70	template <typename X1, typename Y1, typename X2, typename Y2>
71	GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2
72	(
73		X1 const & x1, Y1 const & y1,
74		X2 const & x2, Y2 const & y2
75	)
76	{
77		this->value[0] = col_type(static_cast<T>(x1), value_type(y1));
78		this->value[1] = col_type(static_cast<T>(x2), value_type(y2));
79	}
80
81	template <typename T, precision P>
82	template <typename V1, typename V2>
83	GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2(tvec2<V1, P> const & v1, tvec2<V2, P> const & v2)
84	{
85		this->value[0] = col_type(v1);
86		this->value[1] = col_type(v2);
87	}
88
89	// -- mat2x2 matrix conversions --
90
91	template <typename T, precision P>
92	template <typename U, precision Q>
93	GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2(tmat2x2<U, Q> const & m)
94	{
95		this->value[0] = col_type(m[0]);
96		this->value[1] = col_type(m[1]);
97	}
98
99	template <typename T, precision P>
100	GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2(tmat3x3<T, P> const & m)
101	{
102		this->value[0] = col_type(m[0]);
103		this->value[1] = col_type(m[1]);
104	}
105
106	template <typename T, precision P>
107	GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2(tmat4x4<T, P> const & m)
108	{
109		this->value[0] = col_type(m[0]);
110		this->value[1] = col_type(m[1]);
111	}
112
113	template <typename T, precision P>
114	GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2(tmat2x3<T, P> const & m)
115	{
116		this->value[0] = col_type(m[0]);
117		this->value[1] = col_type(m[1]);
118	}
119
120	template <typename T, precision P>
121	GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2(tmat3x2<T, P> const & m)
122	{
123		this->value[0] = m[0];
124		this->value[1] = m[1];
125	}
126
127	template <typename T, precision P>
128	GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2(tmat2x4<T, P> const & m)
129	{
130		this->value[0] = col_type(m[0]);
131		this->value[1] = col_type(m[1]);
132	}
133
134	template <typename T, precision P>
135	GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2(tmat4x2<T, P> const & m)
136	{
137		this->value[0] = m[0];
138		this->value[1] = m[1];
139	}
140
141	template <typename T, precision P>
142	GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2(tmat3x4<T, P> const & m)
143	{
144		this->value[0] = col_type(m[0]);
145		this->value[1] = col_type(m[1]);
146	}
147
148	template <typename T, precision P>
149	GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2(tmat4x3<T, P> const & m)
150	{
151		this->value[0] = col_type(m[0]);
152		this->value[1] = col_type(m[1]);
153	}
154
155	// -- Accesses --
156
157	template <typename T, precision P>
158	GLM_FUNC_QUALIFIER typename tmat2x2<T, P>::col_type & tmat2x2<T, P>::operator[](typename tmat2x2<T, P>::length_type i)
159	{
160		assert(i < this->length());
161		return this->value[i];
162	}
163
164	template <typename T, precision P>
165	GLM_FUNC_QUALIFIER typename tmat2x2<T, P>::col_type const & tmat2x2<T, P>::operator[](typename tmat2x2<T, P>::length_type i) const
166	{
167		assert(i < this->length());
168		return this->value[i];
169	}
170
171	// -- Unary updatable operators --
172
173#	if !GLM_HAS_DEFAULTED_FUNCTIONS
174		template <typename T, precision P>
175		GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator=(tmat2x2<T, P> const & m)
176		{
177			this->value[0] = m[0];
178			this->value[1] = m[1];
179			return *this;
180		}
181#	endif//!GLM_HAS_DEFAULTED_FUNCTIONS
182
183	template <typename T, precision P>
184	template <typename U>
185	GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator=(tmat2x2<U, P> const & m)
186	{
187		this->value[0] = m[0];
188		this->value[1] = m[1];
189		return *this;
190	}
191
192	template <typename T, precision P>
193	template <typename U>
194	GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator+=(U scalar)
195	{
196		this->value[0] += scalar;
197		this->value[1] += scalar;
198		return *this;
199	}
200
201	template <typename T, precision P>
202	template <typename U>
203	GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator+=(tmat2x2<U, P> const & m)
204	{
205		this->value[0] += m[0];
206		this->value[1] += m[1];
207		return *this;
208	}
209
210	template <typename T, precision P>
211	template <typename U>
212	GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator-=(U scalar)
213	{
214		this->value[0] -= scalar;
215		this->value[1] -= scalar;
216		return *this;
217	}
218
219	template <typename T, precision P>
220	template <typename U>
221	GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator-=(tmat2x2<U, P> const & m)
222	{
223		this->value[0] -= m[0];
224		this->value[1] -= m[1];
225		return *this;
226	}
227
228	template <typename T, precision P>
229	template <typename U>
230	GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator*=(U scalar)
231	{
232		this->value[0] *= scalar;
233		this->value[1] *= scalar;
234		return *this;
235	}
236
237	template <typename T, precision P>
238	template <typename U>
239	GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator*=(tmat2x2<U, P> const & m)
240	{
241		return (*this = *this * m);
242	}
243
244	template <typename T, precision P>
245	template <typename U>
246	GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator/=(U scalar)
247	{
248		this->value[0] /= scalar;
249		this->value[1] /= scalar;
250		return *this;
251	}
252
253	template <typename T, precision P>
254	template <typename U>
255	GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator/=(tmat2x2<U, P> const & m)
256	{
257		return *this *= inverse(m);
258	}
259
260	// -- Increment and decrement operators --
261
262	template <typename T, precision P>
263	GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator++()
264	{
265		++this->value[0];
266		++this->value[1];
267		return *this;
268	}
269
270	template <typename T, precision P>
271	GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator--()
272	{
273		--this->value[0];
274		--this->value[1];
275		return *this;
276	}
277
278	template <typename T, precision P>
279	GLM_FUNC_QUALIFIER tmat2x2<T, P> tmat2x2<T, P>::operator++(int)
280	{
281		tmat2x2<T, P> Result(*this);
282		++*this;
283		return Result;
284	}
285
286	template <typename T, precision P>
287	GLM_FUNC_QUALIFIER tmat2x2<T, P> tmat2x2<T, P>::operator--(int)
288	{
289		tmat2x2<T, P> Result(*this);
290		--*this;
291		return Result;
292	}
293
294	// -- Unary arithmetic operators --
295
296	template <typename T, precision P>
297	GLM_FUNC_QUALIFIER tmat2x2<T, P> operator+(tmat2x2<T, P> const & m)
298	{
299		return m;
300	}
301
302	template <typename T, precision P>
303	GLM_FUNC_QUALIFIER tmat2x2<T, P> operator-(tmat2x2<T, P> const & m)
304	{
305		return tmat2x2<T, P>(
306			-m[0],
307			-m[1]);
308	}
309
310	// -- Binary arithmetic operators --
311
312	template <typename T, precision P>
313	GLM_FUNC_QUALIFIER tmat2x2<T, P> operator+(tmat2x2<T, P> const & m, T scalar)
314	{
315		return tmat2x2<T, P>(
316			m[0] + scalar,
317			m[1] + scalar);
318	}
319
320	template <typename T, precision P>
321	GLM_FUNC_QUALIFIER tmat2x2<T, P> operator+(T scalar, tmat2x2<T, P> const & m)
322	{
323		return tmat2x2<T, P>(
324			m[0] + scalar,
325			m[1] + scalar);
326	}
327
328	template <typename T, precision P>
329	GLM_FUNC_QUALIFIER tmat2x2<T, P> operator+(tmat2x2<T, P> const & m1, tmat2x2<T, P> const & m2)
330	{
331		return tmat2x2<T, P>(
332			m1[0] + m2[0],
333			m1[1] + m2[1]);
334	}
335
336	template <typename T, precision P>
337	GLM_FUNC_QUALIFIER tmat2x2<T, P> operator-(tmat2x2<T, P> const & m, T scalar)
338	{
339		return tmat2x2<T, P>(
340			m[0] - scalar,
341			m[1] - scalar);
342	}
343
344	template <typename T, precision P>
345	GLM_FUNC_QUALIFIER tmat2x2<T, P> operator-(T scalar, tmat2x2<T, P> const & m)
346	{
347		return tmat2x2<T, P>(
348			scalar - m[0],
349			scalar - m[1]);
350	}
351
352	template <typename T, precision P>
353	GLM_FUNC_QUALIFIER tmat2x2<T, P> operator-(tmat2x2<T, P> const & m1, tmat2x2<T, P> const & m2)
354	{
355		return tmat2x2<T, P>(
356			m1[0] - m2[0],
357			m1[1] - m2[1]);
358	}
359
360	template <typename T, precision P>
361	GLM_FUNC_QUALIFIER tmat2x2<T, P> operator*(tmat2x2<T, P> const & m, T scalar)
362	{
363		return tmat2x2<T, P>(
364			m[0] * scalar,
365			m[1] * scalar);
366	}
367
368	template <typename T, precision P>
369	GLM_FUNC_QUALIFIER tmat2x2<T, P> operator*(T scalar, tmat2x2<T, P> const & m)
370	{
371		return tmat2x2<T, P>(
372			m[0] * scalar,
373			m[1] * scalar);
374	}
375
376	template <typename T, precision P>
377	GLM_FUNC_QUALIFIER typename tmat2x2<T, P>::col_type operator*
378	(
379		tmat2x2<T, P> const & m,
380		typename tmat2x2<T, P>::row_type const & v
381	)
382	{
383		return tvec2<T, P>(
384			m[0][0] * v.x + m[1][0] * v.y,
385			m[0][1] * v.x + m[1][1] * v.y);
386	}
387
388	template <typename T, precision P>
389	GLM_FUNC_QUALIFIER typename tmat2x2<T, P>::row_type operator*
390	(
391		typename tmat2x2<T, P>::col_type const & v,
392		tmat2x2<T, P> const & m
393	)
394	{
395		return tvec2<T, P>(
396			v.x * m[0][0] + v.y * m[0][1],
397			v.x * m[1][0] + v.y * m[1][1]);
398	}
399
400	template <typename T, precision P>
401	GLM_FUNC_QUALIFIER tmat2x2<T, P> operator*(tmat2x2<T, P> const & m1, tmat2x2<T, P> const & m2)
402	{
403		return tmat2x2<T, P>(
404			m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1],
405			m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1],
406			m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1],
407			m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1]);
408	}
409
410	template <typename T, precision P>
411	GLM_FUNC_QUALIFIER tmat3x2<T, P> operator*(tmat2x2<T, P> const & m1, tmat3x2<T, P> const & m2)
412	{
413		return tmat3x2<T, P>(
414			m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1],
415			m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1],
416			m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1],
417			m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1],
418			m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1],
419			m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1]);
420	}
421
422	template <typename T, precision P>
423	GLM_FUNC_QUALIFIER tmat4x2<T, P> operator*(tmat2x2<T, P> const & m1, tmat4x2<T, P> const & m2)
424	{
425		return tmat4x2<T, P>(
426			m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1],
427			m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1],
428			m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1],
429			m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1],
430			m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1],
431			m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1],
432			m1[0][0] * m2[3][0] + m1[1][0] * m2[3][1],
433			m1[0][1] * m2[3][0] + m1[1][1] * m2[3][1]);
434	}
435
436	template <typename T, precision P>
437	GLM_FUNC_QUALIFIER tmat2x2<T, P> operator/(tmat2x2<T, P> const & m, T scalar)
438	{
439		return tmat2x2<T, P>(
440			m[0] / scalar,
441			m[1] / scalar);
442	}
443
444	template <typename T, precision P>
445	GLM_FUNC_QUALIFIER tmat2x2<T, P> operator/(T scalar, tmat2x2<T, P> const & m)
446	{
447		return tmat2x2<T, P>(
448			scalar / m[0],
449			scalar / m[1]);
450	}
451
452	template <typename T, precision P>
453	GLM_FUNC_QUALIFIER typename tmat2x2<T, P>::col_type operator/(tmat2x2<T, P> const & m, typename tmat2x2<T, P>::row_type const & v)
454	{
455		return inverse(m) * v;
456	}
457
458	template <typename T, precision P>
459	GLM_FUNC_QUALIFIER typename tmat2x2<T, P>::row_type operator/(typename tmat2x2<T, P>::col_type const & v, tmat2x2<T, P> const & m)
460	{
461		return v *  inverse(m);
462	}
463
464	template <typename T, precision P>
465	GLM_FUNC_QUALIFIER tmat2x2<T, P> operator/(tmat2x2<T, P> const & m1, tmat2x2<T, P> const & m2)
466	{
467		tmat2x2<T, P> m1_copy(m1);
468		return m1_copy /= m2;
469	}
470
471	// -- Boolean operators --
472
473	template <typename T, precision P>
474	GLM_FUNC_QUALIFIER bool operator==(tmat2x2<T, P> const & m1, tmat2x2<T, P> const & m2)
475	{
476		return (m1[0] == m2[0]) && (m1[1] == m2[1]);
477	}
478
479	template <typename T, precision P>
480	GLM_FUNC_QUALIFIER bool operator!=(tmat2x2<T, P> const & m1, tmat2x2<T, P> const & m2)
481	{
482		return (m1[0] != m2[0]) || (m1[1] != m2[1]);
483	}
484} //namespace glm
485