• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/// @ref gtx_simd_mat4
2/// @file glm/gtx/simd_mat4.inl
3
4namespace glm{
5namespace detail{
6
7GLM_FUNC_QUALIFIER length_t fmat4x4SIMD::length() const
8{
9	return 4;
10}
11
12//////////////////////////////////////
13// Accesses
14
15GLM_FUNC_QUALIFIER fvec4SIMD & fmat4x4SIMD::operator[]
16(
17	length_t i
18)
19{
20	assert(i < this->length());
21
22	return this->Data[i];
23}
24
25GLM_FUNC_QUALIFIER fvec4SIMD const & fmat4x4SIMD::operator[]
26(
27	length_t i
28) const
29{
30	assert(i < this->length());
31
32	return this->Data[i];
33}
34
35//////////////////////////////////////////////////////////////
36// Constructors
37
38#if !GLM_HAS_DEFAULTED_FUNCTIONS || !defined(GLM_FORCE_NO_CTOR_INIT)
39	GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD()
40	{
41#		ifndef GLM_FORCE_NO_CTOR_INIT
42			this->Data[0] = fvec4SIMD(1, 0, 0, 0);
43			this->Data[1] = fvec4SIMD(0, 1, 0, 0);
44			this->Data[2] = fvec4SIMD(0, 0, 1, 0);
45			this->Data[3] = fvec4SIMD(0, 0, 0, 1);
46#		endif
47	}
48#	endif//!GLM_HAS_DEFAULTED_FUNCTIONS
49
50GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD(float const & s)
51{
52	this->Data[0] = fvec4SIMD(s, 0, 0, 0);
53	this->Data[1] = fvec4SIMD(0, s, 0, 0);
54	this->Data[2] = fvec4SIMD(0, 0, s, 0);
55	this->Data[3] = fvec4SIMD(0, 0, 0, s);
56}
57
58GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD
59(
60	float const & x0, float const & y0, float const & z0, float const & w0,
61	float const & x1, float const & y1, float const & z1, float const & w1,
62	float const & x2, float const & y2, float const & z2, float const & w2,
63	float const & x3, float const & y3, float const & z3, float const & w3
64)
65{
66	this->Data[0] = fvec4SIMD(x0, y0, z0, w0);
67	this->Data[1] = fvec4SIMD(x1, y1, z1, w1);
68	this->Data[2] = fvec4SIMD(x2, y2, z2, w2);
69	this->Data[3] = fvec4SIMD(x3, y3, z3, w3);
70}
71
72GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD
73(
74	fvec4SIMD const & v0,
75	fvec4SIMD const & v1,
76	fvec4SIMD const & v2,
77	fvec4SIMD const & v3
78)
79{
80	this->Data[0] = v0;
81	this->Data[1] = v1;
82	this->Data[2] = v2;
83	this->Data[3] = v3;
84}
85
86GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD
87(
88	mat4 const & m
89)
90{
91	this->Data[0] = fvec4SIMD(m[0]);
92	this->Data[1] = fvec4SIMD(m[1]);
93	this->Data[2] = fvec4SIMD(m[2]);
94	this->Data[3] = fvec4SIMD(m[3]);
95}
96
97GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD
98(
99	__m128 const in[4]
100)
101{
102	this->Data[0] = in[0];
103	this->Data[1] = in[1];
104	this->Data[2] = in[2];
105	this->Data[3] = in[3];
106}
107
108//////////////////////////////////////////////////////////////
109// mat4 operators
110
111#if !GLM_HAS_DEFAULTED_FUNCTIONS
112	GLM_FUNC_QUALIFIER fmat4x4SIMD& fmat4x4SIMD::operator=
113	(
114		fmat4x4SIMD const & m
115	)
116	{
117		this->Data[0] = m[0];
118		this->Data[1] = m[1];
119		this->Data[2] = m[2];
120		this->Data[3] = m[3];
121		return *this;
122	}
123#endif//!GLM_HAS_DEFAULTED_FUNCTIONS
124
125GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator+=
126(
127	fmat4x4SIMD const & m
128)
129{
130	this->Data[0].Data = _mm_add_ps(this->Data[0].Data, m[0].Data);
131	this->Data[1].Data = _mm_add_ps(this->Data[1].Data, m[1].Data);
132	this->Data[2].Data = _mm_add_ps(this->Data[2].Data, m[2].Data);
133	this->Data[3].Data = _mm_add_ps(this->Data[3].Data, m[3].Data);
134	return *this;
135}
136
137GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator-=
138(
139	fmat4x4SIMD const & m
140)
141{
142	this->Data[0].Data = _mm_sub_ps(this->Data[0].Data, m[0].Data);
143	this->Data[1].Data = _mm_sub_ps(this->Data[1].Data, m[1].Data);
144	this->Data[2].Data = _mm_sub_ps(this->Data[2].Data, m[2].Data);
145	this->Data[3].Data = _mm_sub_ps(this->Data[3].Data, m[3].Data);
146
147	return *this;
148}
149
150GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator*=
151(
152	fmat4x4SIMD const & m
153)
154{
155	sse_mul_ps(&this->Data[0].Data, &m.Data[0].Data, &this->Data[0].Data);
156	return *this;
157}
158
159GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator/=
160(
161	fmat4x4SIMD const & m
162)
163{
164	__m128 Inv[4];
165	sse_inverse_ps(&m.Data[0].Data, Inv);
166	sse_mul_ps(&this->Data[0].Data, Inv, &this->Data[0].Data);
167	return *this;
168}
169
170GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator+=
171(
172	float const & s
173)
174{
175	__m128 Operand = _mm_set_ps1(s);
176	this->Data[0].Data = _mm_add_ps(this->Data[0].Data, Operand);
177	this->Data[1].Data = _mm_add_ps(this->Data[1].Data, Operand);
178	this->Data[2].Data = _mm_add_ps(this->Data[2].Data, Operand);
179	this->Data[3].Data = _mm_add_ps(this->Data[3].Data, Operand);
180	return *this;
181}
182
183GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator-=
184(
185	float const & s
186)
187{
188	__m128 Operand = _mm_set_ps1(s);
189	this->Data[0].Data = _mm_sub_ps(this->Data[0].Data, Operand);
190	this->Data[1].Data = _mm_sub_ps(this->Data[1].Data, Operand);
191	this->Data[2].Data = _mm_sub_ps(this->Data[2].Data, Operand);
192	this->Data[3].Data = _mm_sub_ps(this->Data[3].Data, Operand);
193	return *this;
194}
195
196GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator*=
197(
198	float const & s
199)
200{
201	__m128 Operand = _mm_set_ps1(s);
202	this->Data[0].Data = _mm_mul_ps(this->Data[0].Data, Operand);
203	this->Data[1].Data = _mm_mul_ps(this->Data[1].Data, Operand);
204	this->Data[2].Data = _mm_mul_ps(this->Data[2].Data, Operand);
205	this->Data[3].Data = _mm_mul_ps(this->Data[3].Data, Operand);
206	return *this;
207}
208
209GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator/=
210(
211	float const & s
212)
213{
214	__m128 Operand = _mm_div_ps(one, _mm_set_ps1(s));
215	this->Data[0].Data = _mm_mul_ps(this->Data[0].Data, Operand);
216	this->Data[1].Data = _mm_mul_ps(this->Data[1].Data, Operand);
217	this->Data[2].Data = _mm_mul_ps(this->Data[2].Data, Operand);
218	this->Data[3].Data = _mm_mul_ps(this->Data[3].Data, Operand);
219	return *this;
220}
221
222GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator++ ()
223{
224	this->Data[0].Data = _mm_add_ps(this->Data[0].Data, one);
225	this->Data[1].Data = _mm_add_ps(this->Data[1].Data, one);
226	this->Data[2].Data = _mm_add_ps(this->Data[2].Data, one);
227	this->Data[3].Data = _mm_add_ps(this->Data[3].Data, one);
228	return *this;
229}
230
231GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator-- ()
232{
233	this->Data[0].Data = _mm_sub_ps(this->Data[0].Data, one);
234	this->Data[1].Data = _mm_sub_ps(this->Data[1].Data, one);
235	this->Data[2].Data = _mm_sub_ps(this->Data[2].Data, one);
236	this->Data[3].Data = _mm_sub_ps(this->Data[3].Data, one);
237	return *this;
238}
239
240
241//////////////////////////////////////////////////////////////
242// Binary operators
243
244GLM_FUNC_QUALIFIER fmat4x4SIMD operator+
245(
246	const fmat4x4SIMD &m,
247	float const & s
248)
249{
250	return detail::fmat4x4SIMD
251	(
252		m[0] + s,
253		m[1] + s,
254		m[2] + s,
255		m[3] + s
256	);
257}
258
259GLM_FUNC_QUALIFIER fmat4x4SIMD operator+
260(
261	float const & s,
262	const fmat4x4SIMD &m
263)
264{
265	return detail::fmat4x4SIMD
266	(
267		m[0] + s,
268		m[1] + s,
269		m[2] + s,
270		m[3] + s
271	);
272}
273
274GLM_FUNC_QUALIFIER fmat4x4SIMD operator+
275(
276    const fmat4x4SIMD &m1,
277    const fmat4x4SIMD &m2
278)
279{
280    return detail::fmat4x4SIMD
281    (
282        m1[0] + m2[0],
283        m1[1] + m2[1],
284        m1[2] + m2[2],
285        m1[3] + m2[3]
286    );
287}
288
289
290GLM_FUNC_QUALIFIER fmat4x4SIMD operator-
291(
292    const fmat4x4SIMD &m,
293    float const & s
294)
295{
296    return detail::fmat4x4SIMD
297    (
298        m[0] - s,
299        m[1] - s,
300        m[2] - s,
301        m[3] - s
302    );
303}
304
305GLM_FUNC_QUALIFIER fmat4x4SIMD operator-
306(
307    float const & s,
308    const fmat4x4SIMD &m
309)
310{
311    return detail::fmat4x4SIMD
312    (
313        s - m[0],
314        s - m[1],
315        s - m[2],
316        s - m[3]
317    );
318}
319
320GLM_FUNC_QUALIFIER fmat4x4SIMD operator-
321(
322    const fmat4x4SIMD &m1,
323    const fmat4x4SIMD &m2
324)
325{
326    return detail::fmat4x4SIMD
327    (
328        m1[0] - m2[0],
329        m1[1] - m2[1],
330        m1[2] - m2[2],
331        m1[3] - m2[3]
332    );
333}
334
335
336GLM_FUNC_QUALIFIER fmat4x4SIMD operator*
337(
338    const fmat4x4SIMD &m,
339    float const & s
340)
341{
342    return detail::fmat4x4SIMD
343    (
344        m[0] * s,
345        m[1] * s,
346        m[2] * s,
347        m[3] * s
348    );
349}
350
351GLM_FUNC_QUALIFIER fmat4x4SIMD operator*
352(
353    float const & s,
354    const fmat4x4SIMD &m
355)
356{
357    return detail::fmat4x4SIMD
358    (
359        m[0] * s,
360        m[1] * s,
361        m[2] * s,
362        m[3] * s
363    );
364}
365
366GLM_FUNC_QUALIFIER fvec4SIMD operator*
367(
368    const fmat4x4SIMD &m,
369    fvec4SIMD const & v
370)
371{
372    return sse_mul_ps(&m.Data[0].Data, v.Data);
373}
374
375GLM_FUNC_QUALIFIER fvec4SIMD operator*
376(
377    fvec4SIMD const & v,
378    const fmat4x4SIMD &m
379)
380{
381    return sse_mul_ps(v.Data, &m.Data[0].Data);
382}
383
384GLM_FUNC_QUALIFIER fmat4x4SIMD operator*
385(
386    const fmat4x4SIMD &m1,
387    const fmat4x4SIMD &m2
388)
389{
390    fmat4x4SIMD result;
391    sse_mul_ps(&m1.Data[0].Data, &m2.Data[0].Data, &result.Data[0].Data);
392
393    return result;
394}
395
396
397
398GLM_FUNC_QUALIFIER fmat4x4SIMD operator/
399(
400    const fmat4x4SIMD &m,
401    float const & s
402)
403{
404    return detail::fmat4x4SIMD
405    (
406        m[0] / s,
407        m[1] / s,
408        m[2] / s,
409        m[3] / s
410    );
411}
412
413GLM_FUNC_QUALIFIER fmat4x4SIMD operator/
414(
415    float const & s,
416    const fmat4x4SIMD &m
417)
418{
419    return detail::fmat4x4SIMD
420    (
421        s / m[0],
422        s / m[1],
423        s / m[2],
424        s / m[3]
425    );
426}
427
428GLM_FUNC_QUALIFIER detail::fmat4x4SIMD inverse(detail::fmat4x4SIMD const & m)
429{
430	detail::fmat4x4SIMD result;
431	detail::sse_inverse_ps(&m[0].Data, &result[0].Data);
432	return result;
433}
434
435GLM_FUNC_QUALIFIER fvec4SIMD operator/
436(
437	const fmat4x4SIMD & m,
438	fvec4SIMD const & v
439)
440{
441	return inverse(m) * v;
442}
443
444GLM_FUNC_QUALIFIER fvec4SIMD operator/
445(
446	fvec4SIMD const & v,
447	const fmat4x4SIMD &m
448)
449{
450	return v * inverse(m);
451}
452
453GLM_FUNC_QUALIFIER fmat4x4SIMD operator/
454(
455	const fmat4x4SIMD &m1,
456	const fmat4x4SIMD &m2
457)
458{
459	__m128 result[4];
460	__m128 inv[4];
461
462	sse_inverse_ps(&m2.Data[0].Data, inv);
463	sse_mul_ps(&m1.Data[0].Data, inv, result);
464
465	return fmat4x4SIMD(result);
466}
467
468
469//////////////////////////////////////////////////////////////
470// Unary constant operators
471GLM_FUNC_QUALIFIER fmat4x4SIMD const operator-
472(
473    fmat4x4SIMD const & m
474)
475{
476    return detail::fmat4x4SIMD
477    (
478        -m[0],
479        -m[1],
480        -m[2],
481        -m[3]
482    );
483}
484
485GLM_FUNC_QUALIFIER fmat4x4SIMD const operator--
486(
487    fmat4x4SIMD const & m,
488    int
489)
490{
491    return detail::fmat4x4SIMD
492    (
493        m[0] - 1.0f,
494        m[1] - 1.0f,
495        m[2] - 1.0f,
496        m[3] - 1.0f
497    );
498}
499
500GLM_FUNC_QUALIFIER fmat4x4SIMD const operator++
501(
502    fmat4x4SIMD const & m,
503    int
504)
505{
506    return detail::fmat4x4SIMD
507    (
508        m[0] + 1.0f,
509        m[1] + 1.0f,
510        m[2] + 1.0f,
511        m[3] + 1.0f
512    );
513}
514
515}//namespace detail
516
517GLM_FUNC_QUALIFIER mat4 mat4_cast
518(
519	detail::fmat4x4SIMD const & x
520)
521{
522	GLM_ALIGN(16) mat4 Result;
523	_mm_store_ps(&Result[0][0], x.Data[0].Data);
524	_mm_store_ps(&Result[1][0], x.Data[1].Data);
525	_mm_store_ps(&Result[2][0], x.Data[2].Data);
526	_mm_store_ps(&Result[3][0], x.Data[3].Data);
527	return Result;
528}
529
530GLM_FUNC_QUALIFIER detail::fmat4x4SIMD matrixCompMult
531(
532	detail::fmat4x4SIMD const & x,
533	detail::fmat4x4SIMD const & y
534)
535{
536	detail::fmat4x4SIMD result;
537	result[0] = x[0] * y[0];
538	result[1] = x[1] * y[1];
539	result[2] = x[2] * y[2];
540	result[3] = x[3] * y[3];
541	return result;
542}
543
544GLM_FUNC_QUALIFIER detail::fmat4x4SIMD outerProduct
545(
546	detail::fvec4SIMD const & c,
547	detail::fvec4SIMD const & r
548)
549{
550	__m128 Shu0 = _mm_shuffle_ps(r.Data, r.Data, _MM_SHUFFLE(0, 0, 0, 0));
551	__m128 Shu1 = _mm_shuffle_ps(r.Data, r.Data, _MM_SHUFFLE(1, 1, 1, 1));
552	__m128 Shu2 = _mm_shuffle_ps(r.Data, r.Data, _MM_SHUFFLE(2, 2, 2, 2));
553	__m128 Shu3 = _mm_shuffle_ps(r.Data, r.Data, _MM_SHUFFLE(3, 3, 3, 3));
554
555	detail::fmat4x4SIMD result(uninitialize);
556	result[0].Data = _mm_mul_ps(c.Data, Shu0);
557	result[1].Data = _mm_mul_ps(c.Data, Shu1);
558	result[2].Data = _mm_mul_ps(c.Data, Shu2);
559	result[3].Data = _mm_mul_ps(c.Data, Shu3);
560	return result;
561}
562
563GLM_FUNC_QUALIFIER detail::fmat4x4SIMD transpose(detail::fmat4x4SIMD const & m)
564{
565	detail::fmat4x4SIMD result;
566	glm_mat4_transpose(&m[0].Data, &result[0].Data);
567	return result;
568}
569
570GLM_FUNC_QUALIFIER float determinant(detail::fmat4x4SIMD const & m)
571{
572	float Result;
573	_mm_store_ss(&Result, glm_mat4_determinant(&m[0].Data));
574	return Result;
575}
576
577}//namespace glm
578