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;
68
70 void load(const scalar* ptr);
72 void loadu(const scalar* ptr);
74 void store(scalar* ptr) const;
76 void store3(scalar* ptr) const;
78 void storeu(scalar* ptr) const;
80 void stream(scalar* ptr) const;
81
83 void set(const vec4& r0, const vec4& r1, const vec4& r2, const vec4& r3);
85 void set(
86 float m00, float m01, float m02, float m03,
87 float m10, float m11, float m12, float m13,
88 float m20, float m21, float m22, float m23,
89 float m30, float m31, float m32, float m33);
90
92 void get_scale(vec4& scale) const;
94 void translate(const vec3& t);
96 void translate(const float x, const float y, const float z);
98 vec4 get_x() const;
100 vec4 get_y() const;
102 vec4 get_z() const;
104 vec4 get_w() const;
106 void scale(const vec3& v);
108 void scale(const float x, const float y, const float z);
109
111 union
112 {
113 struct
114 {
119 };
120
122 struct
123 {
124 float _11, _12, _13, _14;
125 float _21, _22, _23, _24;
126 float _31, _32, _33, _34;
127 float _41, _42, _43, _44;
128 };
129 float m[4][4];
130
132 vec4 r[4];
133 struct
134 {
139 };
140 };
141
142 static const mat4 identity;
143};
144
145//------------------------------------------------------------------------------
148__forceinline
149mat4::mat4() : row0(_id_x), row1(_id_y), row2(_id_z), row3(_id_w)
150{
151 // empty
152}
153
154//------------------------------------------------------------------------------
157__forceinline
158mat4::mat4(const vec4& row0, const vec4& row1, const vec4& row2, const vec4& row3)
159{
160 r[0] = row0.vec;
161 r[1] = row1.vec;
162 r[2] = row2.vec;
163 r[3] = row3.vec;
164}
165
166//------------------------------------------------------------------------------
169__forceinline
170mat4::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)
171{
172 this->r[0] = vec4(m00, m01, m02, m03);
173 this->r[1] = vec4(m10, m11, m12, m13);
174 this->r[2] = vec4(m20, m21, m22, m23);
175 this->r[3] = vec4(m30, m31, m32, m33);
176}
177
178//------------------------------------------------------------------------------
181__forceinline bool
182mat4::operator==(const mat4& rhs) const
183{
184 return vec4(r[0]) == vec4(rhs.r[0]) &&
185 vec4(r[1]) == vec4(rhs.r[1]) &&
186 vec4(r[2]) == vec4(rhs.r[2]) &&
187 vec4(r[3]) == vec4(rhs.r[3]);
188}
189
190//------------------------------------------------------------------------------
193__forceinline bool
194mat4::operator!=(const mat4& rhs) const
195{
196 return !(*this == rhs);
197}
198
199//------------------------------------------------------------------------------
202__forceinline void
204{
205 r[0] = _mm_load_ps(ptr);
206 r[1] = _mm_load_ps(ptr + 4);
207 r[2] = _mm_load_ps(ptr + 8);
208 r[3] = _mm_load_ps(ptr + 12);
209}
210
211//------------------------------------------------------------------------------
214__forceinline void
216{
217 r[0] = _mm_loadu_ps(ptr);
218 r[1] = _mm_loadu_ps(ptr + 4);
219 r[2] = _mm_loadu_ps(ptr + 8);
220 r[3] = _mm_loadu_ps(ptr + 12);
221}
222
223//------------------------------------------------------------------------------
226__forceinline void
228{
229 _mm_store_ps(ptr, r[0].vec);
230 _mm_store_ps((ptr + 4), r[1].vec);
231 _mm_store_ps((ptr + 8), r[2].vec);
232 _mm_store_ps((ptr + 12), r[3].vec);
233}
234
235//------------------------------------------------------------------------------
238__forceinline void
240{
241 _mm_store_ps(ptr, r[0].vec);
242 _mm_store_ps((ptr + 4), r[1].vec);
243 _mm_store_ps((ptr + 8), r[2].vec);
244}
245
246//------------------------------------------------------------------------------
249__forceinline void
251{
252 _mm_storeu_ps(ptr, r[0].vec);
253 _mm_storeu_ps((ptr + 4), r[1].vec);
254 _mm_storeu_ps((ptr + 8), r[2].vec);
255 _mm_storeu_ps((ptr + 12), r[3].vec);
256}
257
258//------------------------------------------------------------------------------
261__forceinline void
263{
264 this->storeu(ptr);
265}
266
267
268//------------------------------------------------------------------------------
271__forceinline void
272mat4::set(const vec4& r0, const vec4& r1, const vec4& r2, const vec4& r3)
273{
274 this->r[0] = r0;
275 this->r[1] = r1;
276 this->r[2] = r2;
277 this->r[3] = r3;
278}
279
280//------------------------------------------------------------------------------
283__forceinline void
284mat4::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)
285{
286 this->r[0] = vec4(m00, m01, m02, m03);
287 this->r[1] = vec4(m10, m11, m12, m13);
288 this->r[2] = vec4(m20, m21, m22, m23);
289 this->r[3] = vec4(m30, m31, m32, m33);
290}
291
292//------------------------------------------------------------------------------
295__forceinline void
297{
298 vec4 xaxis = r[0];
299 vec4 yaxis = r[1];
300 vec4 zaxis = r[2];
301 scalar xScale = length3(xaxis);
302 scalar yScale = length3(yaxis);
303 scalar zScale = length3(zaxis);
304
305 v = vec4(xScale, yScale, zScale, 1.0f);
306}
307
308//------------------------------------------------------------------------------
311__forceinline vec4
313{
314 return this->r[0];
315}
316
317//------------------------------------------------------------------------------
320__forceinline vec4
322{
323 return this->r[1];
324}
325
326//------------------------------------------------------------------------------
329__forceinline vec4
331{
332 return this->r[2];
333}
334
335//------------------------------------------------------------------------------
338__forceinline vec4
340{
341 return this->r[3];
342}
343
344//------------------------------------------------------------------------------
347__forceinline void
349{
350 this->r[3] = _mm_add_ps(r[3].vec, t.vec);
351}
352
353//------------------------------------------------------------------------------
356__forceinline void
358{
359 // need to make sure that last column isn't erased
360 vec4 scl = vec4(s, 1.0f);
361
362 r[0] = r[0] * scl;
363 r[1] = r[1] * scl;
364 r[2] = r[2] * scl;
365 r[3] = r[3] * scl;
366}
367
368//------------------------------------------------------------------------------
371__forceinline bool
373{
374 return m.r[0] == _id_x &&
375 m.r[1] == _id_y &&
376 m.r[2] == _id_z &&
377 m.r[3] == _id_w;
378}
379
380//------------------------------------------------------------------------------
383__forceinline scalar
385{
386 __m128 Va,Vb,Vc;
387 __m128 r1,r2,r3,tt,tt2;
388 __m128 sum,Det;
389
390 __m128 _L1 = m.r[0].vec;
391 __m128 _L2 = m.r[1].vec;
392 __m128 _L3 = m.r[2].vec;
393 __m128 _L4 = m.r[3].vec;
394 // Calculating the minterms for the first line.
395
396 // _mm_ror_ps is just a macro using _mm_shuffle_ps().
397 tt = _L4; tt2 = mm_ror_ps(_L3,1);
398 Vc = _mm_mul_ps(tt2, mm_ror_ps(tt,0)); // V3' dot V4
399 Va = _mm_mul_ps(tt2, mm_ror_ps(tt,2)); // V3' dot V4"
400 Vb = _mm_mul_ps(tt2, mm_ror_ps(tt,3)); // V3' dot V4^
401
402 r1 = _mm_sub_ps(mm_ror_ps(Va,1), mm_ror_ps(Vc,2)); // V3" dot V4^ - V3^ dot V4"
403 r2 = _mm_sub_ps(mm_ror_ps(Vb,2), mm_ror_ps(Vb,0)); // V3^ dot V4' - V3' dot V4^
404 r3 = _mm_sub_ps(mm_ror_ps(Va,0), mm_ror_ps(Vc,1)); // V3' dot V4" - V3" dot V4'
405
406 tt = _L2;
407 Va = mm_ror_ps(tt,1); sum = _mm_mul_ps(Va,r1);
408 Vb = mm_ror_ps(tt,2); sum = _mm_add_ps(sum,_mm_mul_ps(Vb,r2));
409 Vc = mm_ror_ps(tt,3); sum = _mm_add_ps(sum,_mm_mul_ps(Vc,r3));
410
411 // Calculating the determinant.
412 Det = _mm_mul_ps(sum,_L1);
413 Det = _mm_add_ps(Det,_mm_movehl_ps(Det,Det));
414
415 // Calculating the minterms of the second line (using previous results).
416 tt = mm_ror_ps(_L1,1); sum = _mm_mul_ps(tt,r1);
417 tt = mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r2));
418 tt = mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r3));
419
420 // Testing the determinant.
421 Det = _mm_sub_ss(Det,_mm_shuffle_ps(Det,Det,1));
422 return vec4(Det).x;
423}
424
425//------------------------------------------------------------------------------
428__forceinline mat4
429inverse(const mat4& m)
430{
431 __m128 Va,Vb,Vc;
432 __m128 r1,r2,r3,tt,tt2;
433 __m128 sum,Det,RDet;
434 __m128 trns0,trns1,trns2,trns3;
435
436 const __m128i pnpn = _mm_setr_epi32(0x00000000, static_cast<int>(0x80000000), 0x00000000, static_cast<int>(0x80000000));
437 const __m128i npnp = _mm_setr_epi32(static_cast<int>(0x80000000), 0x00000000, static_cast<int>(0x80000000), 0x00000000);
438 const __m128 zeroone = _mm_setr_ps(1.0f, 0.0f, 0.0f, 1.0f);
439
440 __m128 _L1 = m.r[0].vec;
441 __m128 _L2 = m.r[1].vec;
442 __m128 _L3 = m.r[2].vec;
443 __m128 _L4 = m.r[3].vec;
444 // Calculating the minterms for the first line.
445
446 // _mm_ror_ps is just a macro using _mm_shuffle_ps().
447 tt = _L4; tt2 = mm_ror_ps(_L3,1);
448 Vc = _mm_mul_ps(tt2, mm_ror_ps(tt,0)); // V3'dot V4
449 Va = _mm_mul_ps(tt2, mm_ror_ps(tt,2)); // V3'dot V4"
450 Vb = _mm_mul_ps(tt2, mm_ror_ps(tt,3)); // V3' dot V4^
451
452 r1 = _mm_sub_ps(mm_ror_ps(Va,1), mm_ror_ps(Vc,2)); // V3" dot V4^ - V3^ dot V4"
453 r2 = _mm_sub_ps(mm_ror_ps(Vb,2), mm_ror_ps(Vb,0)); // V3^ dot V4' - V3' dot V4^
454 r3 = _mm_sub_ps(mm_ror_ps(Va,0), mm_ror_ps(Vc,1)); // V3' dot V4" - V3" dot V4'
455
456 tt = _L2;
457 Va = mm_ror_ps(tt,1); sum = _mm_mul_ps(Va,r1);
458 Vb = mm_ror_ps(tt,2); sum = _mm_add_ps(sum,_mm_mul_ps(Vb,r2));
459 Vc = mm_ror_ps(tt,3); sum = _mm_add_ps(sum,_mm_mul_ps(Vc,r3));
460
461 // Calculating the determinant.
462 Det = _mm_mul_ps(sum,_L1);
463 Det = _mm_add_ps(Det,_mm_movehl_ps(Det,Det));
464
465
466 __m128 mtL1 = _mm_xor_ps(sum, _mm_castsi128_ps(pnpn));
467
468 // Calculating the minterms of the second line (using previous results).
469 tt = mm_ror_ps(_L1,1); sum = _mm_mul_ps(tt,r1);
470 tt = mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r2));
471 tt = mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r3));
472 __m128 mtL2 = _mm_xor_ps(sum, _mm_castsi128_ps(npnp));
473
474 // Testing the determinant.
475 Det = _mm_sub_ss(Det,_mm_shuffle_ps(Det,Det,1));
476
477 // Calculating the minterms of the third line.
478 tt = mm_ror_ps(_L1,1);
479 Va = _mm_mul_ps(tt,Vb); // V1' dot V2"
480 Vb = _mm_mul_ps(tt,Vc); // V1' dot V2^
481 Vc = _mm_mul_ps(tt,_L2); // V1' dot V2
482
483 r1 = _mm_sub_ps(mm_ror_ps(Va,1), mm_ror_ps(Vc,2)); // V1" dot V2^ - V1^ dot V2"
484 r2 = _mm_sub_ps(mm_ror_ps(Vb,2), mm_ror_ps(Vb,0)); // V1^ dot V2' - V1' dot V2^
485 r3 = _mm_sub_ps(mm_ror_ps(Va,0), mm_ror_ps(Vc,1)); // V1' dot V2" - V1" dot V2'
486
487 tt = mm_ror_ps(_L4,1); sum = _mm_mul_ps(tt,r1);
488 tt = mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r2));
489 tt = mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r3));
490 __m128 mtL3 = _mm_xor_ps(sum, _mm_castsi128_ps(pnpn));
491
492 // Dividing is FASTER than rcp_nr! (Because rcp_nr causes many register-memory RWs).
493 RDet = _mm_div_ss(zeroone, Det); // TODO: just 1.0f?
494 RDet = _mm_shuffle_ps(RDet,RDet,0x00);
495
496 // Devide the first 12 minterms with the determinant.
497 mtL1 = _mm_mul_ps(mtL1, RDet);
498 mtL2 = _mm_mul_ps(mtL2, RDet);
499 mtL3 = _mm_mul_ps(mtL3, RDet);
500
501 // Calculate the minterms of the forth line and devide by the determinant.
502 tt = mm_ror_ps(_L3,1); sum = _mm_mul_ps(tt,r1);
503 tt = mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r2));
504 tt = mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r3));
505 __m128 mtL4 = _mm_xor_ps(sum, _mm_castsi128_ps(npnp));
506 mtL4 = _mm_mul_ps(mtL4, RDet);
507
508 // Now we just have to transpose the minterms matrix.
509 trns0 = _mm_unpacklo_ps(mtL1,mtL2);
510 trns1 = _mm_unpacklo_ps(mtL3,mtL4);
511 trns2 = _mm_unpackhi_ps(mtL1,mtL2);
512 trns3 = _mm_unpackhi_ps(mtL3,mtL4);
513 _L1 = _mm_movelh_ps(trns0,trns1);
514 _L2 = _mm_movehl_ps(trns1,trns0);
515 _L3 = _mm_movelh_ps(trns2,trns3);
516 _L4 = _mm_movehl_ps(trns3,trns2);
517
518 return mat4(vec4(_L1), vec4(_L2), vec4(_L3), vec4(_L4));
519}
520
521//------------------------------------------------------------------------------
524__forceinline mat4
525lookatlh(const point& eye, const point& at, const vector& up)
526{
527#if NEBULA_DEBUG
528 n_assert(length(up) > 0);
529#endif
530 // hmm the XM lookat functions are kinda pointless, because they
531 // return a VIEW matrix, which is already inverse (so one would
532 // need to reverse again!)
533 const vector zaxis = normalize(at - eye);
534 vector normUp = normalize(up);
535 if (Math::abs(dot(zaxis, normUp)) > 0.9999999f)
536 {
537 // need to choose a different up vector because up and lookat point
538 // into same or opposite direction
539 // just rotate y->x, x->z and z->y
540 normUp = permute(normUp, normUp, 1, 2, 0);
541 }
542 const vector xaxis = normalize(cross(normUp, zaxis));
543 const vector yaxis = normalize(cross(zaxis, xaxis));
544 return mat4(xaxis, yaxis, zaxis, eye);
545}
546
547//------------------------------------------------------------------------------
550__forceinline mat4
551lookatrh(const point& eye, const point& at, const vector& up)
552{
553#if NEBULA_DEBUG
554 n_assert(length(up) > 0);
555#endif
556 // hmm the XM lookat functions are kinda pointless, because they
557 // return a VIEW matrix, which is already inverse (so one would
558 // need to reverse again!)
559 const vector zaxis = normalize(eye - at);
560 vector normUp = normalize(up);
561 if (Math::abs(dot(zaxis, normUp)) > 0.9999999f)
562 {
563 // need to choose a different up vector because up and lookat point
564 // into same or opposite direction
565 // just rotate y->x, x->z and z->y
566 normUp = permute(normUp, normUp, 1, 2, 0);
567 }
568 const vector xaxis = normalize(cross(normUp, zaxis));
569 const vector yaxis = normalize(cross(zaxis, xaxis));
570 return mat4(xaxis, yaxis, zaxis, eye);
571}
572
573#ifdef N_USE_AVX
574// dual linear combination using AVX instructions on YMM regs
575static inline __m256 twolincomb_AVX_8(__m256 A01, const mat4 &B)
576{
577 __m256 result;
578 result = _mm256_mul_ps(_mm256_shuffle_ps(A01, A01, 0x00), _mm256_broadcast_ps(&B.r[0].vec));
579 result = _mm256_add_ps(result, _mm256_mul_ps(_mm256_shuffle_ps(A01, A01, 0x55), _mm256_broadcast_ps(&B.r[1].vec)));
580 result = _mm256_add_ps(result, _mm256_mul_ps(_mm256_shuffle_ps(A01, A01, 0xaa), _mm256_broadcast_ps(&B.r[2].vec)));
581 result = _mm256_add_ps(result, _mm256_mul_ps(_mm256_shuffle_ps(A01, A01, 0xff), _mm256_broadcast_ps(&B.r[3].vec)));
582 return result;
583}
584
585//------------------------------------------------------------------------------
588__forceinline mat4
589operator*(const mat4& m0, const mat4& m1)
590{
591 mat4 out;
592
593 _mm256_zeroupper();
594 __m256 A01 = _mm256_loadu_ps(&m1.m[0][0]);
595 __m256 A23 = _mm256_loadu_ps(&m1.m[2][0]);
596
597 __m256 out01x = twolincomb_AVX_8(A01, m0);
598 __m256 out23x = twolincomb_AVX_8(A23, m0);
599
600 _mm256_storeu_ps(&out.m[0][0], out01x);
601 _mm256_storeu_ps(&out.m[2][0], out23x);
602 return out;
603}
604
605__forceinline mat4 operator%(const mat4& m1, const mat4& m0) = delete;
606
607#else
608//------------------------------------------------------------------------------
611__forceinline mat4
612operator*(const mat4& m0, const mat4& m1)
613{
614 mat4 ret;
615
616 vec4 mw = m1.r[0];
617
618 // Splat the all components of the first row
619 vec4 mx = splat_x(mw);
620 vec4 my = splat_y(mw);
621 vec4 mz = splat_z(mw);
622 mw = splat_w(mw);
623
624 vec4 m1x = m0.r[0];
625 vec4 m1y = m0.r[1];
626 vec4 m1z = m0.r[2];
627 vec4 m1w = m0.r[3];
628
629 //multiply first row
630 mx = multiply(mx, m1x);
631 my = multiply(my, m1y);
632 mz = multiply(mz, m1z);
633 mw = multiply(mw, m1w);
634
635 mx = mx + my;
636 mz = mz + mw;
637 ret.r[0] = mx + mz;
638
639 // rinse and repeat
640 mw = m1.row1;
641
642 mx = splat_x(mw);
643 my = splat_y(mw);
644 mz = splat_z(mw);
645 mw = splat_w(mw);
646
647 mx = multiply(mx, m1x);
648 my = multiply(my, m1y);
649 mz = multiply(mz, m1z);
650 mw = multiply(mw, m1w);
651
652 mx = mx + my;
653 mz = mz + mw;
654 ret.r[1] = mx + mz;
655
656 mw = m1.row2;
657
658 mx = splat_x(mw);
659 my = splat_y(mw);
660 mz = splat_z(mw);
661 mw = splat_w(mw);
662
663 mx = multiply(mx, m0.r[0]);
664 my = multiply(my, m0.r[1]);
665 mz = multiply(mz, m0.r[2]);
666 mw = multiply(mw, m0.r[3]);
667
668 mx = mx + my;
669 mz = mz + mw;
670 ret.r[2] = mx + mz;
671
672 mw = m1.row3;
673
674 mx = splat_x(mw);
675 my = splat_y(mw);
676 mz = splat_z(mw);
677 mw = splat_w(mw);
678
679 mx = multiply(mx, m1x);
680 my = multiply(my, m1y);
681 mz = multiply(mz, m1z);
682 mw = multiply(mw, m1w);
683
684 mx = mx + my;
685 mz = mz + mw;
686 ret.r[3] = mx + mz;
687
688 return ret;
689}
690#endif
691
692//------------------------------------------------------------------------------
695__forceinline vec4
696operator*(const mat4& m, const vec4& v)
697{
698 __m128 x = _mm_shuffle_ps(v.vec, v.vec, _MM_SHUFFLE(0, 0, 0, 0));
699 __m128 y = _mm_shuffle_ps(v.vec, v.vec, _MM_SHUFFLE(1, 1, 1, 1));
700 __m128 z = _mm_shuffle_ps(v.vec, v.vec, _MM_SHUFFLE(2, 2, 2, 2));
701 __m128 w = _mm_shuffle_ps(v.vec, v.vec, _MM_SHUFFLE(3, 3, 3, 3));
702
703 return
704 fmadd(x, m.r[0].vec,
705 fmadd(y, m.r[1].vec,
706 fmadd(z, m.r[2].vec,
707 _mm_mul_ps(w, m.r[3].vec))));
708}
709
710//------------------------------------------------------------------------------
713__forceinline vec4
714operator*(const mat4& m, const vec3& v)
715{
716 __m128 x = _mm_shuffle_ps(v.vec, v.vec, _MM_SHUFFLE(0, 0, 0, 0));
717 x = _mm_and_ps(x, _mask_xyz);
718 __m128 y = _mm_shuffle_ps(v.vec, v.vec, _MM_SHUFFLE(1, 1, 1, 1));
719 y = _mm_and_ps(y, _mask_xyz);
720 __m128 z = _mm_shuffle_ps(v.vec, v.vec, _MM_SHUFFLE(2, 2, 2, 2));
721 z = _mm_and_ps(z, _mask_xyz);
722
723 return
724 fmadd(x, m.r[0].vec,
725 fmadd(y, m.r[1].vec,
726 _mm_mul_ps(z, m.r[2].vec)));
727}
728
729//------------------------------------------------------------------------------
732__forceinline vec4
733operator*(const mat4& m, const point& p)
734{
735 __m128 x = _mm_shuffle_ps(p.vec, p.vec, _MM_SHUFFLE(0, 0, 0, 0));
736 __m128 y = _mm_shuffle_ps(p.vec, p.vec, _MM_SHUFFLE(1, 1, 1, 1));
737 __m128 z = _mm_shuffle_ps(p.vec, p.vec, _MM_SHUFFLE(2, 2, 2, 2));
738 __m128 w = _mm_shuffle_ps(p.vec, p.vec, _MM_SHUFFLE(3, 3, 3, 3));
739
740 return
741 fmadd(x, m.r[0].vec,
742 fmadd(y, m.r[1].vec,
743 fmadd(z, m.r[2].vec,
744 _mm_mul_ps(w, m.r[3].vec))));
745}
746
747//------------------------------------------------------------------------------
750__forceinline vector
751operator*(const mat4& m, const vector& v)
752{
753 __m128 x = _mm_shuffle_ps(v.vec, v.vec, _MM_SHUFFLE(0, 0, 0, 0));
754 x = _mm_and_ps(x, _mask_xyz);
755 __m128 y = _mm_shuffle_ps(v.vec, v.vec, _MM_SHUFFLE(1, 1, 1, 1));
756 y = _mm_and_ps(y, _mask_xyz);
757 __m128 z = _mm_shuffle_ps(v.vec, v.vec, _MM_SHUFFLE(2, 2, 2, 2));
758 z = _mm_and_ps(z, _mask_xyz);
759
760 return
761 fmadd(x, m.r[0].vec,
762 fmadd(y, m.r[1].vec,
763 _mm_mul_ps(z, m.r[2].vec)));
764}
765
766//------------------------------------------------------------------------------
769__forceinline mat4
771{
773 scalar dist = 1.0f / (zf - zn);
774 m.r[0] = vec4(2.0f / w, 0.0f, 0.0f, 0.0f);
775 m.r[1] = vec4(0.0f, 2.0f / h, 0.0f, 0.0f);
776 m.r[2] = vec4(0.0f, 0.0f, dist, 0.0f);
777 m.r[3] = vec4(0.0f, 0.0, -dist * zn, 1.0f);
778 return m;
779}
780
781//------------------------------------------------------------------------------
784__forceinline mat4
786{
788 scalar dist = 1.0f / (zn - zf);
789 m.r[0] = vec4(2.0f / w, 0.0f, 0.0f, 0.0f);
790 m.r[1] = vec4(0.0f, 2.0f / h, 0.0f, 0.0f);
791 m.r[2] = vec4(0.0f, 0.0f, dist, 0.0f);
792 m.r[3] = vec4(0.0f, 0.0, dist * zn, 1.0f);
793 return m;
794}
795
796//------------------------------------------------------------------------------
799__forceinline mat4
801{
803 scalar divwidth = 1.0f / (r - l);
804 scalar divheight = 1.0f / (t - b);
805 scalar dist = 1.0f / (zf - zn);
806 m.r[0] = vec4(2.0f * divwidth, 0.0f, 0.0f, 0.0f);
807 m.r[1] = vec4(0.0f, 2.0f * divheight, 0.0f, 0.0f);
808 m.r[2] = vec4(0.0f, 0.0f, dist, 0.0f);
809 m.r[3] = vec4(-(l+r) * divwidth, - (b+t) * divheight, -dist * zn, 1.0f);
810 return m;
811}
812
813//------------------------------------------------------------------------------
816__forceinline mat4
818{
820 scalar divwidth = 1.0f / (r - l);
821 scalar divheight = 1.0f / (t - b);
822 scalar dist = 1.0f / (zn - zf);
823 m.r[0] = vec4(2.0f * divwidth, 0.0f, 0.0f, 0.0f);
824 m.r[1] = vec4(0.0f, 2.0f * divheight, 0.0f, 0.0f);
825 m.r[2] = vec4(0.0f, 0.0f, dist, 0.0f);
826 m.r[3] = vec4(-(l+r) * divwidth, - (b+t) * divheight, dist * zn, 1.0f);
827 return m;
828}
829
830//------------------------------------------------------------------------------
833__forceinline mat4
834perspfovlh(scalar fovy, scalar aspect, scalar zn, scalar zf)
835{
837 scalar halfFov = 0.5f * fovy;
838 scalar sinfov = Math::sin(halfFov);
839 scalar cosfov = Math::cos(halfFov);
840
841 scalar height = cosfov / sinfov;
842 scalar width = height / aspect;
843
844 scalar dist = zf / (zf - zn);
845 m.r[0] = vec4(width, 0.0f, 0.0f, 0.0f);
846 m.r[1] = vec4(0.0f, height, 0.0f, 0.0f);
847 m.r[2] = vec4(0.0f, 0.0f, dist, 1.0f);
848 m.r[3] = vec4(0.0f, 0.0f, -dist * zn, 0.0f);
849
850 return m;
851}
852
853//------------------------------------------------------------------------------
856__forceinline mat4
857perspfovrh(scalar fovy, scalar aspect, scalar zn, scalar zf)
858{
860 scalar halfFov = 0.5f * fovy;
861 scalar sinfov = Math::sin(halfFov);
862 scalar cosfov = Math::cos(halfFov);
863
864 scalar height = cosfov / sinfov;
865 scalar width = height / aspect;
866
867 scalar dist = zf / (zn - zf);
868
869 m.r[0] = vec4(width, 0.0f, 0.0f, 0.0f);
870 m.r[1] = vec4(0.0f, height, 0.0f, 0.0f);
871 m.r[2] = vec4(0.0f, 0.0f, dist, -1.0f);
872 m.r[3] = vec4(0.0f, 0.0f, dist * zn, 0.0f);
873
874 return m;
875}
876
877//------------------------------------------------------------------------------
880__forceinline mat4
882{
884 scalar dist = zf / (zf - zn);
885
886 m.r[0] = vec4(2.0f * zn / w, 0.0f, 0.0f, 0.0f);
887 m.r[1] = vec4(0.0f, 2.0f * zn / h, 0.0f, 0.0f);
888 m.r[2] = vec4(0.0f, 0.0f, dist, 1.0f);
889 m.r[3] = vec4(0.0f, 0.0, -dist * zn, 0.0f);
890 return m;
891}
892
893//------------------------------------------------------------------------------
896__forceinline mat4
898{
900 scalar dist = zf / (zn - zf);
901
902 m.r[0] = vec4(2.0f * zn / w, 0.0f, 0.0f, 0.0f);
903 m.r[1] = vec4(0.0f, 2.0f * zn / h, 0.0f, 0.0f);
904 m.r[2] = vec4(0.0f, 0.0f, dist, -1.0f);
905 m.r[3] = vec4(0.0f, 0.0, dist * zn, 0.0f);
906 return m;
907}
908
909//------------------------------------------------------------------------------
912__forceinline mat4
914{
916 scalar divwidth = 1.0f / (r - l);
917 scalar divheight = 1.0f / (t - b);
918 scalar dist = zf / (zf - zn);
919
920 m.r[0] = vec4(2.0f * zn * divwidth, 0.0f, 0.0f, 0.0f);
921 m.r[1] = vec4(0.0f, 2.0f * zn * divheight, 0.0f, 0.0f);
922 m.r[2] = vec4(-(l + r) * divwidth, -(b + t) * divheight, dist, 1.0f);
923 m.r[3] = vec4(0.0f, 0.0f, -dist * zn, 0.0f);
924 return m;
925}
926
927//------------------------------------------------------------------------------
930__forceinline mat4
932{
934 scalar divwidth = 1.0f / (r - l);
935 scalar divheight = 1.0f / (t - b);
936 scalar dist = zf / (zn - zf);
937
938 m.r[0] = vec4(2.0f * zn * divwidth, 0.0f, 0.0f, 0.0f);
939 m.r[1] = vec4(0.0f, 2.0f * zn * divheight, 0.0f, 0.0f);
940 m.r[2] = vec4((l + r) * divwidth, (b + t) * divheight, dist, -1.0f);
941 m.r[3] = vec4(0.0f, 0.0f, dist * zn, 0.0f);
942 return m;
943}
944
945//------------------------------------------------------------------------------
948__forceinline mat4
950{
951 __m128 norm = normalize(axis).vec;
952
953 scalar sangle = Math::sin(angle);
954 scalar cangle = Math::cos(angle);
955
956 __m128 m1_c = _mm_set_ps1(1.0f - cangle);
957 __m128 c = _mm_set_ps1(cangle);
958 __m128 s = _mm_set_ps1(sangle);
959
960 __m128 nn1 = _mm_shuffle_ps(norm,norm,_MM_SHUFFLE(3,0,2,1));
961 __m128 nn2 = _mm_shuffle_ps(norm,norm,_MM_SHUFFLE(3,1,0,2));
962
963 __m128 v = _mm_mul_ps(nn1,m1_c);
964 v = _mm_mul_ps(nn2,v);
965
966 __m128 nn3 = _mm_mul_ps(norm, m1_c);
967 nn3 = _mm_mul_ps(norm, nn3);
968 nn3 = _mm_add_ps(nn3, c);
969
970 __m128 nn4 = _mm_mul_ps(norm,s);
971 nn4 = _mm_add_ps(nn4, v);
972 __m128 nn5 = _mm_mul_ps(s, norm);
973 nn5 = _mm_sub_ps(v,nn5);
974
975 v = _mm_and_ps(nn3, _mask_xyz);
976
977 __m128 v1 = _mm_shuffle_ps(nn4,nn5,_MM_SHUFFLE(2,1,2,0));
978 v1 = _mm_shuffle_ps(v1,v1,_MM_SHUFFLE(0,3,2,1));
979
980 __m128 v2 = _mm_shuffle_ps(nn4,nn5,_MM_SHUFFLE(0,0,1,1));
981 v2 = _mm_shuffle_ps(v2,v2,_MM_SHUFFLE(2,0,2,0));
982
983
984 nn5 = _mm_shuffle_ps(v,v1,_MM_SHUFFLE(1,0,3,0));
985 nn5 = _mm_shuffle_ps(nn5,nn5,_MM_SHUFFLE(1,3,2,0));
986
987 mat4 m;
988 m.row0 = nn5;
989
990 nn5 = _mm_shuffle_ps(v,v1,_MM_SHUFFLE(3,2,3,1));
991 nn5 = _mm_shuffle_ps(nn5,nn5,_MM_SHUFFLE(1,3,0,2));
992 m.row1 = nn5;
993
994 v2 = _mm_shuffle_ps(v2,v,_MM_SHUFFLE(3,2,1,0));
995 m.row2 = v2;
996
997 m.row3 = _id_w;
998 return m;
999
1000
1001}
1002
1003//------------------------------------------------------------------------------
1006__forceinline mat4
1008{
1009 mat4 m = mat4::identity;
1010
1011 scalar sangle = Math::sin(angle);
1012 scalar cangle = Math::cos(angle);
1013
1014 m.m[1][1] = cangle;
1015 m.m[1][2] = sangle;
1016
1017 m.m[2][1] = -sangle;
1018 m.m[2][2] = cangle;
1019 return m;
1020}
1021
1022//------------------------------------------------------------------------------
1025__forceinline mat4
1027{
1028 mat4 m = mat4::identity;
1029
1030 scalar sangle = Math::sin(angle);
1031 scalar cangle = Math::cos(angle);
1032
1033 m.m[0][0] = cangle;
1034 m.m[0][2] = -sangle;
1035
1036 m.m[2][0] = sangle;
1037 m.m[2][2] = cangle;
1038 return m;
1039}
1040
1041//------------------------------------------------------------------------------
1044__forceinline mat4
1046{
1047 mat4 m = mat4::identity;
1048
1049 scalar sangle = Math::sin(angle);
1050 scalar cangle = Math::cos(angle);
1051
1052 m.m[0][0] = cangle;
1053 m.m[0][1] = sangle;
1054
1055 m.m[1][0] = -sangle;
1056 m.m[1][1] = cangle;
1057 return m;
1058}
1059
1060//------------------------------------------------------------------------------
1063__forceinline mat4
1065{
1066 quat q = quatyawpitchroll(yaw, pitch, roll);
1067 return rotationquat(q);
1068}
1069
1070//------------------------------------------------------------------------------
1073__forceinline mat4
1075{
1076 mat4 m = mat4::identity;
1077 m.r[0] = _mm_setr_ps(scale, 0.0f, 0.0f, 0.0f);
1078 m.r[1] = _mm_setr_ps(0.0f, scale, 0.0f, 0.0f);
1079 m.r[2] = _mm_setr_ps(0.0f, 0.0f, scale, 0.0f);
1080 m.r[3] = _mm_setr_ps(0.0f, 0.0f, 0.0f, 1.0f);
1081
1082 return m;
1083}
1084
1085//------------------------------------------------------------------------------
1088__forceinline mat4
1090{
1091 mat4 m = mat4::identity;
1092 m.r[0] = _mm_setr_ps(sx, 0.0f, 0.0f, 0.0f);
1093 m.r[1] = _mm_setr_ps(0.0f, sy, 0.0f, 0.0f);
1094 m.r[2] = _mm_setr_ps(0.0f, 0.0f, sz, 0.0f);
1095 m.r[3] = _mm_setr_ps(0.0f, 0.0f, 0.0f, 1.0f);
1096
1097 return m;
1098}
1099
1100//------------------------------------------------------------------------------
1103__forceinline mat4
1104scaling(const vec3& s)
1105{
1106 mat4 m = mat4::identity;
1107 m.r[0] = _mm_and_ps(s.vec, _mm_castsi128_ps(maskX));
1108 m.r[1] = _mm_and_ps(s.vec, _mm_castsi128_ps(maskY));
1109 m.r[2] = _mm_and_ps(s.vec, _mm_castsi128_ps(maskZ));
1110
1111 return m;
1112}
1113
1114//------------------------------------------------------------------------------
1117__forceinline mat4
1119{
1120 mat4 m = mat4::identity;
1121 m.r[3] = _mm_set_ps(1.0f,z,y,x);
1122 return m;
1123}
1124
1125//------------------------------------------------------------------------------
1128__forceinline mat4
1130{
1131 mat4 m = mat4::identity;
1132 m.r[3] = vec4(t.vec, 1.0f);
1133 return m;
1134}
1135
1136//------------------------------------------------------------------------------
1141__forceinline mat4
1142trs(const vec3& position, const quat& rotation, const vec3& scale)
1143{
1144 return Math::affine(scale, rotation, position);
1145}
1146
1147//------------------------------------------------------------------------------
1150__forceinline mat4
1152{
1153 __m128 tmp3, tmp2, tmp1, tmp0;
1154 tmp0 = _mm_unpacklo_ps(m.r[0].vec, m.r[1].vec);
1155 tmp2 = _mm_unpacklo_ps(m.r[2].vec, m.r[3].vec);
1156 tmp1 = _mm_unpackhi_ps(m.r[0].vec, m.r[1].vec);
1157 tmp3 = _mm_unpackhi_ps(m.r[2].vec, m.r[3].vec);
1158 mat4 ret;
1159 ret.r[0] = _mm_movelh_ps(tmp0, tmp2);
1160 ret.r[1] = _mm_movehl_ps(tmp2, tmp0);
1161 ret.r[2] = _mm_movelh_ps(tmp1, tmp3);
1162 ret.r[3] = _mm_movehl_ps(tmp3, tmp1);
1163 return ret;
1164}
1165
1166//------------------------------------------------------------------------------
1169__forceinline mat4
1171{
1172 return {
1173 0, -v.z, v.y, 0,
1174 v.z, 0, -v.x, 0,
1175 -v.y, v.x, 0, 0,
1176 0, 0, 0, 0,
1177 };
1178}
1179
1180} // namespace Math
1181//------------------------------------------------------------------------------
1182
#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:417
static const __m128 _id_x
Definition vec3.h:29
__forceinline mat4 rotationz(scalar angle)
Definition mat4.h:1045
__forceinline mat4 rotationyawpitchroll(scalar yaw, scalar pitch, scalar roll)
Definition mat4.h:1064
__forceinline mat4 ortholh(scalar w, scalar h, scalar zn, scalar zf)
Definition mat4.h:770
__forceinline vec3 splat_z(const vec3 &v)
Definition vec3.h:823
__forceinline scalar length3(const vec4 &v)
Definition vec4.h:395
__forceinline mat4 rotationy(scalar angle)
Definition mat4.h:1026
__forceinline vec3 splat_x(const vec3 &v)
Definition vec3.h:801
__forceinline mat4 perspoffcenterlh(scalar l, scalar r, scalar b, scalar t, scalar zn, scalar zf)
Definition mat4.h:913
__forceinline mat4 orthooffcenterlh(scalar l, scalar r, scalar t, scalar b, scalar zn, scalar zf)
Definition mat4.h:800
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:897
__forceinline vec3 multiply(const vec3 &v0, const vec3 &v1)
Definition vec3.h:375
__forceinline scalar angle(const vec3 &v0, const vec3 &v1)
Definition vec3.h:508
__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:1142
__forceinline mat4 rotationaxis(const vec3 &axis, scalar angle)
Definition mat4.h:949
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:1118
__forceinline scalar length(const quat &q)
Definition quat.h:259
mat4 fromeuler(const vec3 &v)
Definition mat4.cc:237
__forceinline scalar dot(const plane &p, const vec4 &v1)
Definition plane.h:246
__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:785
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:551
static const __m128i maskZ
Definition mat4.h:32
__forceinline plane normalize(const plane &p)
Definition plane.h:255
__forceinline mat4 rotationx(scalar angle)
Definition mat4.h:1007
__forceinline mat4 persplh(scalar w, scalar h, scalar zn, scalar zf)
Definition mat4.h:881
__forceinline mat4 scaling(scalar scale)
Definition mat4.h:1074
__forceinline mat4 perspfovrh(scalar fovy, scalar aspect, scalar zn, scalar zf)
Definition mat4.h:857
static const __m128 _id_w
Definition vec3.h:32
__forceinline mat4 perspfovlh(scalar fovy, scalar aspect, scalar zn, scalar zf)
Definition mat4.h:834
__forceinline vec3 splat_y(const vec3 &v)
Definition vec3.h:812
__forceinline bool isidentity(const mat4 &m)
Definition mat4.h:372
__forceinline scalar determinant(const mat4 &m)
Definition mat4.h:384
mat4 skewsymmetric(const vec3 &v)
Definition mat4.h:1170
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:817
__forceinline mat4 lookatlh(const point &eye, const point &at, const vector &up)
Definition mat4.h:525
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:432
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:1151
__forceinline mat4 perspoffcenterrh(scalar l, scalar r, scalar b, scalar t, scalar zn, scalar zf)
Definition mat4.h:931
__forceinline vec4 splat_w(const vec4 &v)
Definition vec4.h:1047
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:429
Nebula's scalar datatype.
SSE support functions.
A 4x4 single point precision float matrix.
Definition mat4.h:49
vec4 y_axis
Definition mat4.h:116
vec4 row3
Definition mat4.h:138
vec4 position
Definition mat4.h:118
void translate(const vec3 &t)
add a translation to pos_component
Definition mat4.h:348
mat4(const mat4 &rhs)=default
copy constructor
vec4 get_w() const
Definition mat4.h:339
vec4 row1
Definition mat4.h:136
bool operator==(const mat4 &rhs) const
equality operator
Definition mat4.h:182
vec4 get_x() const
Definition mat4.h:312
void stream(scalar *ptr) const
stream content to 16-byte-aligned memory circumventing the write-cache
Definition mat4.h:262
vec4 z_axis
Definition mat4.h:117
float _21
Definition mat4.h:125
void store3(scalar *ptr) const
write 3 columns to 16-byte aligned memory through the write cache
Definition mat4.h:239
vec4 row0
Definition mat4.h:135
void scale(const vec3 &v)
scale matrix
Definition mat4.h:357
void load(const scalar *ptr)
load content from 16-byte-aligned memory
Definition mat4.h:203
vec4 r[4]
as a two-dimensional array
Definition mat4.h:132
float _31
Definition mat4.h:126
vec4 x_axis
Definition mat4.h:115
vec4 row2
Definition mat4.h:137
float _41
Definition mat4.h:127
vec4 get_y() const
Definition mat4.h:321
void store(scalar *ptr) const
write content to 16-byte-aligned memory through the write cache
Definition mat4.h:227
float m[4][4]
Definition mat4.h:129
void loadu(const scalar *ptr)
load content from unaligned memory
Definition mat4.h:215
void set(const vec4 &r0, const vec4 &r1, const vec4 &r2, const vec4 &r3)
set content from row vectors
Definition mat4.h:272
float _11
Definition mat4.h:124
bool operator!=(const mat4 &rhs) const
inequality operator
Definition mat4.h:194
vec4 get_z() const
Definition mat4.h:330
static const mat4 identity
Definition mat4.h:142
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:250
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:296
mat4()
default constructor. returns identity matrix
Definition mat4.h:149
__m128 vec
Definition plane.h:45
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:94
float z
Definition vec3.h:94
__m128 vec
Definition vec3.h:96
float y
Definition vec3.h:94
A 4D vector.
Definition vec4.h:24
__m128 vec
Definition vec4.h:95
float x
Definition vec4.h:93
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:154