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
459{
460 __m128 tmp3, tmp2, tmp1, tmp0;
461 tmp0 = _mm_unpacklo_ps(m.r[0].vec, m.r[1].vec);
462 tmp2 = _mm_unpacklo_ps(m.r[2].vec, m.r[3].vec);
463 tmp1 = _mm_unpackhi_ps(m.r[0].vec, m.r[1].vec);
464 tmp3 = _mm_unpackhi_ps(m.r[2].vec, m.r[3].vec);
465 mat4 ret;
466 ret.r[0] = _mm_movelh_ps(tmp0, tmp2);
467 ret.r[1] = _mm_movehl_ps(tmp2, tmp0);
468 ret.r[2] = _mm_movelh_ps(tmp1, tmp3);
469 ret.r[3] = _mm_movehl_ps(tmp3, tmp1);
470 return ret;
471}
472
473//------------------------------------------------------------------------------
476__forceinline mat4
477inverse(const mat4& m)
478{
479 __m128 Va,Vb,Vc;
480 __m128 r1,r2,r3,tt,tt2;
481 __m128 sum,Det,RDet;
482 __m128 trns0,trns1,trns2,trns3;
483
484 const __m128i pnpn = _mm_setr_epi32(0x00000000, static_cast<int>(0x80000000), 0x00000000, static_cast<int>(0x80000000));
485 const __m128i npnp = _mm_setr_epi32(static_cast<int>(0x80000000), 0x00000000, static_cast<int>(0x80000000), 0x00000000);
486 const __m128 zeroone = _mm_setr_ps(1.0f, 0.0f, 0.0f, 1.0f);
487
488 __m128 _L1 = m.r[0].vec;
489 __m128 _L2 = m.r[1].vec;
490 __m128 _L3 = m.r[2].vec;
491 __m128 _L4 = m.r[3].vec;
492 // Calculating the minterms for the first line.
493
494 // _mm_ror_ps is just a macro using _mm_shuffle_ps().
495 tt = _L4; tt2 = mm_ror_ps(_L3,1);
496 Vc = _mm_mul_ps(tt2, mm_ror_ps(tt,0)); // V3'dot V4
497 Va = _mm_mul_ps(tt2, mm_ror_ps(tt,2)); // V3'dot V4"
498 Vb = _mm_mul_ps(tt2, mm_ror_ps(tt,3)); // V3' dot V4^
499
500 r1 = _mm_sub_ps(mm_ror_ps(Va,1), mm_ror_ps(Vc,2)); // V3" dot V4^ - V3^ dot V4"
501 r2 = _mm_sub_ps(mm_ror_ps(Vb,2), mm_ror_ps(Vb,0)); // V3^ dot V4' - V3' dot V4^
502 r3 = _mm_sub_ps(mm_ror_ps(Va,0), mm_ror_ps(Vc,1)); // V3' dot V4" - V3" dot V4'
503
504 tt = _L2;
505 Va = mm_ror_ps(tt,1); sum = _mm_mul_ps(Va,r1);
506 Vb = mm_ror_ps(tt,2); sum = _mm_add_ps(sum,_mm_mul_ps(Vb,r2));
507 Vc = mm_ror_ps(tt,3); sum = _mm_add_ps(sum,_mm_mul_ps(Vc,r3));
508
509 // Calculating the determinant.
510 Det = _mm_mul_ps(sum,_L1);
511 Det = _mm_add_ps(Det,_mm_movehl_ps(Det,Det));
512
513
514 __m128 mtL1 = _mm_xor_ps(sum, _mm_castsi128_ps(pnpn));
515
516 // Calculating the minterms of the second line (using previous results).
517 tt = mm_ror_ps(_L1,1); sum = _mm_mul_ps(tt,r1);
518 tt = mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r2));
519 tt = mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r3));
520 __m128 mtL2 = _mm_xor_ps(sum, _mm_castsi128_ps(npnp));
521
522 // Testing the determinant.
523 Det = _mm_sub_ss(Det,_mm_shuffle_ps(Det,Det,1));
524
525 // Calculating the minterms of the third line.
526 tt = mm_ror_ps(_L1,1);
527 Va = _mm_mul_ps(tt,Vb); // V1' dot V2"
528 Vb = _mm_mul_ps(tt,Vc); // V1' dot V2^
529 Vc = _mm_mul_ps(tt,_L2); // V1' dot V2
530
531 r1 = _mm_sub_ps(mm_ror_ps(Va,1), mm_ror_ps(Vc,2)); // V1" dot V2^ - V1^ dot V2"
532 r2 = _mm_sub_ps(mm_ror_ps(Vb,2), mm_ror_ps(Vb,0)); // V1^ dot V2' - V1' dot V2^
533 r3 = _mm_sub_ps(mm_ror_ps(Va,0), mm_ror_ps(Vc,1)); // V1' dot V2" - V1" dot V2'
534
535 tt = mm_ror_ps(_L4,1); sum = _mm_mul_ps(tt,r1);
536 tt = mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r2));
537 tt = mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r3));
538 __m128 mtL3 = _mm_xor_ps(sum, _mm_castsi128_ps(pnpn));
539
540 // Dividing is FASTER than rcp_nr! (Because rcp_nr causes many register-memory RWs).
541 RDet = _mm_div_ss(zeroone, Det); // TODO: just 1.0f?
542 RDet = _mm_shuffle_ps(RDet,RDet,0x00);
543
544 // Devide the first 12 minterms with the determinant.
545 mtL1 = _mm_mul_ps(mtL1, RDet);
546 mtL2 = _mm_mul_ps(mtL2, RDet);
547 mtL3 = _mm_mul_ps(mtL3, RDet);
548
549 // Calculate the minterms of the forth line and devide by the determinant.
550 tt = mm_ror_ps(_L3,1); sum = _mm_mul_ps(tt,r1);
551 tt = mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r2));
552 tt = mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r3));
553 __m128 mtL4 = _mm_xor_ps(sum, _mm_castsi128_ps(npnp));
554 mtL4 = _mm_mul_ps(mtL4, RDet);
555
556 // Now we just have to transpose the minterms matrix.
557 trns0 = _mm_unpacklo_ps(mtL1,mtL2);
558 trns1 = _mm_unpacklo_ps(mtL3,mtL4);
559 trns2 = _mm_unpackhi_ps(mtL1,mtL2);
560 trns3 = _mm_unpackhi_ps(mtL3,mtL4);
561 _L1 = _mm_movelh_ps(trns0,trns1);
562 _L2 = _mm_movehl_ps(trns1,trns0);
563 _L3 = _mm_movelh_ps(trns2,trns3);
564 _L4 = _mm_movehl_ps(trns3,trns2);
565
566 return mat4(vec4(_L1), vec4(_L2), vec4(_L3), vec4(_L4));
567}
568
569//------------------------------------------------------------------------------
572__forceinline mat4
573lookatlh(const point& eye, const point& at, const vector& up)
574{
575#if NEBULA_DEBUG
576 n_assert(length(up) > 0);
577#endif
578 // hmm the XM lookat functions are kinda pointless, because they
579 // return a VIEW matrix, which is already inverse (so one would
580 // need to reverse again!)
581 const vector zaxis = normalize(at - eye);
582 vector normUp = normalize(up);
583 if (Math::abs(dot(zaxis, normUp)) > 0.9999999f)
584 {
585 // need to choose a different up vector because up and lookat point
586 // into same or opposite direction
587 // just rotate y->x, x->z and z->y
588 normUp = permute(normUp, normUp, 1, 2, 0);
589 }
590 const vector xaxis = normalize(cross(normUp, zaxis));
591 const vector yaxis = normalize(cross(zaxis, xaxis));
592 mat4 ret;
593 ret.row0 = xaxis;
594 ret.row0.w = -dot(xaxis, eye);
595 ret.row1 = yaxis;
596 ret.row1.w = -dot(yaxis, eye);
597 ret.row2 = zaxis;
598 ret.row2.w = -dot(zaxis, eye);
599 ret.row3 = vec4(0, 0, 0, 1);
600 return transpose(ret);
601}
602
603//------------------------------------------------------------------------------
606__forceinline mat4
607lookatrh(const point& eye, const point& at, const vector& up)
608{
609#if NEBULA_DEBUG
610 n_assert(length(up) > 0);
611#endif
612 // hmm the XM lookat functions are kinda pointless, because they
613 // return a VIEW matrix, which is already inverse (so one would
614 // need to reverse again!)
615 const vector zaxis = normalize(eye - at);
616 vector normUp = normalize(up);
617 if (Math::abs(dot(zaxis, normUp)) > 0.9999999f)
618 {
619 // need to choose a different up vector because up and lookat point
620 // into same or opposite direction
621 // just rotate y->x, x->z and z->y
622 normUp = permute(normUp, normUp, 1, 2, 0);
623 }
624 const vector xaxis = normalize(cross(normUp, zaxis));
625 const vector yaxis = normalize(cross(zaxis, xaxis));
626
627 mat4 ret;
628 ret.row0 = xaxis;
629 ret.row0.w = -dot(xaxis, eye);
630 ret.row1 = yaxis;
631 ret.row1.w = -dot(yaxis, eye);
632 ret.row2 = zaxis;
633 ret.row2.w = -dot(zaxis, eye);
634 ret.row3 = vec4(0, 0, 0, 1);
635 return transpose(ret);
636}
637
638#ifdef N_USE_AVX
639// dual linear combination using AVX instructions on YMM regs
640static inline __m256 twolincomb_AVX_8(__m256 A01, const mat4 &B)
641{
642 __m256 result;
643 result = _mm256_mul_ps(_mm256_shuffle_ps(A01, A01, 0x00), _mm256_broadcast_ps(&B.r[0].vec));
644 result = _mm256_add_ps(result, _mm256_mul_ps(_mm256_shuffle_ps(A01, A01, 0x55), _mm256_broadcast_ps(&B.r[1].vec)));
645 result = _mm256_add_ps(result, _mm256_mul_ps(_mm256_shuffle_ps(A01, A01, 0xaa), _mm256_broadcast_ps(&B.r[2].vec)));
646 result = _mm256_add_ps(result, _mm256_mul_ps(_mm256_shuffle_ps(A01, A01, 0xff), _mm256_broadcast_ps(&B.r[3].vec)));
647 return result;
648}
649
650//------------------------------------------------------------------------------
653__forceinline mat4
654operator*(const mat4& m0, const mat4& m1)
655{
656 mat4 out;
657
658 _mm256_zeroupper();
659 __m256 A01 = _mm256_loadu_ps(&m1.m[0][0]);
660 __m256 A23 = _mm256_loadu_ps(&m1.m[2][0]);
661
662 __m256 out01x = twolincomb_AVX_8(A01, m0);
663 __m256 out23x = twolincomb_AVX_8(A23, m0);
664
665 _mm256_storeu_ps(&out.m[0][0], out01x);
666 _mm256_storeu_ps(&out.m[2][0], out23x);
667 return out;
668}
669
670__forceinline mat4 operator%(const mat4& m1, const mat4& m0) = delete;
671
672#else
673//------------------------------------------------------------------------------
676__forceinline mat4
677operator*(const mat4& m0, const mat4& m1)
678{
679 mat4 ret;
680
681 vec4 mw = m1.r[0];
682
683 // Splat the all components of the first row
684 vec4 mx = splat_x(mw);
685 vec4 my = splat_y(mw);
686 vec4 mz = splat_z(mw);
687 mw = splat_w(mw);
688
689 vec4 m1x = m0.r[0];
690 vec4 m1y = m0.r[1];
691 vec4 m1z = m0.r[2];
692 vec4 m1w = m0.r[3];
693
694 //multiply first row
695 mx = multiply(mx, m1x);
696 my = multiply(my, m1y);
697 mz = multiply(mz, m1z);
698 mw = multiply(mw, m1w);
699
700 mx = mx + my;
701 mz = mz + mw;
702 ret.r[0] = mx + mz;
703
704 // rinse and repeat
705 mw = m1.row1;
706
707 mx = splat_x(mw);
708 my = splat_y(mw);
709 mz = splat_z(mw);
710 mw = splat_w(mw);
711
712 mx = multiply(mx, m1x);
713 my = multiply(my, m1y);
714 mz = multiply(mz, m1z);
715 mw = multiply(mw, m1w);
716
717 mx = mx + my;
718 mz = mz + mw;
719 ret.r[1] = mx + mz;
720
721 mw = m1.row2;
722
723 mx = splat_x(mw);
724 my = splat_y(mw);
725 mz = splat_z(mw);
726 mw = splat_w(mw);
727
728 mx = multiply(mx, m0.r[0]);
729 my = multiply(my, m0.r[1]);
730 mz = multiply(mz, m0.r[2]);
731 mw = multiply(mw, m0.r[3]);
732
733 mx = mx + my;
734 mz = mz + mw;
735 ret.r[2] = mx + mz;
736
737 mw = m1.row3;
738
739 mx = splat_x(mw);
740 my = splat_y(mw);
741 mz = splat_z(mw);
742 mw = splat_w(mw);
743
744 mx = multiply(mx, m1x);
745 my = multiply(my, m1y);
746 mz = multiply(mz, m1z);
747 mw = multiply(mw, m1w);
748
749 mx = mx + my;
750 mz = mz + mw;
751 ret.r[3] = mx + mz;
752
753 return ret;
754}
755#endif
756
757//------------------------------------------------------------------------------
760__forceinline vec4
761operator*(const mat4& m, const vec4& v)
762{
763 __m128 x = _mm_shuffle_ps(v.vec, v.vec, _MM_SHUFFLE(0, 0, 0, 0));
764 __m128 y = _mm_shuffle_ps(v.vec, v.vec, _MM_SHUFFLE(1, 1, 1, 1));
765 __m128 z = _mm_shuffle_ps(v.vec, v.vec, _MM_SHUFFLE(2, 2, 2, 2));
766 __m128 w = _mm_shuffle_ps(v.vec, v.vec, _MM_SHUFFLE(3, 3, 3, 3));
767
768 return
769 fmadd(x, m.r[0].vec,
770 fmadd(y, m.r[1].vec,
771 fmadd(z, m.r[2].vec,
772 _mm_mul_ps(w, m.r[3].vec))));
773}
774
775//------------------------------------------------------------------------------
778__forceinline vec4
779operator*(const mat4& m, const vec3& v)
780{
781 __m128 x = _mm_shuffle_ps(v.vec, v.vec, _MM_SHUFFLE(0, 0, 0, 0));
782 x = _mm_and_ps(x, _mask_xyz);
783 __m128 y = _mm_shuffle_ps(v.vec, v.vec, _MM_SHUFFLE(1, 1, 1, 1));
784 y = _mm_and_ps(y, _mask_xyz);
785 __m128 z = _mm_shuffle_ps(v.vec, v.vec, _MM_SHUFFLE(2, 2, 2, 2));
786 z = _mm_and_ps(z, _mask_xyz);
787
788 return
789 fmadd(x, m.r[0].vec,
790 fmadd(y, m.r[1].vec,
791 _mm_mul_ps(z, m.r[2].vec)));
792}
793
794//------------------------------------------------------------------------------
797__forceinline vec4
798operator*(const mat4& m, const point& p)
799{
800 __m128 x = _mm_shuffle_ps(p.vec, p.vec, _MM_SHUFFLE(0, 0, 0, 0));
801 __m128 y = _mm_shuffle_ps(p.vec, p.vec, _MM_SHUFFLE(1, 1, 1, 1));
802 __m128 z = _mm_shuffle_ps(p.vec, p.vec, _MM_SHUFFLE(2, 2, 2, 2));
803 __m128 w = _mm_shuffle_ps(p.vec, p.vec, _MM_SHUFFLE(3, 3, 3, 3));
804
805 return
806 fmadd(x, m.r[0].vec,
807 fmadd(y, m.r[1].vec,
808 fmadd(z, m.r[2].vec,
809 _mm_mul_ps(w, m.r[3].vec))));
810}
811
812//------------------------------------------------------------------------------
815__forceinline vector
816operator*(const mat4& m, const vector& v)
817{
818 __m128 x = _mm_shuffle_ps(v.vec, v.vec, _MM_SHUFFLE(0, 0, 0, 0));
819 x = _mm_and_ps(x, _mask_xyz);
820 __m128 y = _mm_shuffle_ps(v.vec, v.vec, _MM_SHUFFLE(1, 1, 1, 1));
821 y = _mm_and_ps(y, _mask_xyz);
822 __m128 z = _mm_shuffle_ps(v.vec, v.vec, _MM_SHUFFLE(2, 2, 2, 2));
823 z = _mm_and_ps(z, _mask_xyz);
824
825 return
826 fmadd(x, m.r[0].vec,
827 fmadd(y, m.r[1].vec,
828 _mm_mul_ps(z, m.r[2].vec)));
829}
830
831//------------------------------------------------------------------------------
834__forceinline mat4
836{
838 scalar dist = 1.0f / (zf - zn);
839 m.r[0] = vec4(2.0f / w, 0.0f, 0.0f, 0.0f);
840 m.r[1] = vec4(0.0f, 2.0f / h, 0.0f, 0.0f);
841 m.r[2] = vec4(0.0f, 0.0f, dist, 0.0f);
842 m.r[3] = vec4(0.0f, 0.0, -zn * dist, 1.0f);
843 return m;
844}
845
846//------------------------------------------------------------------------------
849__forceinline mat4
851{
853 scalar dist = 1.0f / (zn - zf);
854 m.r[0] = vec4(2.0f / w, 0.0f, 0.0f, 0.0f);
855 m.r[1] = vec4(0.0f, 2.0f / h, 0.0f, 0.0f);
856 m.r[2] = vec4(0.0f, 0.0f, dist, 0.0f);
857 m.r[3] = vec4(0.0f, 0.0, zn * dist, 1.0f);
858 return m;
859}
860
861//------------------------------------------------------------------------------
864__forceinline mat4
866{
868 m.r[0] = vec4(2.0f / (r-l), 0.0f, 0.0f, 0.0f);
869 m.r[1] = vec4(0.0f, 2.0f / (t-b), 0.0f, 0.0f);
870 m.r[2] = vec4(0.0f, 0.0f, 1.0f / (zf-zn), 0.0f);
871 m.r[3] = vec4((l + r) / (l - r), (t + b) / (b - t), zn / (zn - zf), 1.0f);
872 return m;
873}
874
875//------------------------------------------------------------------------------
878__forceinline mat4
880{
882 m.r[0] = vec4(2.0f / (r-l), 0.0f, 0.0f, 0.0f);
883 m.r[1] = vec4(0.0f, 2.0f / (t-b), 0.0f, 0.0f);
884 m.r[2] = vec4(0.0f, 0.0f, 1 / (zn-zf), 0.0f);
885 m.r[3] = vec4((l + r) / (l - r), (t + b) / (b - t), zn / (zn-zf), 1.0f);
886 return m;
887}
888
889//------------------------------------------------------------------------------
892__forceinline mat4
893perspfovlh(scalar fovy, scalar aspect, scalar zn, scalar zf)
894{
896 scalar halfFov = 0.5f * fovy;
897 scalar sinfov = Math::sin(halfFov);
898 scalar cosfov = Math::cos(halfFov);
899
900 scalar height = cosfov / sinfov;
901 scalar width = height / aspect;
902
903 scalar dist = zf / (zf - zn);
904 m.r[0] = vec4(width, 0.0f, 0.0f, 0.0f);
905 m.r[1] = vec4(0.0f, height, 0.0f, 0.0f);
906 m.r[2] = vec4(0.0f, 0.0f, dist, 1.0f);
907 m.r[3] = vec4(0.0f, 0.0f, -dist * zn, 0.0f);
908
909 return m;
910}
911
912//------------------------------------------------------------------------------
915__forceinline mat4
916perspfovrh(scalar fovy, scalar aspect, scalar zn, scalar zf)
917{
919 scalar halfFov = 0.5f * fovy;
920 scalar sinfov = Math::sin(halfFov);
921 scalar cosfov = Math::cos(halfFov);
922
923 scalar height = cosfov / sinfov;
924 scalar width = height / aspect;
925
926 scalar dist = zf / (zn - zf);
927
928 m.r[0] = vec4(width, 0.0f, 0.0f, 0.0f);
929 m.r[1] = vec4(0.0f, height, 0.0f, 0.0f);
930 m.r[2] = vec4(0.0f, 0.0f, dist, -1.0f);
931 m.r[3] = vec4(0.0f, 0.0f, dist * zn, 0.0f);
932
933 return m;
934}
935
936//------------------------------------------------------------------------------
939__forceinline mat4
941{
943 scalar dist = zf / (zf - zn);
944
945 m.r[0] = vec4(2.0f * zn / w, 0.0f, 0.0f, 0.0f);
946 m.r[1] = vec4(0.0f, 2.0f * zn / h, 0.0f, 0.0f);
947 m.r[2] = vec4(0.0f, 0.0f, dist, 1.0f);
948 m.r[3] = vec4(0.0f, 0.0, -dist * zn, 0.0f);
949 return m;
950}
951
952//------------------------------------------------------------------------------
955__forceinline mat4
957{
959 scalar dist = zf / (zn - zf);
960
961 m.r[0] = vec4(2.0f * zn / w, 0.0f, 0.0f, 0.0f);
962 m.r[1] = vec4(0.0f, 2.0f * zn / h, 0.0f, 0.0f);
963 m.r[2] = vec4(0.0f, 0.0f, dist, -1.0f);
964 m.r[3] = vec4(0.0f, 0.0, dist * zn, 0.0f);
965 return m;
966}
967
968//------------------------------------------------------------------------------
971__forceinline mat4
973{
975 scalar divwidth = 1.0f / (r - l);
976 scalar divheight = 1.0f / (t - b);
977 scalar dist = zf / (zf - zn);
978
979 m.r[0] = vec4(2.0f * zn * divwidth, 0.0f, 0.0f, 0.0f);
980 m.r[1] = vec4(0.0f, 2.0f * zn * divheight, 0.0f, 0.0f);
981 m.r[2] = vec4(-(l + r) * divwidth, -(b + t) * divheight, dist, 1.0f);
982 m.r[3] = vec4(0.0f, 0.0f, -dist * zn, 0.0f);
983 return m;
984}
985
986//------------------------------------------------------------------------------
989__forceinline mat4
991{
993 scalar divwidth = 1.0f / (r - l);
994 scalar divheight = 1.0f / (t - b);
995 scalar dist = zf / (zn - zf);
996
997 m.r[0] = vec4(2.0f * zn * divwidth, 0.0f, 0.0f, 0.0f);
998 m.r[1] = vec4(0.0f, 2.0f * zn * divheight, 0.0f, 0.0f);
999 m.r[2] = vec4((l + r) * divwidth, (b + t) * divheight, dist, -1.0f);
1000 m.r[3] = vec4(0.0f, 0.0f, dist * zn, 0.0f);
1001 return m;
1002}
1003
1004//------------------------------------------------------------------------------
1007__forceinline mat4
1009{
1010 __m128 norm = normalize(axis).vec;
1011
1012 scalar sangle = Math::sin(angle);
1013 scalar cangle = Math::cos(angle);
1014
1015 __m128 m1_c = _mm_set_ps1(1.0f - cangle);
1016 __m128 c = _mm_set_ps1(cangle);
1017 __m128 s = _mm_set_ps1(sangle);
1018
1019 __m128 nn1 = _mm_shuffle_ps(norm,norm,_MM_SHUFFLE(3,0,2,1));
1020 __m128 nn2 = _mm_shuffle_ps(norm,norm,_MM_SHUFFLE(3,1,0,2));
1021
1022 __m128 v = _mm_mul_ps(nn1,m1_c);
1023 v = _mm_mul_ps(nn2,v);
1024
1025 __m128 nn3 = _mm_mul_ps(norm, m1_c);
1026 nn3 = _mm_mul_ps(norm, nn3);
1027 nn3 = _mm_add_ps(nn3, c);
1028
1029 __m128 nn4 = _mm_mul_ps(norm,s);
1030 nn4 = _mm_add_ps(nn4, v);
1031 __m128 nn5 = _mm_mul_ps(s, norm);
1032 nn5 = _mm_sub_ps(v,nn5);
1033
1034 v = _mm_and_ps(nn3, _mask_xyz);
1035
1036 __m128 v1 = _mm_shuffle_ps(nn4,nn5,_MM_SHUFFLE(2,1,2,0));
1037 v1 = _mm_shuffle_ps(v1,v1,_MM_SHUFFLE(0,3,2,1));
1038
1039 __m128 v2 = _mm_shuffle_ps(nn4,nn5,_MM_SHUFFLE(0,0,1,1));
1040 v2 = _mm_shuffle_ps(v2,v2,_MM_SHUFFLE(2,0,2,0));
1041
1042
1043 nn5 = _mm_shuffle_ps(v,v1,_MM_SHUFFLE(1,0,3,0));
1044 nn5 = _mm_shuffle_ps(nn5,nn5,_MM_SHUFFLE(1,3,2,0));
1045
1046 mat4 m;
1047 m.row0 = nn5;
1048
1049 nn5 = _mm_shuffle_ps(v,v1,_MM_SHUFFLE(3,2,3,1));
1050 nn5 = _mm_shuffle_ps(nn5,nn5,_MM_SHUFFLE(1,3,0,2));
1051 m.row1 = nn5;
1052
1053 v2 = _mm_shuffle_ps(v2,v,_MM_SHUFFLE(3,2,1,0));
1054 m.row2 = v2;
1055
1056 m.row3 = _id_w;
1057 return m;
1058
1059
1060}
1061
1062//------------------------------------------------------------------------------
1065__forceinline mat4
1067{
1068 mat4 m = mat4::identity;
1069
1070 scalar sangle = Math::sin(angle);
1071 scalar cangle = Math::cos(angle);
1072
1073 m.m[1][1] = cangle;
1074 m.m[1][2] = sangle;
1075
1076 m.m[2][1] = -sangle;
1077 m.m[2][2] = cangle;
1078 return m;
1079}
1080
1081//------------------------------------------------------------------------------
1084__forceinline mat4
1086{
1087 mat4 m = mat4::identity;
1088
1089 scalar sangle = Math::sin(angle);
1090 scalar cangle = Math::cos(angle);
1091
1092 m.m[0][0] = cangle;
1093 m.m[0][2] = -sangle;
1094
1095 m.m[2][0] = sangle;
1096 m.m[2][2] = cangle;
1097 return m;
1098}
1099
1100//------------------------------------------------------------------------------
1103__forceinline mat4
1105{
1106 mat4 m = mat4::identity;
1107
1108 scalar sangle = Math::sin(angle);
1109 scalar cangle = Math::cos(angle);
1110
1111 m.m[0][0] = cangle;
1112 m.m[0][1] = sangle;
1113
1114 m.m[1][0] = -sangle;
1115 m.m[1][1] = cangle;
1116 return m;
1117}
1118
1119//------------------------------------------------------------------------------
1122__forceinline mat4
1124{
1125 quat q = quatyawpitchroll(yaw, pitch, roll);
1126 return rotationquat(q);
1127}
1128
1129//------------------------------------------------------------------------------
1132__forceinline mat4
1134{
1135 mat4 m = mat4::identity;
1136 m.r[0] = _mm_setr_ps(scale, 0.0f, 0.0f, 0.0f);
1137 m.r[1] = _mm_setr_ps(0.0f, scale, 0.0f, 0.0f);
1138 m.r[2] = _mm_setr_ps(0.0f, 0.0f, scale, 0.0f);
1139 m.r[3] = _mm_setr_ps(0.0f, 0.0f, 0.0f, 1.0f);
1140
1141 return m;
1142}
1143
1144//------------------------------------------------------------------------------
1147__forceinline mat4
1149{
1150 mat4 m = mat4::identity;
1151 m.r[0] = _mm_setr_ps(sx, 0.0f, 0.0f, 0.0f);
1152 m.r[1] = _mm_setr_ps(0.0f, sy, 0.0f, 0.0f);
1153 m.r[2] = _mm_setr_ps(0.0f, 0.0f, sz, 0.0f);
1154 m.r[3] = _mm_setr_ps(0.0f, 0.0f, 0.0f, 1.0f);
1155
1156 return m;
1157}
1158
1159//------------------------------------------------------------------------------
1162__forceinline mat4
1163scaling(const vec3& s)
1164{
1165 mat4 m = mat4::identity;
1166 m.r[0] = _mm_and_ps(s.vec, _mm_castsi128_ps(maskX));
1167 m.r[1] = _mm_and_ps(s.vec, _mm_castsi128_ps(maskY));
1168 m.r[2] = _mm_and_ps(s.vec, _mm_castsi128_ps(maskZ));
1169
1170 return m;
1171}
1172
1173//------------------------------------------------------------------------------
1176__forceinline mat4
1178{
1179 mat4 m = mat4::identity;
1180 m.r[3] = _mm_set_ps(1.0f,z,y,x);
1181 return m;
1182}
1183
1184//------------------------------------------------------------------------------
1187__forceinline mat4
1189{
1190 mat4 m = mat4::identity;
1191 m.r[3] = vec4(t.vec, 1.0f);
1192 return m;
1193}
1194
1195//------------------------------------------------------------------------------
1200__forceinline mat4
1201trs(const vec3& position, const quat& rotation, const vec3& scale)
1202{
1203 return Math::affine(scale, rotation, position);
1204}
1205
1206//------------------------------------------------------------------------------
1209__forceinline mat4
1211{
1212 return {
1213 0, -v.z, v.y, 0,
1214 v.z, 0, -v.x, 0,
1215 -v.y, v.x, 0, 0,
1216 0, 0, 0, 0,
1217 };
1218}
1219
1220//------------------------------------------------------------------------------
1223__forceinline mat4
1225{
1226#if PROJECTION_HANDEDNESS_LH
1227 return lookatlh(eye, at, up);
1228#else
1229 return lookatrh(eye, at, up);
1230#endif
1231}
1232
1233
1234//------------------------------------------------------------------------------
1237__forceinline mat4
1238lookto(point eye, vector direction, vector up)
1239{
1240#if PROJECTION_HANDEDNESS_LH
1241 return lookatlh(eye, eye + direction, up);
1242#else
1243 return lookatrh(eye, eye + direction, up);
1244#endif
1245}
1246
1247
1248//------------------------------------------------------------------------------
1251__forceinline mat4
1252perspfov(scalar fovy, scalar aspect, scalar zn, scalar zf)
1253{
1254#if PROJECTION_HANDEDNESS_LH
1255 return perspfovlh(fovy, aspect, zn, zf);
1256#else
1257 return perspfovrh(fovy, aspect, zn, zf);
1258#endif
1259}
1260
1261//------------------------------------------------------------------------------
1264__forceinline mat4
1266{
1267#if PROJECTION_HANDEDNESS_LH
1268 return persplh(w, h, zn, zf);
1269#else
1270 return persprh(w, h, zn, zf);
1271#endif
1272}
1273
1274//------------------------------------------------------------------------------
1277__forceinline mat4
1279{
1280#if PROJECTION_HANDEDNESS_LH
1281 return perspoffcenterlh(l, r, b, t, zn, zf);
1282#else
1283 return perspoffcenterrh(l, r, b, t, zn, zf);
1284#endif
1285}
1286
1287//------------------------------------------------------------------------------
1290__forceinline mat4
1292{
1293#if PROJECTION_HANDEDNESS_LH
1294 return ortholh(w, h, zn, zf);
1295#else
1296 return orthorh(w, h, zn, zf);
1297#endif
1298}
1299
1300//------------------------------------------------------------------------------
1303__forceinline mat4
1305{
1306#if PROJECTION_HANDEDNESS_LH
1307 return orthooffcenterlh(l, r, b, t, zn, zf);
1308#else
1309 return orthooffcenterrh(l, r, b, t, zn, zf);
1310#endif
1311}
1312
1313} // namespace Math
1314//------------------------------------------------------------------------------
#define n_assert(exp)
Definition debug.h:50
#define mm_ror_ps(vec, i)
Definition mat4.h:21
Different curves.
Definition angularpfeedbackloop.h:17
__forceinline vec3 cross(const vec3 &v0, const vec3 &v1)
Definition vec3.h:423
static const f32x4 _id_w
Definition vec3.h:29
__forceinline mat4 rotationz(scalar angle)
Definition mat4.h:1104
__forceinline mat4 rotationyawpitchroll(scalar yaw, scalar pitch, scalar roll)
Definition mat4.h:1123
__forceinline mat4 ortholh(scalar w, scalar h, scalar zn, scalar zf)
Definition mat4.h:835
__forceinline vec3 splat_z(const vec3 &v)
Definition vec3.h:824
__forceinline scalar length3(const vec4 &v)
Definition vec4.h:397
__forceinline mat4 rotationy(scalar angle)
Definition mat4.h:1085
__forceinline vec3 splat_x(const vec3 &v)
Definition vec3.h:804
__forceinline mat4 perspoffcenterlh(scalar l, scalar r, scalar b, scalar t, scalar zn, scalar zf)
Definition mat4.h:972
__forceinline mat4 orthooffcenterlh(scalar l, scalar r, scalar t, scalar b, scalar zn, scalar zf)
Definition mat4.h:865
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:956
__forceinline vec3 multiply(const vec3 &v0, const vec3 &v1)
Definition vec3.h:387
__forceinline scalar angle(const vec3 &v0, const vec3 &v1)
Definition vec3.h:514
__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:1201
__forceinline mat4 rotationaxis(const vec3 &axis, scalar angle)
Definition mat4.h:1008
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:1177
__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 mat4 orthooffcenter(scalar l, scalar r, scalar b, scalar t, scalar zn, scalar zf)
Definition mat4.h:1304
__forceinline vec3 permute(const vec3 &v0, const vec3 &v1, unsigned int i0, unsigned int i1, unsigned int i2)
Definition vec3.h:834
__forceinline mat4 orthorh(scalar w, scalar h, scalar zn, scalar zf)
Definition mat4.h:850
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:607
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:1066
__forceinline mat4 persplh(scalar w, scalar h, scalar zn, scalar zf)
Definition mat4.h:940
__forceinline mat4 scaling(scalar scale)
Definition mat4.h:1133
static const f32x4 _id_y
Definition vec3.h:27
__forceinline mat4 perspfov(scalar fovy, scalar aspect, scalar zn, scalar zf)
Definition mat4.h:1252
__forceinline mat4 ortho(scalar w, scalar h, scalar zn, scalar zf)
Definition mat4.h:1291
static const f32x4 _id_z
Definition vec3.h:28
__forceinline mat4 perspfovrh(scalar fovy, scalar aspect, scalar zn, scalar zf)
Definition mat4.h:916
__forceinline mat4 perspfovlh(scalar fovy, scalar aspect, scalar zn, scalar zf)
Definition mat4.h:893
__forceinline mat4 lookat(point eye, point at, vector up)
Definition mat4.h:1224
__forceinline vec3 splat_y(const vec3 &v)
Definition vec3.h:814
__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:1210
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:879
__forceinline mat4 perspoffcenter(scalar l, scalar r, scalar b, scalar t, scalar zn, scalar zf)
Definition mat4.h:1278
__forceinline mat4 lookatlh(const point &eye, const point &at, const vector &up)
Definition mat4.h:573
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:451
static const f32x4 _mask_xyz
Definition vec3.h:34
mat4 affine(const vec3 &scale, const vec3 &rotationCenter, const quat &rotation, const vec3 &translation)
Definition mat4.cc:117
__forceinline mat4 lookto(point eye, vector direction, vector up)
Definition mat4.h:1238
__forceinline scalar cos(scalar x)
Definition scalar.h:191
bool ispointinside(const vec4 &p, const mat4 &m)
Definition mat4.cc:224
__forceinline scalar sin(scalar x)
Definition scalar.h:182
static const __m128i maskY
Definition mat4.h:31
__forceinline mat4 transpose(const mat4 &m)
Definition mat4.h:458
static const f32x4 _id_x
Definition vec3.h:26
__forceinline mat4 perspoffcenterrh(scalar l, scalar r, scalar b, scalar t, scalar zn, scalar zf)
Definition mat4.h:990
__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 persp(scalar w, scalar h, scalar zn, scalar zf)
Definition mat4.h:1265
__forceinline mat4 inverse(const mat4 &m)
Definition mat4.h:477
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:37
float x
Definition vec3.h:93
float z
Definition vec3.h:93
f32x4 vec
Definition vec3.h:95
float y
Definition vec3.h:93
A 4D vector.
Definition vec4.h:24
__m128 vec
Definition vec4.h:97
float w
Definition vec4.h:95
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:143