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