Nebula
Loading...
Searching...
No Matches
mat4.h
Go to the documentation of this file.
1#pragma once
2//------------------------------------------------------------------------------
11#include "core/types.h"
12#include "math/scalar.h"
13#include "math/vec4.h"
14#include "math/quat.h"
15#include "math/point.h"
16#include "math/vector.h"
17#include "math/sse.h"
18
19//------------------------------------------------------------------------------
20
21#define mm_ror_ps(vec,i) \
22 (((i)%4) ? (_mm_shuffle_ps(vec,vec, _MM_SHUFFLE((unsigned char)(i+3)%4,(unsigned char)(i+2)%4,(unsigned char)(i+1)%4,(unsigned char)(i+0)%4))) : (vec))
23
24namespace Math
25{
26
27struct mat4;
28struct quat;
29
30static const __m128i maskX = _mm_setr_epi32( -1,0,0,0 );
31static const __m128i maskY = _mm_setr_epi32( 0,-1,0,0 );
32static const __m128i maskZ = _mm_setr_epi32( 0,0,-1,0 );
33static const __m128i maskW = _mm_setr_epi32( 0,0,0,-1 );
34
35mat4 rotationquat(const quat& q);
36mat4 reflect(const vec4& p);
37void decompose(const mat4& mat, vec3& outScale, quat& outRotation, vec3& outTranslation);
38mat4 affine(const vec3& scale, const vec3& rotationCenter, const quat& rotation, const vec3& translation);
39mat4 affine(const vec3& scale, const quat& rotation, const vec3& translation);
40mat4 affine(const vec3& scale, const vec3& rotation, const vec3& translation);
41mat4 affinetransformation(scalar scale, const vec3& rotationCenter, const quat& rotation, const vec3& translation);
42mat4 transformation(const vec3& scalingCenter, const quat& scalingRotation, const vec3& scale, const vec3& rotationCenter, const quat& rotation, const vec3& trans);
43bool ispointinside(const vec4& p, const mat4& m);
44mat4 skewsymmetric(const vec3& v);
45mat4 fromeuler(const vec3& v);
46vec3 aseuler(const mat4& m);
47
49{
50public:
52 mat4();
54 mat4(const mat4& rhs) = default;
56 mat4(const vec4& row0, const vec4& row1, const vec4& row2, const vec4& row3);
58 mat4(
59 float m00, float m01, float m02, float m03,
60 float m10, float m11, float m12, float m13,
61 float m20, float m21, float m22, float m23,
62 float m30, float m31, float m32, float m33);
63
65 bool operator==(const mat4& rhs) const;
67 bool operator!=(const mat4& rhs) const;
69 vec4& operator[](size_t const i);
71 vec4 const& operator[](size_t const i) const;
72
74 void load(const scalar* ptr);
76 void loadu(const scalar* ptr);
78 void store(scalar* ptr) const;
80 void store3(scalar* ptr) const;
82 void storeu(scalar* ptr) const;
84 void stream(scalar* ptr) const;
85
87 void set(const vec4& r0, const vec4& r1, const vec4& r2, const vec4& r3);
89 void set(
90 float m00, float m01, float m02, float m03,
91 float m10, float m11, float m12, float m13,
92 float m20, float m21, float m22, float m23,
93 float m30, float m31, float m32, float m33);
94
96 void get_scale(vec4& scale) const;
98 void translate(const vec3& t);
100 void translate(const float x, const float y, const float z);
102 vec4 get_x() const;
104 vec4 get_y() const;
106 vec4 get_z() const;
108 vec4 get_w() const;
110 void scale(const vec3& v);
112 void scale(const float x, const float y, const float z);
113
114
116 union
117 {
118 struct
119 {
124 };
125
127 struct
128 {
129 float _11, _12, _13, _14;
130 float _21, _22, _23, _24;
131 float _31, _32, _33, _34;
132 float _41, _42, _43, _44;
133 };
134 float m[4][4];
135
137 vec4 r[4];
138 struct
139 {
144 };
145 };
146
147 static const mat4 identity;
148};
149
150//------------------------------------------------------------------------------
153__forceinline
155{
156 // empty
157}
158
159//------------------------------------------------------------------------------
162__forceinline
163mat4::mat4(const vec4& row0, const vec4& row1, const vec4& row2, const vec4& row3)
164{
165 r[0] = row0.vec;
166 r[1] = row1.vec;
167 r[2] = row2.vec;
168 r[3] = row3.vec;
169}
170
171//------------------------------------------------------------------------------
174__forceinline
175mat4::mat4(float m00, float m01, float m02, float m03, float m10, float m11, float m12, float m13, float m20, float m21, float m22, float m23, float m30, float m31, float m32, float m33)
176{
177 this->r[0] = vec4(m00, m01, m02, m03);
178 this->r[1] = vec4(m10, m11, m12, m13);
179 this->r[2] = vec4(m20, m21, m22, m23);
180 this->r[3] = vec4(m30, m31, m32, m33);
181}
182
183//------------------------------------------------------------------------------
186__forceinline bool
187mat4::operator==(const mat4& rhs) const
188{
189 return vec4(r[0]) == vec4(rhs.r[0]) &&
190 vec4(r[1]) == vec4(rhs.r[1]) &&
191 vec4(r[2]) == vec4(rhs.r[2]) &&
192 vec4(r[3]) == vec4(rhs.r[3]);
193}
194
195//------------------------------------------------------------------------------
198__forceinline bool
199mat4::operator!=(const mat4& rhs) const
200{
201 return !(*this == rhs);
202}
203
204//--------------------------------------------------------------------------
207__forceinline vec4 const&
208mat4::operator[](size_t const i) const
209{
210#if NEBULA_BOUNDS_CHECK
211 n_assert(i < 4);
212#endif
213 return this->r[i];
214}
215
216//--------------------------------------------------------------------------
219__forceinline vec4&
220mat4::operator[](size_t const i)
221{
222#if NEBULA_BOUNDS_CHECK
223 n_assert(i < 4);
224#endif
225 return this->r[i];
226}
227
228//------------------------------------------------------------------------------
231__forceinline void
233{
234 r[0] = _mm_load_ps(ptr);
235 r[1] = _mm_load_ps(ptr + 4);
236 r[2] = _mm_load_ps(ptr + 8);
237 r[3] = _mm_load_ps(ptr + 12);
238}
239
240//------------------------------------------------------------------------------
243__forceinline void
245{
246 r[0] = _mm_loadu_ps(ptr);
247 r[1] = _mm_loadu_ps(ptr + 4);
248 r[2] = _mm_loadu_ps(ptr + 8);
249 r[3] = _mm_loadu_ps(ptr + 12);
250}
251
252//------------------------------------------------------------------------------
255__forceinline void
257{
258 _mm_store_ps(ptr, r[0].vec);
259 _mm_store_ps((ptr + 4), r[1].vec);
260 _mm_store_ps((ptr + 8), r[2].vec);
261 _mm_store_ps((ptr + 12), r[3].vec);
262}
263
264//------------------------------------------------------------------------------
267__forceinline void
269{
270 _mm_store_ps(ptr, r[0].vec);
271 _mm_store_ps((ptr + 4), r[1].vec);
272 _mm_store_ps((ptr + 8), r[2].vec);
273}
274
275//------------------------------------------------------------------------------
278__forceinline void
280{
281 _mm_storeu_ps(ptr, r[0].vec);
282 _mm_storeu_ps((ptr + 4), r[1].vec);
283 _mm_storeu_ps((ptr + 8), r[2].vec);
284 _mm_storeu_ps((ptr + 12), r[3].vec);
285}
286
287//------------------------------------------------------------------------------
290__forceinline void
292{
293 this->storeu(ptr);
294}
295
296
297//------------------------------------------------------------------------------
300__forceinline void
301mat4::set(const vec4& r0, const vec4& r1, const vec4& r2, const vec4& r3)
302{
303 this->r[0] = r0;
304 this->r[1] = r1;
305 this->r[2] = r2;
306 this->r[3] = r3;
307}
308
309//------------------------------------------------------------------------------
312__forceinline void
313mat4::set(float m00, float m01, float m02, float m03, float m10, float m11, float m12, float m13, float m20, float m21, float m22, float m23, float m30, float m31, float m32, float m33)
314{
315 this->r[0] = vec4(m00, m01, m02, m03);
316 this->r[1] = vec4(m10, m11, m12, m13);
317 this->r[2] = vec4(m20, m21, m22, m23);
318 this->r[3] = vec4(m30, m31, m32, m33);
319}
320
321//------------------------------------------------------------------------------
324__forceinline void
326{
327 vec4 xaxis = r[0];
328 vec4 yaxis = r[1];
329 vec4 zaxis = r[2];
330 scalar xScale = length3(xaxis);
331 scalar yScale = length3(yaxis);
332 scalar zScale = length3(zaxis);
333
334 v = vec4(xScale, yScale, zScale, 1.0f);
335}
336
337//------------------------------------------------------------------------------
340__forceinline vec4
342{
343 return this->r[0];
344}
345
346//------------------------------------------------------------------------------
349__forceinline vec4
351{
352 return this->r[1];
353}
354
355//------------------------------------------------------------------------------
358__forceinline vec4
360{
361 return this->r[2];
362}
363
364//------------------------------------------------------------------------------
367__forceinline vec4
369{
370 return this->r[3];
371}
372
373//------------------------------------------------------------------------------
376__forceinline void
378{
379 this->r[3] = _mm_add_ps(r[3].vec, t.vec);
380}
381
382//------------------------------------------------------------------------------
385__forceinline void
387{
388 // need to make sure that last column isn't erased
389 vec4 scl = vec4(s, 1.0f);
390
391 r[0] = r[0] * scl;
392 r[1] = r[1] * scl;
393 r[2] = r[2] * scl;
394 r[3] = r[3] * scl;
395}
396
397//------------------------------------------------------------------------------
400__forceinline bool
402{
403 return m.r[0] == _id_x &&
404 m.r[1] == _id_y &&
405 m.r[2] == _id_z &&
406 m.r[3] == _id_w;
407}
408
409//------------------------------------------------------------------------------
412__forceinline scalar
414{
415 __m128 Va,Vb,Vc;
416 __m128 r1,r2,r3,tt,tt2;
417 __m128 sum,Det;
418
419 __m128 _L1 = m.r[0].vec;
420 __m128 _L2 = m.r[1].vec;
421 __m128 _L3 = m.r[2].vec;
422 __m128 _L4 = m.r[3].vec;
423 // Calculating the minterms for the first line.
424
425 // _mm_ror_ps is just a macro using _mm_shuffle_ps().
426 tt = _L4; tt2 = mm_ror_ps(_L3,1);
427 Vc = _mm_mul_ps(tt2, mm_ror_ps(tt,0)); // V3' dot V4
428 Va = _mm_mul_ps(tt2, mm_ror_ps(tt,2)); // V3' dot V4"
429 Vb = _mm_mul_ps(tt2, mm_ror_ps(tt,3)); // V3' dot V4^
430
431 r1 = _mm_sub_ps(mm_ror_ps(Va,1), mm_ror_ps(Vc,2)); // V3" dot V4^ - V3^ dot V4"
432 r2 = _mm_sub_ps(mm_ror_ps(Vb,2), mm_ror_ps(Vb,0)); // V3^ dot V4' - V3' dot V4^
433 r3 = _mm_sub_ps(mm_ror_ps(Va,0), mm_ror_ps(Vc,1)); // V3' dot V4" - V3" dot V4'
434
435 tt = _L2;
436 Va = mm_ror_ps(tt,1); sum = _mm_mul_ps(Va,r1);
437 Vb = mm_ror_ps(tt,2); sum = _mm_add_ps(sum,_mm_mul_ps(Vb,r2));
438 Vc = mm_ror_ps(tt,3); sum = _mm_add_ps(sum,_mm_mul_ps(Vc,r3));
439
440 // Calculating the determinant.
441 Det = _mm_mul_ps(sum,_L1);
442 Det = _mm_add_ps(Det,_mm_movehl_ps(Det,Det));
443
444 // Calculating the minterms of the second line (using previous results).
445 tt = mm_ror_ps(_L1,1); sum = _mm_mul_ps(tt,r1);
446 tt = mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r2));
447 tt = mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r3));
448
449 // Testing the determinant.
450 Det = _mm_sub_ss(Det,_mm_shuffle_ps(Det,Det,1));
451 return vec4(Det).x;
452}
453
454//------------------------------------------------------------------------------
457__forceinline mat4
458inverse(const mat4& m)
459{
460 __m128 Va,Vb,Vc;
461 __m128 r1,r2,r3,tt,tt2;
462 __m128 sum,Det,RDet;
463 __m128 trns0,trns1,trns2,trns3;
464
465 const __m128i pnpn = _mm_setr_epi32(0x00000000, static_cast<int>(0x80000000), 0x00000000, static_cast<int>(0x80000000));
466 const __m128i npnp = _mm_setr_epi32(static_cast<int>(0x80000000), 0x00000000, static_cast<int>(0x80000000), 0x00000000);
467 const __m128 zeroone = _mm_setr_ps(1.0f, 0.0f, 0.0f, 1.0f);
468
469 __m128 _L1 = m.r[0].vec;
470 __m128 _L2 = m.r[1].vec;
471 __m128 _L3 = m.r[2].vec;
472 __m128 _L4 = m.r[3].vec;
473 // Calculating the minterms for the first line.
474
475 // _mm_ror_ps is just a macro using _mm_shuffle_ps().
476 tt = _L4; tt2 = mm_ror_ps(_L3,1);
477 Vc = _mm_mul_ps(tt2, mm_ror_ps(tt,0)); // V3'dot V4
478 Va = _mm_mul_ps(tt2, mm_ror_ps(tt,2)); // V3'dot V4"
479 Vb = _mm_mul_ps(tt2, mm_ror_ps(tt,3)); // V3' dot V4^
480
481 r1 = _mm_sub_ps(mm_ror_ps(Va,1), mm_ror_ps(Vc,2)); // V3" dot V4^ - V3^ dot V4"
482 r2 = _mm_sub_ps(mm_ror_ps(Vb,2), mm_ror_ps(Vb,0)); // V3^ dot V4' - V3' dot V4^
483 r3 = _mm_sub_ps(mm_ror_ps(Va,0), mm_ror_ps(Vc,1)); // V3' dot V4" - V3" dot V4'
484
485 tt = _L2;
486 Va = mm_ror_ps(tt,1); sum = _mm_mul_ps(Va,r1);
487 Vb = mm_ror_ps(tt,2); sum = _mm_add_ps(sum,_mm_mul_ps(Vb,r2));
488 Vc = mm_ror_ps(tt,3); sum = _mm_add_ps(sum,_mm_mul_ps(Vc,r3));
489
490 // Calculating the determinant.
491 Det = _mm_mul_ps(sum,_L1);
492 Det = _mm_add_ps(Det,_mm_movehl_ps(Det,Det));
493
494
495 __m128 mtL1 = _mm_xor_ps(sum, _mm_castsi128_ps(pnpn));
496
497 // Calculating the minterms of the second line (using previous results).
498 tt = mm_ror_ps(_L1,1); sum = _mm_mul_ps(tt,r1);
499 tt = mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r2));
500 tt = mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r3));
501 __m128 mtL2 = _mm_xor_ps(sum, _mm_castsi128_ps(npnp));
502
503 // Testing the determinant.
504 Det = _mm_sub_ss(Det,_mm_shuffle_ps(Det,Det,1));
505
506 // Calculating the minterms of the third line.
507 tt = mm_ror_ps(_L1,1);
508 Va = _mm_mul_ps(tt,Vb); // V1' dot V2"
509 Vb = _mm_mul_ps(tt,Vc); // V1' dot V2^
510 Vc = _mm_mul_ps(tt,_L2); // V1' dot V2
511
512 r1 = _mm_sub_ps(mm_ror_ps(Va,1), mm_ror_ps(Vc,2)); // V1" dot V2^ - V1^ dot V2"
513 r2 = _mm_sub_ps(mm_ror_ps(Vb,2), mm_ror_ps(Vb,0)); // V1^ dot V2' - V1' dot V2^
514 r3 = _mm_sub_ps(mm_ror_ps(Va,0), mm_ror_ps(Vc,1)); // V1' dot V2" - V1" dot V2'
515
516 tt = mm_ror_ps(_L4,1); sum = _mm_mul_ps(tt,r1);
517 tt = mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r2));
518 tt = mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r3));
519 __m128 mtL3 = _mm_xor_ps(sum, _mm_castsi128_ps(pnpn));
520
521 // Dividing is FASTER than rcp_nr! (Because rcp_nr causes many register-memory RWs).
522 RDet = _mm_div_ss(zeroone, Det); // TODO: just 1.0f?
523 RDet = _mm_shuffle_ps(RDet,RDet,0x00);
524
525 // Devide the first 12 minterms with the determinant.
526 mtL1 = _mm_mul_ps(mtL1, RDet);
527 mtL2 = _mm_mul_ps(mtL2, RDet);
528 mtL3 = _mm_mul_ps(mtL3, RDet);
529
530 // Calculate the minterms of the forth line and devide by the determinant.
531 tt = mm_ror_ps(_L3,1); sum = _mm_mul_ps(tt,r1);
532 tt = mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r2));
533 tt = mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r3));
534 __m128 mtL4 = _mm_xor_ps(sum, _mm_castsi128_ps(npnp));
535 mtL4 = _mm_mul_ps(mtL4, RDet);
536
537 // Now we just have to transpose the minterms matrix.
538 trns0 = _mm_unpacklo_ps(mtL1,mtL2);
539 trns1 = _mm_unpacklo_ps(mtL3,mtL4);
540 trns2 = _mm_unpackhi_ps(mtL1,mtL2);
541 trns3 = _mm_unpackhi_ps(mtL3,mtL4);
542 _L1 = _mm_movelh_ps(trns0,trns1);
543 _L2 = _mm_movehl_ps(trns1,trns0);
544 _L3 = _mm_movelh_ps(trns2,trns3);
545 _L4 = _mm_movehl_ps(trns3,trns2);
546
547 return mat4(vec4(_L1), vec4(_L2), vec4(_L3), vec4(_L4));
548}
549
550//------------------------------------------------------------------------------
553__forceinline mat4
554lookatlh(const point& eye, const point& at, const vector& up)
555{
556#if NEBULA_DEBUG
557 n_assert(length(up) > 0);
558#endif
559 // hmm the XM lookat functions are kinda pointless, because they
560 // return a VIEW matrix, which is already inverse (so one would
561 // need to reverse again!)
562 const vector zaxis = normalize(at - eye);
563 vector normUp = normalize(up);
564 if (Math::abs(dot(zaxis, normUp)) > 0.9999999f)
565 {
566 // need to choose a different up vector because up and lookat point
567 // into same or opposite direction
568 // just rotate y->x, x->z and z->y
569 normUp = permute(normUp, normUp, 1, 2, 0);
570 }
571 const vector xaxis = normalize(cross(normUp, zaxis));
572 const vector yaxis = normalize(cross(zaxis, xaxis));
573 return mat4(xaxis, yaxis, zaxis, eye);
574}
575
576//------------------------------------------------------------------------------
579__forceinline mat4
580lookatrh(const point& eye, const point& at, const vector& up)
581{
582#if NEBULA_DEBUG
583 n_assert(length(up) > 0);
584#endif
585 // hmm the XM lookat functions are kinda pointless, because they
586 // return a VIEW matrix, which is already inverse (so one would
587 // need to reverse again!)
588 const vector zaxis = normalize(eye - at);
589 vector normUp = normalize(up);
590 if (Math::abs(dot(zaxis, normUp)) > 0.9999999f)
591 {
592 // need to choose a different up vector because up and lookat point
593 // into same or opposite direction
594 // just rotate y->x, x->z and z->y
595 normUp = permute(normUp, normUp, 1, 2, 0);
596 }
597 const vector xaxis = normalize(cross(normUp, zaxis));
598 const vector yaxis = normalize(cross(zaxis, xaxis));
599 return mat4(xaxis, yaxis, zaxis, eye);
600}
601
602#ifdef N_USE_AVX
603// dual linear combination using AVX instructions on YMM regs
604static inline __m256 twolincomb_AVX_8(__m256 A01, const mat4 &B)
605{
606 __m256 result;
607 result = _mm256_mul_ps(_mm256_shuffle_ps(A01, A01, 0x00), _mm256_broadcast_ps(&B.r[0].vec));
608 result = _mm256_add_ps(result, _mm256_mul_ps(_mm256_shuffle_ps(A01, A01, 0x55), _mm256_broadcast_ps(&B.r[1].vec)));
609 result = _mm256_add_ps(result, _mm256_mul_ps(_mm256_shuffle_ps(A01, A01, 0xaa), _mm256_broadcast_ps(&B.r[2].vec)));
610 result = _mm256_add_ps(result, _mm256_mul_ps(_mm256_shuffle_ps(A01, A01, 0xff), _mm256_broadcast_ps(&B.r[3].vec)));
611 return result;
612}
613
614//------------------------------------------------------------------------------
617__forceinline mat4
618operator*(const mat4& m0, const mat4& m1)
619{
620 mat4 out;
621
622 _mm256_zeroupper();
623 __m256 A01 = _mm256_loadu_ps(&m1.m[0][0]);
624 __m256 A23 = _mm256_loadu_ps(&m1.m[2][0]);
625
626 __m256 out01x = twolincomb_AVX_8(A01, m0);
627 __m256 out23x = twolincomb_AVX_8(A23, m0);
628
629 _mm256_storeu_ps(&out.m[0][0], out01x);
630 _mm256_storeu_ps(&out.m[2][0], out23x);
631 return out;
632}
633
634__forceinline mat4 operator%(const mat4& m1, const mat4& m0) = delete;
635
636#else
637//------------------------------------------------------------------------------
640__forceinline mat4
641operator*(const mat4& m0, const mat4& m1)
642{
643 mat4 ret;
644
645 vec4 mw = m1.r[0];
646
647 // Splat the all components of the first row
648 vec4 mx = splat_x(mw);
649 vec4 my = splat_y(mw);
650 vec4 mz = splat_z(mw);
651 mw = splat_w(mw);
652
653 vec4 m1x = m0.r[0];
654 vec4 m1y = m0.r[1];
655 vec4 m1z = m0.r[2];
656 vec4 m1w = m0.r[3];
657
658 //multiply first row
659 mx = multiply(mx, m1x);
660 my = multiply(my, m1y);
661 mz = multiply(mz, m1z);
662 mw = multiply(mw, m1w);
663
664 mx = mx + my;
665 mz = mz + mw;
666 ret.r[0] = mx + mz;
667
668 // rinse and repeat
669 mw = m1.row1;
670
671 mx = splat_x(mw);
672 my = splat_y(mw);
673 mz = splat_z(mw);
674 mw = splat_w(mw);
675
676 mx = multiply(mx, m1x);
677 my = multiply(my, m1y);
678 mz = multiply(mz, m1z);
679 mw = multiply(mw, m1w);
680
681 mx = mx + my;
682 mz = mz + mw;
683 ret.r[1] = mx + mz;
684
685 mw = m1.row2;
686
687 mx = splat_x(mw);
688 my = splat_y(mw);
689 mz = splat_z(mw);
690 mw = splat_w(mw);
691
692 mx = multiply(mx, m0.r[0]);
693 my = multiply(my, m0.r[1]);
694 mz = multiply(mz, m0.r[2]);
695 mw = multiply(mw, m0.r[3]);
696
697 mx = mx + my;
698 mz = mz + mw;
699 ret.r[2] = mx + mz;
700
701 mw = m1.row3;
702
703 mx = splat_x(mw);
704 my = splat_y(mw);
705 mz = splat_z(mw);
706 mw = splat_w(mw);
707
708 mx = multiply(mx, m1x);
709 my = multiply(my, m1y);
710 mz = multiply(mz, m1z);
711 mw = multiply(mw, m1w);
712
713 mx = mx + my;
714 mz = mz + mw;
715 ret.r[3] = mx + mz;
716
717 return ret;
718}
719#endif
720
721//------------------------------------------------------------------------------
724__forceinline vec4
725operator*(const mat4& m, const vec4& v)
726{
727 __m128 x = _mm_shuffle_ps(v.vec, v.vec, _MM_SHUFFLE(0, 0, 0, 0));
728 __m128 y = _mm_shuffle_ps(v.vec, v.vec, _MM_SHUFFLE(1, 1, 1, 1));
729 __m128 z = _mm_shuffle_ps(v.vec, v.vec, _MM_SHUFFLE(2, 2, 2, 2));
730 __m128 w = _mm_shuffle_ps(v.vec, v.vec, _MM_SHUFFLE(3, 3, 3, 3));
731
732 return
733 fmadd(x, m.r[0].vec,
734 fmadd(y, m.r[1].vec,
735 fmadd(z, m.r[2].vec,
736 _mm_mul_ps(w, m.r[3].vec))));
737}
738
739//------------------------------------------------------------------------------
742__forceinline vec4
743operator*(const mat4& m, const vec3& v)
744{
745 __m128 x = _mm_shuffle_ps(v.vec, v.vec, _MM_SHUFFLE(0, 0, 0, 0));
746 x = _mm_and_ps(x, _mask_xyz);
747 __m128 y = _mm_shuffle_ps(v.vec, v.vec, _MM_SHUFFLE(1, 1, 1, 1));
748 y = _mm_and_ps(y, _mask_xyz);
749 __m128 z = _mm_shuffle_ps(v.vec, v.vec, _MM_SHUFFLE(2, 2, 2, 2));
750 z = _mm_and_ps(z, _mask_xyz);
751
752 return
753 fmadd(x, m.r[0].vec,
754 fmadd(y, m.r[1].vec,
755 _mm_mul_ps(z, m.r[2].vec)));
756}
757
758//------------------------------------------------------------------------------
761__forceinline vec4
762operator*(const mat4& m, const point& p)
763{
764 __m128 x = _mm_shuffle_ps(p.vec, p.vec, _MM_SHUFFLE(0, 0, 0, 0));
765 __m128 y = _mm_shuffle_ps(p.vec, p.vec, _MM_SHUFFLE(1, 1, 1, 1));
766 __m128 z = _mm_shuffle_ps(p.vec, p.vec, _MM_SHUFFLE(2, 2, 2, 2));
767 __m128 w = _mm_shuffle_ps(p.vec, p.vec, _MM_SHUFFLE(3, 3, 3, 3));
768
769 return
770 fmadd(x, m.r[0].vec,
771 fmadd(y, m.r[1].vec,
772 fmadd(z, m.r[2].vec,
773 _mm_mul_ps(w, m.r[3].vec))));
774}
775
776//------------------------------------------------------------------------------
779__forceinline vector
780operator*(const mat4& m, const vector& v)
781{
782 __m128 x = _mm_shuffle_ps(v.vec, v.vec, _MM_SHUFFLE(0, 0, 0, 0));
783 x = _mm_and_ps(x, _mask_xyz);
784 __m128 y = _mm_shuffle_ps(v.vec, v.vec, _MM_SHUFFLE(1, 1, 1, 1));
785 y = _mm_and_ps(y, _mask_xyz);
786 __m128 z = _mm_shuffle_ps(v.vec, v.vec, _MM_SHUFFLE(2, 2, 2, 2));
787 z = _mm_and_ps(z, _mask_xyz);
788
789 return
790 fmadd(x, m.r[0].vec,
791 fmadd(y, m.r[1].vec,
792 _mm_mul_ps(z, m.r[2].vec)));
793}
794
795//------------------------------------------------------------------------------
798__forceinline mat4
800{
802 scalar dist = 1.0f / (zf - zn);
803 m.r[0] = vec4(2.0f / w, 0.0f, 0.0f, 0.0f);
804 m.r[1] = vec4(0.0f, 2.0f / h, 0.0f, 0.0f);
805 m.r[2] = vec4(0.0f, 0.0f, 2.0f * dist, 0.0f);
806 m.r[3] = vec4(0.0f, 0.0, -dist * (zf + zn), 1.0f);
807 return m;
808}
809
810//------------------------------------------------------------------------------
813__forceinline mat4
815{
817 scalar dist = 1.0f / (zn - zf);
818 m.r[0] = vec4(2.0f / w, 0.0f, 0.0f, 0.0f);
819 m.r[1] = vec4(0.0f, 2.0f / h, 0.0f, 0.0f);
820 m.r[2] = vec4(0.0f, 0.0f, 2.0f * dist, 0.0f);
821 m.r[3] = vec4(0.0f, 0.0, dist * (zf + zn), 1.0f);
822 return m;
823}
824
825//------------------------------------------------------------------------------
828__forceinline mat4
830{
832 scalar divwidth = 1.0f / (r - l);
833 scalar divheight = 1.0f / (t - b);
834 scalar dist = 1.0f / (zf - zn);
835 m.r[0] = vec4(2.0f * divwidth, 0.0f, 0.0f, 0.0f);
836 m.r[1] = vec4(0.0f, 2.0f * divheight, 0.0f, 0.0f);
837 m.r[2] = vec4(0.0f, 0.0f, 2.0f * dist, 0.0f);
838 m.r[3] = vec4(-(l+r) * divwidth, - (b+t) * divheight, -dist * (zf + zn), 1.0f);
839 return m;
840}
841
842//------------------------------------------------------------------------------
845__forceinline mat4
847{
849 scalar divwidth = 1.0f / (r - l);
850 scalar divheight = 1.0f / (t - b);
851 scalar dist = 1.0f / (zn - zf);
852 m.r[0] = vec4(2.0f * divwidth, 0.0f, 0.0f, 0.0f);
853 m.r[1] = vec4(0.0f, 2.0f * divheight, 0.0f, 0.0f);
854 m.r[2] = vec4(0.0f, 0.0f, 2.0f * dist, 0.0f);
855 m.r[3] = vec4(-(l+r) * divwidth, - (b+t) * divheight, dist * (zf + zn), 1.0f);
856 return m;
857}
858
859//------------------------------------------------------------------------------
862__forceinline mat4
863perspfovlh(scalar fovy, scalar aspect, scalar zn, scalar zf)
864{
866 scalar halfFov = 0.5f * fovy;
867 scalar sinfov = Math::sin(halfFov);
868 scalar cosfov = Math::cos(halfFov);
869
870 scalar height = cosfov / sinfov;
871 scalar width = height / aspect;
872
873 scalar dist = zf / (zf - zn);
874 m.r[0] = vec4(width, 0.0f, 0.0f, 0.0f);
875 m.r[1] = vec4(0.0f, height, 0.0f, 0.0f);
876 m.r[2] = vec4(0.0f, 0.0f, dist, 1.0f);
877 m.r[3] = vec4(0.0f, 0.0f, -dist * zn, 0.0f);
878
879 return m;
880}
881
882//------------------------------------------------------------------------------
885__forceinline mat4
886perspfovrh(scalar fovy, scalar aspect, scalar zn, scalar zf)
887{
889 scalar halfFov = 0.5f * fovy;
890 scalar sinfov = Math::sin(halfFov);
891 scalar cosfov = Math::cos(halfFov);
892
893 scalar height = cosfov / sinfov;
894 scalar width = height / aspect;
895
896 scalar dist = zf / (zn - zf);
897
898 m.r[0] = vec4(width, 0.0f, 0.0f, 0.0f);
899 m.r[1] = vec4(0.0f, height, 0.0f, 0.0f);
900 m.r[2] = vec4(0.0f, 0.0f, dist, -1.0f);
901 m.r[3] = vec4(0.0f, 0.0f, dist * zn, 0.0f);
902
903 return m;
904}
905
906//------------------------------------------------------------------------------
909__forceinline mat4
911{
913 scalar dist = zf / (zf - zn);
914
915 m.r[0] = vec4(2.0f * zn / w, 0.0f, 0.0f, 0.0f);
916 m.r[1] = vec4(0.0f, 2.0f * zn / h, 0.0f, 0.0f);
917 m.r[2] = vec4(0.0f, 0.0f, dist, 1.0f);
918 m.r[3] = vec4(0.0f, 0.0, -dist * zn, 0.0f);
919 return m;
920}
921
922//------------------------------------------------------------------------------
925__forceinline mat4
927{
929 scalar dist = zf / (zn - zf);
930
931 m.r[0] = vec4(2.0f * zn / w, 0.0f, 0.0f, 0.0f);
932 m.r[1] = vec4(0.0f, 2.0f * zn / h, 0.0f, 0.0f);
933 m.r[2] = vec4(0.0f, 0.0f, dist, -1.0f);
934 m.r[3] = vec4(0.0f, 0.0, dist * zn, 0.0f);
935 return m;
936}
937
938//------------------------------------------------------------------------------
941__forceinline mat4
943{
945 scalar divwidth = 1.0f / (r - l);
946 scalar divheight = 1.0f / (t - b);
947 scalar dist = zf / (zf - zn);
948
949 m.r[0] = vec4(2.0f * zn * divwidth, 0.0f, 0.0f, 0.0f);
950 m.r[1] = vec4(0.0f, 2.0f * zn * divheight, 0.0f, 0.0f);
951 m.r[2] = vec4(-(l + r) * divwidth, -(b + t) * divheight, dist, 1.0f);
952 m.r[3] = vec4(0.0f, 0.0f, -dist * zn, 0.0f);
953 return m;
954}
955
956//------------------------------------------------------------------------------
959__forceinline mat4
961{
963 scalar divwidth = 1.0f / (r - l);
964 scalar divheight = 1.0f / (t - b);
965 scalar dist = zf / (zn - zf);
966
967 m.r[0] = vec4(2.0f * zn * divwidth, 0.0f, 0.0f, 0.0f);
968 m.r[1] = vec4(0.0f, 2.0f * zn * divheight, 0.0f, 0.0f);
969 m.r[2] = vec4((l + r) * divwidth, (b + t) * divheight, dist, -1.0f);
970 m.r[3] = vec4(0.0f, 0.0f, dist * zn, 0.0f);
971 return m;
972}
973
974//------------------------------------------------------------------------------
977__forceinline mat4
979{
980 __m128 norm = normalize(axis).vec;
981
982 scalar sangle = Math::sin(angle);
983 scalar cangle = Math::cos(angle);
984
985 __m128 m1_c = _mm_set_ps1(1.0f - cangle);
986 __m128 c = _mm_set_ps1(cangle);
987 __m128 s = _mm_set_ps1(sangle);
988
989 __m128 nn1 = _mm_shuffle_ps(norm,norm,_MM_SHUFFLE(3,0,2,1));
990 __m128 nn2 = _mm_shuffle_ps(norm,norm,_MM_SHUFFLE(3,1,0,2));
991
992 __m128 v = _mm_mul_ps(nn1,m1_c);
993 v = _mm_mul_ps(nn2,v);
994
995 __m128 nn3 = _mm_mul_ps(norm, m1_c);
996 nn3 = _mm_mul_ps(norm, nn3);
997 nn3 = _mm_add_ps(nn3, c);
998
999 __m128 nn4 = _mm_mul_ps(norm,s);
1000 nn4 = _mm_add_ps(nn4, v);
1001 __m128 nn5 = _mm_mul_ps(s, norm);
1002 nn5 = _mm_sub_ps(v,nn5);
1003
1004 v = _mm_and_ps(nn3, _mask_xyz);
1005
1006 __m128 v1 = _mm_shuffle_ps(nn4,nn5,_MM_SHUFFLE(2,1,2,0));
1007 v1 = _mm_shuffle_ps(v1,v1,_MM_SHUFFLE(0,3,2,1));
1008
1009 __m128 v2 = _mm_shuffle_ps(nn4,nn5,_MM_SHUFFLE(0,0,1,1));
1010 v2 = _mm_shuffle_ps(v2,v2,_MM_SHUFFLE(2,0,2,0));
1011
1012
1013 nn5 = _mm_shuffle_ps(v,v1,_MM_SHUFFLE(1,0,3,0));
1014 nn5 = _mm_shuffle_ps(nn5,nn5,_MM_SHUFFLE(1,3,2,0));
1015
1016 mat4 m;
1017 m.row0 = nn5;
1018
1019 nn5 = _mm_shuffle_ps(v,v1,_MM_SHUFFLE(3,2,3,1));
1020 nn5 = _mm_shuffle_ps(nn5,nn5,_MM_SHUFFLE(1,3,0,2));
1021 m.row1 = nn5;
1022
1023 v2 = _mm_shuffle_ps(v2,v,_MM_SHUFFLE(3,2,1,0));
1024 m.row2 = v2;
1025
1026 m.row3 = _id_w;
1027 return m;
1028
1029
1030}
1031
1032//------------------------------------------------------------------------------
1035__forceinline mat4
1037{
1038 mat4 m = mat4::identity;
1039
1040 scalar sangle = Math::sin(angle);
1041 scalar cangle = Math::cos(angle);
1042
1043 m.m[1][1] = cangle;
1044 m.m[1][2] = sangle;
1045
1046 m.m[2][1] = -sangle;
1047 m.m[2][2] = cangle;
1048 return m;
1049}
1050
1051//------------------------------------------------------------------------------
1054__forceinline mat4
1056{
1057 mat4 m = mat4::identity;
1058
1059 scalar sangle = Math::sin(angle);
1060 scalar cangle = Math::cos(angle);
1061
1062 m.m[0][0] = cangle;
1063 m.m[0][2] = -sangle;
1064
1065 m.m[2][0] = sangle;
1066 m.m[2][2] = cangle;
1067 return m;
1068}
1069
1070//------------------------------------------------------------------------------
1073__forceinline mat4
1075{
1076 mat4 m = mat4::identity;
1077
1078 scalar sangle = Math::sin(angle);
1079 scalar cangle = Math::cos(angle);
1080
1081 m.m[0][0] = cangle;
1082 m.m[0][1] = sangle;
1083
1084 m.m[1][0] = -sangle;
1085 m.m[1][1] = cangle;
1086 return m;
1087}
1088
1089//------------------------------------------------------------------------------
1092__forceinline mat4
1094{
1095 quat q = quatyawpitchroll(yaw, pitch, roll);
1096 return rotationquat(q);
1097}
1098
1099//------------------------------------------------------------------------------
1102__forceinline mat4
1104{
1105 mat4 m = mat4::identity;
1106 m.r[0] = _mm_setr_ps(scale, 0.0f, 0.0f, 0.0f);
1107 m.r[1] = _mm_setr_ps(0.0f, scale, 0.0f, 0.0f);
1108 m.r[2] = _mm_setr_ps(0.0f, 0.0f, scale, 0.0f);
1109 m.r[3] = _mm_setr_ps(0.0f, 0.0f, 0.0f, 1.0f);
1110
1111 return m;
1112}
1113
1114//------------------------------------------------------------------------------
1117__forceinline mat4
1119{
1120 mat4 m = mat4::identity;
1121 m.r[0] = _mm_setr_ps(sx, 0.0f, 0.0f, 0.0f);
1122 m.r[1] = _mm_setr_ps(0.0f, sy, 0.0f, 0.0f);
1123 m.r[2] = _mm_setr_ps(0.0f, 0.0f, sz, 0.0f);
1124 m.r[3] = _mm_setr_ps(0.0f, 0.0f, 0.0f, 1.0f);
1125
1126 return m;
1127}
1128
1129//------------------------------------------------------------------------------
1132__forceinline mat4
1133scaling(const vec3& s)
1134{
1135 mat4 m = mat4::identity;
1136 m.r[0] = _mm_and_ps(s.vec, _mm_castsi128_ps(maskX));
1137 m.r[1] = _mm_and_ps(s.vec, _mm_castsi128_ps(maskY));
1138 m.r[2] = _mm_and_ps(s.vec, _mm_castsi128_ps(maskZ));
1139
1140 return m;
1141}
1142
1143//------------------------------------------------------------------------------
1146__forceinline mat4
1148{
1149 mat4 m = mat4::identity;
1150 m.r[3] = _mm_set_ps(1.0f,z,y,x);
1151 return m;
1152}
1153
1154//------------------------------------------------------------------------------
1157__forceinline mat4
1159{
1160 mat4 m = mat4::identity;
1161 m.r[3] = vec4(t.vec, 1.0f);
1162 return m;
1163}
1164
1165//------------------------------------------------------------------------------
1170__forceinline mat4
1171trs(const vec3& position, const quat& rotation, const vec3& scale)
1172{
1173 return Math::affine(scale, rotation, position);
1174}
1175
1176//------------------------------------------------------------------------------
1179__forceinline mat4
1181{
1182 __m128 tmp3, tmp2, tmp1, tmp0;
1183 tmp0 = _mm_unpacklo_ps(m.r[0].vec, m.r[1].vec);
1184 tmp2 = _mm_unpacklo_ps(m.r[2].vec, m.r[3].vec);
1185 tmp1 = _mm_unpackhi_ps(m.r[0].vec, m.r[1].vec);
1186 tmp3 = _mm_unpackhi_ps(m.r[2].vec, m.r[3].vec);
1187 mat4 ret;
1188 ret.r[0] = _mm_movelh_ps(tmp0, tmp2);
1189 ret.r[1] = _mm_movehl_ps(tmp2, tmp0);
1190 ret.r[2] = _mm_movelh_ps(tmp1, tmp3);
1191 ret.r[3] = _mm_movehl_ps(tmp3, tmp1);
1192 return ret;
1193}
1194
1195//------------------------------------------------------------------------------
1198__forceinline mat4
1200{
1201 return {
1202 0, -v.z, v.y, 0,
1203 v.z, 0, -v.x, 0,
1204 -v.y, v.x, 0, 0,
1205 0, 0, 0, 0,
1206 };
1207}
1208
1209} // namespace Math
1210//------------------------------------------------------------------------------
1211
#define n_assert(exp)
Definition debug.h:50
#define mm_ror_ps(vec, i)
Definition mat4.h:21
Different curves.
Definition angularpfeedbackloop.h:17
static const __m128 _id_z
Definition vec3.h:31
__forceinline vec3 cross(const vec3 &v0, const vec3 &v1)
Definition vec3.h:441
static const __m128 _id_x
Definition vec3.h:29
__forceinline mat4 rotationz(scalar angle)
Definition mat4.h:1074
__forceinline mat4 rotationyawpitchroll(scalar yaw, scalar pitch, scalar roll)
Definition mat4.h:1093
__forceinline mat4 ortholh(scalar w, scalar h, scalar zn, scalar zf)
Definition mat4.h:799
__forceinline vec3 splat_z(const vec3 &v)
Definition vec3.h:847
__forceinline scalar length3(const vec4 &v)
Definition vec4.h:397
__forceinline mat4 rotationy(scalar angle)
Definition mat4.h:1055
__forceinline vec3 splat_x(const vec3 &v)
Definition vec3.h:825
__forceinline mat4 perspoffcenterlh(scalar l, scalar r, scalar b, scalar t, scalar zn, scalar zf)
Definition mat4.h:942
__forceinline mat4 orthooffcenterlh(scalar l, scalar r, scalar t, scalar b, scalar zn, scalar zf)
Definition mat4.h:829
mat4 reflect(const vec4 &p)
based on this http://www.opengl.org/discussion_boards/showthread.php/169605-reflection-matrix-how-to-...
Definition mat4.cc:22
__forceinline mat4 persprh(scalar w, scalar h, scalar zn, scalar zf)
Definition mat4.h:926
__forceinline vec3 multiply(const vec3 &v0, const vec3 &v1)
Definition vec3.h:399
__forceinline scalar angle(const vec3 &v0, const vec3 &v1)
Definition vec3.h:532
__forceinline mat4 trs(const vec3 &position, const quat &rotation, const vec3 &scale)
A short hand for creating a TRS (translation, rotation, scale) matrix from pos, rot and scale.
Definition mat4.h:1171
__forceinline mat4 rotationaxis(const vec3 &axis, scalar angle)
Definition mat4.h:978
mat4 rotationquat(const quat &q)
TODO: rewrite using SSE.
Definition mat4.cc:178
__forceinline mat4 translation(scalar x, scalar y, scalar z)
Definition mat4.h:1147
__forceinline scalar length(const quat &q)
Definition quat.h:260
mat4 fromeuler(const vec3 &v)
Definition mat4.cc:237
__forceinline scalar dot(const plane &p, const vec4 &v1)
Definition plane.h:252
__forceinline vec3 permute(const vec3 &v0, const vec3 &v1, unsigned int i0, unsigned int i1, unsigned int i2)
Definition vec3.h:858
__forceinline mat4 orthorh(scalar w, scalar h, scalar zn, scalar zf)
Definition mat4.h:814
void decompose(const mat4 &mat, vec3 &outScale, quat &outRotation, vec3 &outTranslation)
Definition mat4.cc:50
__forceinline mat4 lookatrh(const point &eye, const point &at, const vector &up)
Definition mat4.h:580
static const __m128i maskZ
Definition mat4.h:32
__forceinline plane normalize(const plane &p)
Definition plane.h:261
__forceinline mat4 rotationx(scalar angle)
Definition mat4.h:1036
__forceinline mat4 persplh(scalar w, scalar h, scalar zn, scalar zf)
Definition mat4.h:910
__forceinline mat4 scaling(scalar scale)
Definition mat4.h:1103
__forceinline mat4 perspfovrh(scalar fovy, scalar aspect, scalar zn, scalar zf)
Definition mat4.h:886
static const __m128 _id_w
Definition vec3.h:32
__forceinline mat4 perspfovlh(scalar fovy, scalar aspect, scalar zn, scalar zf)
Definition mat4.h:863
__forceinline vec3 splat_y(const vec3 &v)
Definition vec3.h:836
__forceinline bool isidentity(const mat4 &m)
Definition mat4.h:401
__forceinline scalar determinant(const mat4 &m)
Definition mat4.h:413
mat4 skewsymmetric(const vec3 &v)
Definition mat4.h:1199
static const __m128i maskW
Definition mat4.h:33
float scalar
Definition scalar.h:45
mat4 transformation(const vec3 &scalingCenter, const quat &scalingRotation, const vec3 &scale, const vec3 &rotationCenter, const quat &rotation, const vec3 &trans)
Definition mat4.cc:199
__forceinline mat4 orthooffcenterrh(scalar l, scalar r, scalar t, scalar b, scalar zn, scalar zf)
Definition mat4.h:846
__forceinline mat4 lookatlh(const point &eye, const point &at, const vector &up)
Definition mat4.h:554
vec3 aseuler(const mat4 &m)
Definition mat4.cc:270
half operator*(half one, half two)
Definition half.h:123
quat quatyawpitchroll(scalar y, scalar x, scalar z)
Definition quat.cc:63
__forceinline scalar abs(scalar a)
Definition scalar.h:441
mat4 affine(const vec3 &scale, const vec3 &rotationCenter, const quat &rotation, const vec3 &translation)
Definition mat4.cc:117
__forceinline scalar cos(scalar x)
Definition scalar.h:191
bool ispointinside(const vec4 &p, const mat4 &m)
Definition mat4.cc:224
static const __m128 _mask_xyz
Definition vec3.h:37
__forceinline scalar sin(scalar x)
Definition scalar.h:182
static const __m128i maskY
Definition mat4.h:31
static const __m128 _id_y
Definition vec3.h:30
__forceinline mat4 transpose(const mat4 &m)
Definition mat4.h:1180
__forceinline mat4 perspoffcenterrh(scalar l, scalar r, scalar b, scalar t, scalar zn, scalar zf)
Definition mat4.h:960
__forceinline vec4 splat_w(const vec4 &v)
Definition vec4.h:1049
static const __m128i maskX
Definition mat4.h:30
mat4 affinetransformation(scalar scale, const vec3 &rotationCenter, const quat &rotation, const vec3 &translation)
Definition mat4.cc:166
__forceinline __m128 fmadd(__m128 a, __m128 b, __m128 c)
Fused multiply-add operation, (a * b) + c.
Definition sse.h:22
__forceinline mat4 inverse(const mat4 &m)
Definition mat4.h:458
Nebula's scalar datatype.
SSE support functions.
A 4x4 single point precision float matrix.
Definition mat4.h:49
vec4 y_axis
Definition mat4.h:121
float _44
Definition mat4.h:132
vec4 row3
Definition mat4.h:143
float _34
Definition mat4.h:131
vec4 position
Definition mat4.h:123
void translate(const vec3 &t)
add a translation to pos_component
Definition mat4.h:377
vec4 & operator[](size_t const i)
row element accessor
Definition mat4.h:220
float _32
Definition mat4.h:131
float _42
Definition mat4.h:132
float _24
Definition mat4.h:130
mat4(const mat4 &rhs)=default
copy constructor
vec4 get_w() const
Definition mat4.h:368
vec4 row1
Definition mat4.h:141
bool operator==(const mat4 &rhs) const
equality operator
Definition mat4.h:187
vec4 get_x() const
Definition mat4.h:341
void stream(scalar *ptr) const
stream content to 16-byte-aligned memory circumventing the write-cache
Definition mat4.h:291
vec4 z_axis
Definition mat4.h:122
float _21
Definition mat4.h:130
float _43
Definition mat4.h:132
float _33
Definition mat4.h:131
float _23
Definition mat4.h:130
void store3(scalar *ptr) const
write 3 columns to 16-byte aligned memory through the write cache
Definition mat4.h:268
vec4 row0
Definition mat4.h:140
void scale(const vec3 &v)
scale matrix
Definition mat4.h:386
void load(const scalar *ptr)
load content from 16-byte-aligned memory
Definition mat4.h:232
vec4 r[4]
as a two-dimensional array
Definition mat4.h:137
float _31
Definition mat4.h:131
vec4 x_axis
Definition mat4.h:120
vec4 row2
Definition mat4.h:142
float _41
Definition mat4.h:132
float _14
Definition mat4.h:129
vec4 get_y() const
Definition mat4.h:350
void store(scalar *ptr) const
write content to 16-byte-aligned memory through the write cache
Definition mat4.h:256
float m[4][4]
Definition mat4.h:134
void loadu(const scalar *ptr)
load content from unaligned memory
Definition mat4.h:244
void set(const vec4 &r0, const vec4 &r1, const vec4 &r2, const vec4 &r3)
set content from row vectors
Definition mat4.h:301
float _12
Definition mat4.h:129
float _11
Definition mat4.h:129
float _22
Definition mat4.h:130
bool operator!=(const mat4 &rhs) const
inequality operator
Definition mat4.h:199
vec4 get_z() const
Definition mat4.h:359
static const mat4 identity
Definition mat4.h:147
void translate(const float x, const float y, const float z)
add a translation to pos_component
void storeu(scalar *ptr) const
write content to unaligned memory through the write cache
Definition mat4.h:279
float _13
Definition mat4.h:129
void scale(const float x, const float y, const float z)
scale matrix
void get_scale(vec4 &scale) const
extracts scale components to target vector
Definition mat4.h:325
mat4()
default constructor. returns identity matrix
Definition mat4.h:154
__m128 vec
Definition plane.h:46
Represents a 3D point in space.
Definition point.h:22
__m128 vec
Definition point.h:75
A quaternion is usually used to represent an orientation in 3D space.
Definition quat.h:30
A 3D vector.
Definition vec3.h:40
float x
Definition vec3.h:96
float z
Definition vec3.h:96
__m128 vec
Definition vec3.h:98
float y
Definition vec3.h:96
A 4D vector.
Definition vec4.h:24
__m128 vec
Definition vec4.h:97
float x
Definition vec4.h:95
A vector is a 3D direction in space.
Definition vector.h:22
__m128 vec
Definition vector.h:82
bool operator==(const TiXmlString &a, const TiXmlString &b)
Definition tinystr.h:272
bool operator!=(const TiXmlString &a, const TiXmlString &b)
Definition tinystr.h:282
#define NEBULA_ALIGN16
Definition types.h:146