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