Nebula
Loading...
Searching...
No Matches
vector.h
Go to the documentation of this file.
1#pragma once
2//------------------------------------------------------------------------------
14//------------------------------------------------------------------------------
15#include "scalar.h"
16#include "vec4.h"
17#include "vec3.h"
18namespace Math
19{
20
21struct vector
22{
24 vector();
28 vector(scalar v);
30 vector(const vector& rhs);
32 vector(const vec3& rhs);
34 vector(const vec4& rhs);
36 vector(const __m128& rhs);
37
39 void load(const scalar* ptr);
41 void loadu(const scalar* ptr);
43 void store(scalar* ptr) const;
45 void storeu(scalar* ptr) const;
46
48 void operator=(const vector& rhs);
50 void operator=(const __m128& rhs);
52 void operator+=(const vector& rhs);
54 void operator-=(const vector& rhs);
56 void operator*=(scalar s);
58 bool operator==(const vector& rhs) const;
60 bool operator!=(const vector& rhs) const;
62 float operator[](int index) const;
64 float& operator[](int index);
66 operator vec4() const;
68 operator vec3() const;
69
71 void set(scalar x, scalar y, scalar z);
72
74 static vector nullvec();
76 static vector onevec();
78 static vector upvec();
79
80 union
81 {
82 __m128 vec;
83 struct
84 {
85 float x, y, z;
86 };
87 };
88};
89
90//------------------------------------------------------------------------------
93__forceinline
95{
96 this->vec = _mm_set1_ps(0);
97}
98
99//------------------------------------------------------------------------------
102__forceinline
104{
105 this->vec = _mm_setr_ps(x, y, z, 0);
106}
107
108//------------------------------------------------------------------------------
111__forceinline
113{
114 this->vec = _mm_setr_ps(v, v, v, 0);
115}
116
117//------------------------------------------------------------------------------
120__forceinline
122{
123 this->vec = rhs.vec;
124}
125
126//------------------------------------------------------------------------------
129__forceinline
131{
132 this->vec = rhs.vec;
133}
134
135//------------------------------------------------------------------------------
138__forceinline
140{
141 this->vec = rhs.vec;
142}
143
144//------------------------------------------------------------------------------
147__forceinline
148vector::vector(const __m128& rhs)
149{
150 this->vec = _mm_insert_ps(rhs, _id_w, 0b111000);
151}
152
153//------------------------------------------------------------------------------
157__forceinline void
159{
160 this->vec = _mm_load_ps(ptr);
161 this->vec = _mm_and_ps(this->vec, _mask_xyz);
162}
163
164//------------------------------------------------------------------------------
168__forceinline void
170{
171 this->vec = _mm_loadu_ps(ptr);
172 this->vec = _mm_and_ps(this->vec, _mask_xyz);
173}
174
175//------------------------------------------------------------------------------
179__forceinline void
181{
182 __m128 v = _mm_permute_ps(this->vec, _MM_SHUFFLE(2, 2, 2, 2));
183 _mm_storel_epi64(reinterpret_cast<__m128i*>(ptr), _mm_castps_si128(this->vec));
184 _mm_store_ss(&ptr[2], v);
185}
186
187//------------------------------------------------------------------------------
191__forceinline void
193{
194 __m128 t1 = _mm_permute_ps(this->vec, _MM_SHUFFLE(1, 1, 1, 1));
195 __m128 t2 = _mm_permute_ps(this->vec, _MM_SHUFFLE(2, 2, 2, 2));
196 _mm_store_ss(&ptr[0], this->vec);
197 _mm_store_ss(&ptr[1], t1);
198 _mm_store_ss(&ptr[2], t2);
199}
200
201//------------------------------------------------------------------------------
204__forceinline vector
205operator-(const vector& rhs)
206{
207 return vector(_mm_xor_ps(_mm_castsi128_ps(_sign), rhs.vec));
208}
209
210//------------------------------------------------------------------------------
213__forceinline void
215{
216 this->vec = rhs.vec;
217}
218
219//------------------------------------------------------------------------------
222__forceinline void
223vector::operator=(const __m128& rhs)
224{
225 this->vec = _mm_insert_ps(rhs, _id_w, 0b111000);
226}
227
228//------------------------------------------------------------------------------
231__forceinline void
233{
234 this->vec = _mm_add_ps(this->vec, rhs.vec);
235}
236
237//------------------------------------------------------------------------------
240__forceinline void
242{
243 this->vec = _mm_sub_ps(this->vec, rhs.vec);
244}
245
246//------------------------------------------------------------------------------
249__forceinline void
251{
252 this->vec = _mm_mul_ps(this->vec, _mm_set1_ps(s));
253}
254
255//------------------------------------------------------------------------------
258__forceinline vector
259operator+(const vector& lhs, const vector& rhs)
260{
261 return _mm_add_ps(lhs.vec, rhs.vec);
262}
263
264//------------------------------------------------------------------------------
267__forceinline vector
268operator-(const vector& lhs, const vector& rhs)
269{
270 return _mm_sub_ps(lhs.vec, rhs.vec);
271}
272
273//------------------------------------------------------------------------------
276__forceinline vector
277operator*(const vector& lhs, scalar s)
278{
279 return _mm_mul_ps(lhs.vec, _mm_set1_ps(s));
280}
281
282//------------------------------------------------------------------------------
285__forceinline vector
286operator*(const vector& lhs, const vector& rhs)
287{
288 return _mm_mul_ps(lhs.vec, rhs.vec);
289}
290
291//------------------------------------------------------------------------------
294__forceinline bool
295vector::operator==(const vector& rhs) const
296{
297 __m128 vTemp = _mm_cmpeq_ps(this->vec, rhs.vec);
298 return ((_mm_movemask_ps(vTemp) == 0x0f) != 0);
299}
300
301//------------------------------------------------------------------------------
304__forceinline bool
305vector::operator!=(const vector& rhs) const
306{
307 __m128 vTemp = _mm_cmpeq_ps(this->vec, rhs.vec);
308 return ((_mm_movemask_ps(vTemp) == 0x0f) == 0);
309}
310
311//------------------------------------------------------------------------------
314__forceinline float
315vector::operator[](int index) const
316{
317 n_assert(index >= 0 && index < 4);
318 return *((&this->x) + index);
319}
320
321//------------------------------------------------------------------------------
324__forceinline float&
326{
327 n_assert(index >= 0 && index < 4);
328 return *((&this->x) + index);
329}
330
331//------------------------------------------------------------------------------
334__forceinline
335vector::operator vec4() const
336{
337 return vec4(this->vec);
338}
339
340//------------------------------------------------------------------------------
343__forceinline
344vector::operator vec3() const
345{
346 return vec3(this->vec);
347}
348
349//------------------------------------------------------------------------------
352__forceinline void
354{
355 this->vec = _mm_setr_ps(x, y, z, 0);
356}
357
358//------------------------------------------------------------------------------
361__forceinline vector
363{
364 if (v == vector(0)) return v;
365 __m128 t = _mm_sqrt_ps(_mm_dp_ps(v.vec, v.vec, 0xF7));
366 t = _mm_or_ps(t, _id_w);
367 return _mm_div_ps(v.vec, t);
368}
369
370//------------------------------------------------------------------------------
373__forceinline vector
375{
376 if (v == vector(0)) return v;
377 __m128 t = _mm_rsqrt_ps(_mm_dp_ps(v.vec, v.vec, 0xF7));
378 t = _mm_or_ps(t, _id_w);
379 return _mm_mul_ps(v.vec, t);
380}
381
382//------------------------------------------------------------------------------
385__forceinline scalar
386dot(const vector& v0, const vector& v1)
387{
388 return _mm_cvtss_f32(_mm_dp_ps(v0.vec, v1.vec, 0x71));
389}
390
391//------------------------------------------------------------------------------
394__forceinline vector
395cross(const vector& v0, const vector& v1)
396{
397 __m128 tmp0, tmp1, tmp2, tmp3, result;
398 tmp0 = _mm_shuffle_ps(v0.vec, v0.vec, _MM_SHUFFLE(3, 0, 2, 1));
399 tmp1 = _mm_shuffle_ps(v1.vec, v1.vec, _MM_SHUFFLE(3, 1, 0, 2));
400 tmp2 = _mm_shuffle_ps(v0.vec, v0.vec, _MM_SHUFFLE(3, 1, 0, 2));
401 tmp3 = _mm_shuffle_ps(v1.vec, v1.vec, _MM_SHUFFLE(3, 0, 2, 1));
402 result = _mm_mul_ps(tmp0, tmp1);
403 result = _mm_sub_ps(result, _mm_mul_ps(tmp2, tmp3));
404 return result;
405}
406
407//------------------------------------------------------------------------------
410__forceinline scalar
411length(const vector& v)
412{
413 return _mm_cvtss_f32(_mm_sqrt_ss(_mm_dp_ps(v.vec, v.vec, 0x71)));
414}
415
416//------------------------------------------------------------------------------
419__forceinline scalar
421{
422 return _mm_cvtss_f32(_mm_dp_ps(v.vec, v.vec, 0x71));
423}
424
425//------------------------------------------------------------------------------
428__forceinline vector
430{
431 return vector(0,0,0);
432}
433
434//------------------------------------------------------------------------------
437__forceinline vector
439{
440 return vector(1, 1, 1);
441}
442
443//------------------------------------------------------------------------------
446__forceinline vector
448{
449 return vector(0, 1, 0);
450}
451
452} // namespace Math
#define n_assert(exp)
Definition debug.h:50
Half precision (16 bit) float implementation.
Definition angularpfeedbackloop.h:17
__forceinline vec3 cross(const vec3 &v0, const vec3 &v1)
Definition vec3.h:416
static const __m128i _sign
Definition vec3.h:35
__forceinline scalar length(const quat &q)
Definition quat.h:259
__forceinline scalar lengthsq(const quat &q)
Definition quat.h:268
__forceinline scalar dot(const plane &p, const vec4 &v1)
Definition plane.h:246
__forceinline plane normalize(const plane &p)
Definition plane.h:255
half operator-(half one, half two)
Definition half.h:114
static const __m128 _id_w
Definition vec3.h:32
float scalar
Definition scalar.h:45
half operator+(half one, half two)
Definition half.h:105
half operator*(half one, half two)
Definition half.h:123
static const __m128 _mask_xyz
Definition vec3.h:36
__forceinline vec3 normalizeapprox(const vec3 &v)
Definition vec3.h:591
Nebula's scalar datatype.
A 3D vector.
Definition vec3.h:39
__m128 vec
Definition vec3.h:95
A 4D vector.
Definition vec4.h:24
__m128 vec
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 vector &rhs) const
equality operator
Definition vector.h:295
float z
Definition vector.h:85
void store(scalar *ptr) const
write content to 16-byte-aligned memory through the write cache
Definition vector.h:180
void operator=(const vector &rhs)
assignment operator
Definition vector.h:214
float x
Definition vector.h:85
float y
Definition vector.h:85
static vector upvec()
create the up vector
Definition vector.h:447
void storeu(scalar *ptr) const
write content to unaligned memory through the write cache
Definition vector.h:192
void operator*=(scalar s)
inplace scalar multiply
Definition vector.h:250
void loadu(const scalar *ptr)
load content from unaligned memory
Definition vector.h:169
void operator+=(const vector &rhs)
inplace add
Definition vector.h:232
void set(scalar x, scalar y, scalar z)
set content
Definition vector.h:353
static vector onevec()
create a 1,1,1 vector
Definition vector.h:438
void operator-=(const vector &rhs)
inplace sub
Definition vector.h:241
void load(const scalar *ptr)
load content from 16-byte-aligned memory
Definition vector.h:158
bool operator!=(const vector &rhs) const
inequality operator
Definition vector.h:305
vector()
default constructor
Definition vector.h:94
static vector nullvec()
create a null vector
Definition vector.h:429
float operator[](int index) const
Definition vector.h:315