Plasma Engine  2.0
Loading...
Searching...
No Matches
FPUVec4f_inl.h
1#pragma once
2
3PL_ALWAYS_INLINE plSimdVec4f::plSimdVec4f() = default;
4
5PL_ALWAYS_INLINE plSimdVec4f::plSimdVec4f(float xyzw)
6{
7 m_v.Set(xyzw);
8}
9
10PL_ALWAYS_INLINE plSimdVec4f::plSimdVec4f(const plSimdFloat& xyzw)
11{
12 m_v = xyzw.m_v;
13}
14
15PL_ALWAYS_INLINE plSimdVec4f::plSimdVec4f(float x, float y, float z, float w)
16{
17 m_v.Set(x, y, z, w);
18}
19
20PL_ALWAYS_INLINE void plSimdVec4f::Set(float xyzw)
21{
22 m_v.Set(xyzw);
23}
24
25PL_ALWAYS_INLINE void plSimdVec4f::Set(float x, float y, float z, float w)
26{
27 m_v.Set(x, y, z, w);
28}
29
30PL_ALWAYS_INLINE void plSimdVec4f::SetX(const plSimdFloat& f)
31{
32 m_v.x = f.m_v.x;
33}
34
35PL_ALWAYS_INLINE void plSimdVec4f::SetY(const plSimdFloat& f)
36{
37 m_v.y = f.m_v.x;
38}
39
40PL_ALWAYS_INLINE void plSimdVec4f::SetZ(const plSimdFloat& f)
41{
42 m_v.z = f.m_v.x;
43}
44
45PL_ALWAYS_INLINE void plSimdVec4f::SetW(const plSimdFloat& f)
46{
47 m_v.w = f.m_v.x;
48}
49
50PL_ALWAYS_INLINE void plSimdVec4f::SetZero()
51{
52 m_v.SetZero();
53}
54
55template <int N>
56PL_ALWAYS_INLINE void plSimdVec4f::Load(const float* pFloats)
57{
58 m_v.SetZero();
59 for (int i = 0; i < N; ++i)
60 {
61 (&m_v.x)[i] = pFloats[i];
62 }
63}
64
65template <int N>
66PL_ALWAYS_INLINE void plSimdVec4f::Store(float* pFloats) const
67{
68 for (int i = 0; i < N; ++i)
69 {
70 pFloats[i] = (&m_v.x)[i];
71 }
72}
73
74template <plMathAcc::Enum acc>
75PL_ALWAYS_INLINE plSimdVec4f plSimdVec4f::GetReciprocal() const
76{
77 return plVec4(1.0f).CompDiv(m_v);
78}
79
80template <plMathAcc::Enum acc>
81PL_ALWAYS_INLINE plSimdVec4f plSimdVec4f::GetSqrt() const
82{
83 plSimdVec4f result;
84 result.m_v.x = plMath::Sqrt(m_v.x);
85 result.m_v.y = plMath::Sqrt(m_v.y);
86 result.m_v.z = plMath::Sqrt(m_v.z);
87 result.m_v.w = plMath::Sqrt(m_v.w);
88
89 return result;
90}
91
92template <plMathAcc::Enum acc>
93plSimdVec4f plSimdVec4f::GetInvSqrt() const
94{
95 plSimdVec4f result;
96 result.m_v.x = 1.0f / plMath::Sqrt(m_v.x);
97 result.m_v.y = 1.0f / plMath::Sqrt(m_v.y);
98 result.m_v.z = 1.0f / plMath::Sqrt(m_v.z);
99 result.m_v.w = 1.0f / plMath::Sqrt(m_v.w);
100
101 return result;
102}
103
104template <int N, plMathAcc::Enum acc>
105void plSimdVec4f::NormalizeIfNotZero(const plSimdFloat& fEpsilon)
106{
107 plSimdFloat sqLength = GetLengthSquared<N>();
108 m_v *= sqLength.GetInvSqrt<acc>();
109 m_v = sqLength > fEpsilon.m_v ? m_v : plVec4::MakeZero();
110}
111
112template <int N>
113PL_ALWAYS_INLINE bool plSimdVec4f::IsZero() const
114{
115 for (int i = 0; i < N; ++i)
116 {
117 if ((&m_v.x)[i] != 0.0f)
118 return false;
119 }
120
121 return true;
122}
123
124template <int N>
125PL_ALWAYS_INLINE bool plSimdVec4f::IsZero(const plSimdFloat& fEpsilon) const
126{
127 for (int i = 0; i < N; ++i)
128 {
129 if (!plMath::IsZero((&m_v.x)[i], (float)fEpsilon))
130 return false;
131 }
132
133 return true;
134}
135
136template <int N>
137PL_ALWAYS_INLINE bool plSimdVec4f::IsNaN() const
138{
139 for (int i = 0; i < N; ++i)
140 {
141 if (plMath::IsNaN((&m_v.x)[i]))
142 return true;
143 }
144
145 return false;
146}
147
148template <int N>
149PL_ALWAYS_INLINE bool plSimdVec4f::IsValid() const
150{
151 for (int i = 0; i < N; ++i)
152 {
153 if (!plMath::IsFinite((&m_v.x)[i]))
154 return false;
155 }
156
157 return true;
158}
159
160template <int N>
161PL_ALWAYS_INLINE plSimdFloat plSimdVec4f::GetComponent() const
162{
163 return (&m_v.x)[N];
164}
165
166PL_ALWAYS_INLINE plSimdFloat plSimdVec4f::x() const
167{
168 return m_v.x;
169}
170
171PL_ALWAYS_INLINE plSimdFloat plSimdVec4f::y() const
172{
173 return m_v.y;
174}
175
176PL_ALWAYS_INLINE plSimdFloat plSimdVec4f::z() const
177{
178 return m_v.z;
179}
180
181PL_ALWAYS_INLINE plSimdFloat plSimdVec4f::w() const
182{
183 return m_v.w;
184}
185
186template <plSwizzle::Enum s>
187PL_ALWAYS_INLINE plSimdVec4f plSimdVec4f::Get() const
188{
189 plSimdVec4f result;
190
191 const float* v = &m_v.x;
192 result.m_v.x = v[(s & 0x3000) >> 12];
193 result.m_v.y = v[(s & 0x0300) >> 8];
194 result.m_v.z = v[(s & 0x0030) >> 4];
195 result.m_v.w = v[(s & 0x0003)];
196
197 return result;
198}
199
200template <plSwizzle::Enum s>
201PL_ALWAYS_INLINE plSimdVec4f plSimdVec4f::GetCombined(const plSimdVec4f& other) const
202{
203 plSimdVec4f result;
204
205 const float* v = &m_v.x;
206 const float* o = &other.m_v.x;
207 result.m_v.x = v[(s & 0x3000) >> 12];
208 result.m_v.y = v[(s & 0x0300) >> 8];
209 result.m_v.z = o[(s & 0x0030) >> 4];
210 result.m_v.w = o[(s & 0x0003)];
211
212 return result;
213}
214
215PL_ALWAYS_INLINE plSimdVec4f plSimdVec4f::operator-() const
216{
217 return -m_v;
218}
219
220PL_ALWAYS_INLINE plSimdVec4f plSimdVec4f::operator+(const plSimdVec4f& v) const
221{
222 return m_v + v.m_v;
223}
224
225PL_ALWAYS_INLINE plSimdVec4f plSimdVec4f::operator-(const plSimdVec4f& v) const
226{
227 return m_v - v.m_v;
228}
229
230
231PL_ALWAYS_INLINE plSimdVec4f plSimdVec4f::operator*(const plSimdFloat& f) const
232{
233 return m_v * f.m_v.x;
234}
235
236PL_ALWAYS_INLINE plSimdVec4f plSimdVec4f::operator/(const plSimdFloat& f) const
237{
238 return m_v / f.m_v.x;
239}
240
241PL_ALWAYS_INLINE plSimdVec4f plSimdVec4f::CompMul(const plSimdVec4f& v) const
242{
243 return m_v.CompMul(v.m_v);
244}
245
246template <plMathAcc::Enum acc>
247PL_ALWAYS_INLINE plSimdVec4f plSimdVec4f::CompDiv(const plSimdVec4f& v) const
248{
249 return m_v.CompDiv(v.m_v);
250}
251
252PL_ALWAYS_INLINE plSimdVec4f plSimdVec4f::CompMin(const plSimdVec4f& v) const
253{
254 return m_v.CompMin(v.m_v);
255}
256
257PL_ALWAYS_INLINE plSimdVec4f plSimdVec4f::CompMax(const plSimdVec4f& v) const
258{
259 return m_v.CompMax(v.m_v);
260}
261
262PL_ALWAYS_INLINE plSimdVec4f plSimdVec4f::Abs() const
263{
264 return m_v.Abs();
265}
266
267PL_ALWAYS_INLINE plSimdVec4f plSimdVec4f::Round() const
268{
269 plSimdVec4f result;
270 result.m_v.x = plMath::Round(m_v.x);
271 result.m_v.y = plMath::Round(m_v.y);
272 result.m_v.z = plMath::Round(m_v.z);
273 result.m_v.w = plMath::Round(m_v.w);
274
275 return result;
276}
277
278PL_ALWAYS_INLINE plSimdVec4f plSimdVec4f::Floor() const
279{
280 plSimdVec4f result;
281 result.m_v.x = plMath::Floor(m_v.x);
282 result.m_v.y = plMath::Floor(m_v.y);
283 result.m_v.z = plMath::Floor(m_v.z);
284 result.m_v.w = plMath::Floor(m_v.w);
285
286 return result;
287}
288
289PL_ALWAYS_INLINE plSimdVec4f plSimdVec4f::Ceil() const
290{
291 plSimdVec4f result;
292 result.m_v.x = plMath::Ceil(m_v.x);
293 result.m_v.y = plMath::Ceil(m_v.y);
294 result.m_v.z = plMath::Ceil(m_v.z);
295 result.m_v.w = plMath::Ceil(m_v.w);
296
297 return result;
298}
299
300PL_ALWAYS_INLINE plSimdVec4f plSimdVec4f::Trunc() const
301{
302 plSimdVec4f result;
303 result.m_v.x = plMath::Trunc(m_v.x);
304 result.m_v.y = plMath::Trunc(m_v.y);
305 result.m_v.z = plMath::Trunc(m_v.z);
306 result.m_v.w = plMath::Trunc(m_v.w);
307
308 return result;
309}
310
311PL_ALWAYS_INLINE plSimdVec4f plSimdVec4f::FlipSign(const plSimdVec4b& cmp) const
312{
313 plSimdVec4f result;
314 result.m_v.x = cmp.m_v.x ? -m_v.x : m_v.x;
315 result.m_v.y = cmp.m_v.y ? -m_v.y : m_v.y;
316 result.m_v.z = cmp.m_v.z ? -m_v.z : m_v.z;
317 result.m_v.w = cmp.m_v.w ? -m_v.w : m_v.w;
318
319 return result;
320}
321
322// static
323PL_ALWAYS_INLINE plSimdVec4f plSimdVec4f::Select(const plSimdVec4b& cmp, const plSimdVec4f& ifTrue, const plSimdVec4f& ifFalse)
324{
325 plSimdVec4f result;
326 result.m_v.x = cmp.m_v.x ? ifTrue.m_v.x : ifFalse.m_v.x;
327 result.m_v.y = cmp.m_v.y ? ifTrue.m_v.y : ifFalse.m_v.y;
328 result.m_v.z = cmp.m_v.z ? ifTrue.m_v.z : ifFalse.m_v.z;
329 result.m_v.w = cmp.m_v.w ? ifTrue.m_v.w : ifFalse.m_v.w;
330
331 return result;
332}
333
334PL_ALWAYS_INLINE plSimdVec4f& plSimdVec4f::operator+=(const plSimdVec4f& v)
335{
336 m_v += v.m_v;
337 return *this;
338}
339
340PL_ALWAYS_INLINE plSimdVec4f& plSimdVec4f::operator-=(const plSimdVec4f& v)
341{
342 m_v -= v.m_v;
343 return *this;
344}
345
346PL_ALWAYS_INLINE plSimdVec4f& plSimdVec4f::operator*=(const plSimdFloat& f)
347{
348 m_v *= f.m_v.x;
349 return *this;
350}
351
352PL_ALWAYS_INLINE plSimdVec4f& plSimdVec4f::operator/=(const plSimdFloat& f)
353{
354 m_v /= f.m_v.x;
355 return *this;
356}
357
358PL_ALWAYS_INLINE plSimdVec4b plSimdVec4f::operator==(const plSimdVec4f& v) const
359{
360 bool result[4];
361 result[0] = m_v.x == v.m_v.x;
362 result[1] = m_v.y == v.m_v.y;
363 result[2] = m_v.z == v.m_v.z;
364 result[3] = m_v.w == v.m_v.w;
365
366 return plSimdVec4b(result[0], result[1], result[2], result[3]);
367}
368
369PL_ALWAYS_INLINE plSimdVec4b plSimdVec4f::operator!=(const plSimdVec4f& v) const
370{
371 return !(*this == v);
372}
373
374PL_ALWAYS_INLINE plSimdVec4b plSimdVec4f::operator<=(const plSimdVec4f& v) const
375{
376 return !(*this > v);
377}
378
379PL_ALWAYS_INLINE plSimdVec4b plSimdVec4f::operator<(const plSimdVec4f& v) const
380{
381 bool result[4];
382 result[0] = m_v.x < v.m_v.x;
383 result[1] = m_v.y < v.m_v.y;
384 result[2] = m_v.z < v.m_v.z;
385 result[3] = m_v.w < v.m_v.w;
386
387 return plSimdVec4b(result[0], result[1], result[2], result[3]);
388}
389
390PL_ALWAYS_INLINE plSimdVec4b plSimdVec4f::operator>=(const plSimdVec4f& v) const
391{
392 return !(*this < v);
393}
394
395PL_ALWAYS_INLINE plSimdVec4b plSimdVec4f::operator>(const plSimdVec4f& v) const
396{
397 bool result[4];
398 result[0] = m_v.x > v.m_v.x;
399 result[1] = m_v.y > v.m_v.y;
400 result[2] = m_v.z > v.m_v.z;
401 result[3] = m_v.w > v.m_v.w;
402
403 return plSimdVec4b(result[0], result[1], result[2], result[3]);
404}
405
406template <>
407PL_ALWAYS_INLINE plSimdFloat plSimdVec4f::HorizontalSum<2>() const
408{
409 return m_v.x + m_v.y;
410}
411
412template <>
413PL_ALWAYS_INLINE plSimdFloat plSimdVec4f::HorizontalSum<3>() const
414{
415 return (float)HorizontalSum<2>() + m_v.z;
416}
417
418template <>
419PL_ALWAYS_INLINE plSimdFloat plSimdVec4f::HorizontalSum<4>() const
420{
421 return (float)HorizontalSum<3>() + m_v.w;
422}
423
424template <>
425PL_ALWAYS_INLINE plSimdFloat plSimdVec4f::HorizontalMin<2>() const
426{
427 return plMath::Min(m_v.x, m_v.y);
428}
429
430template <>
431PL_ALWAYS_INLINE plSimdFloat plSimdVec4f::HorizontalMin<3>() const
432{
433 return plMath::Min((float)HorizontalMin<2>(), m_v.z);
434}
435
436template <>
437PL_ALWAYS_INLINE plSimdFloat plSimdVec4f::HorizontalMin<4>() const
438{
439 return plMath::Min((float)HorizontalMin<3>(), m_v.w);
440}
441
442template <>
443PL_ALWAYS_INLINE plSimdFloat plSimdVec4f::HorizontalMax<2>() const
444{
445 return plMath::Max(m_v.x, m_v.y);
446}
447
448template <>
449PL_ALWAYS_INLINE plSimdFloat plSimdVec4f::HorizontalMax<3>() const
450{
451 return plMath::Max((float)HorizontalMax<2>(), m_v.z);
452}
453
454template <>
455PL_ALWAYS_INLINE plSimdFloat plSimdVec4f::HorizontalMax<4>() const
456{
457 return plMath::Max((float)HorizontalMax<3>(), m_v.w);
458}
459
460template <int N>
461PL_ALWAYS_INLINE plSimdFloat plSimdVec4f::Dot(const plSimdVec4f& v) const
462{
463 float result = 0.0f;
464
465 for (int i = 0; i < N; ++i)
466 {
467 result += (&m_v.x)[i] * (&v.m_v.x)[i];
468 }
469
470 return result;
471}
472
473PL_ALWAYS_INLINE plSimdVec4f plSimdVec4f::CrossRH(const plSimdVec4f& v) const
474{
475 return m_v.GetAsVec3().CrossRH(v.m_v.GetAsVec3()).GetAsVec4(0.0f);
476}
477
479{
480 if (plMath::Abs(m_v.y) < 0.99f)
481 {
482 return plVec4(-m_v.z, 0.0f, m_v.x, 0.0f);
483 }
484 else
485 {
486 return plVec4(0.0f, m_v.z, -m_v.y, 0.0f);
487 }
488}
489
490// static
491PL_ALWAYS_INLINE plSimdVec4f plSimdVec4f::MulAdd(const plSimdVec4f& a, const plSimdVec4f& b, const plSimdVec4f& c)
492{
493 return a.CompMul(b) + c;
494}
495
496// static
497PL_ALWAYS_INLINE plSimdVec4f plSimdVec4f::MulAdd(const plSimdVec4f& a, const plSimdFloat& b, const plSimdVec4f& c)
498{
499 return a * b + c;
500}
501
502// static
503PL_ALWAYS_INLINE plSimdVec4f plSimdVec4f::MulSub(const plSimdVec4f& a, const plSimdVec4f& b, const plSimdVec4f& c)
504{
505 return a.CompMul(b) - c;
506}
507
508// static
509PL_ALWAYS_INLINE plSimdVec4f plSimdVec4f::MulSub(const plSimdVec4f& a, const plSimdFloat& b, const plSimdVec4f& c)
510{
511 return a * b - c;
512}
513
514// static
515PL_ALWAYS_INLINE plSimdVec4f plSimdVec4f::CopySign(const plSimdVec4f& magnitude, const plSimdVec4f& sign)
516{
517 plSimdVec4f result;
518 result.m_v.x = sign.m_v.x < 0.0f ? -magnitude.m_v.x : magnitude.m_v.x;
519 result.m_v.y = sign.m_v.y < 0.0f ? -magnitude.m_v.y : magnitude.m_v.y;
520 result.m_v.z = sign.m_v.z < 0.0f ? -magnitude.m_v.z : magnitude.m_v.z;
521 result.m_v.w = sign.m_v.w < 0.0f ? -magnitude.m_v.w : magnitude.m_v.w;
522
523 return result;
524}
Definition SimdFloat.h:7
Definition SimdVec4b.h:7
A 4-component SIMD vector class.
Definition SimdVec4f.h:8
plSimdVec4f CrossRH(const plSimdVec4f &v) const
3D cross product, w is ignored.
Definition FPUVec4f_inl.h:473
plSimdVec4f GetOrthogonalVector() const
Generates an arbitrary vector such that Dot<3>(GetOrthogonalVector()) == 0.
Definition FPUVec4f_inl.h:478
plSimdVec4f GetCombined(const plSimdVec4f &other) const
x = this[s0], y = this[s1], z = other[s2], w = other[s3]
const plVec3Template< Type > CrossRH(const plVec3Template< Type > &rhs) const
Returns the Cross-product of the two vectors (NOT commutative, order DOES matter)
Definition Vec3_inl.h:299
const plVec4Template< Type > GetAsVec4(Type w) const
Returns an plVec4Template with x,y,z from this vector and w set to the parameter.
Definition Vec4_inl.h:35
const plVec4Template< Type > CompMin(const plVec4Template< Type > &rhs) const
Returns the component-wise minimum of *this and rhs.
Definition Vec4_inl.h:327
const plVec4Template< Type > CompDiv(const plVec4Template< Type > &rhs) const
Returns the component-wise division of *this and rhs.
Definition Vec4_inl.h:366
void SetZero()
Sets the vector to all zero.
Definition Vec4_inl.h:139
const plVec3Template< Type > GetAsVec3() const
Returns an plVec3Template with x,y and z from this vector.
Definition Vec4_inl.h:112
const plVec4Template< Type > Abs() const
brief Returns the component-wise absolute of *this.
Definition Vec4_inl.h:376
static plVec4Template< float > MakeZero()
Definition Vec4.h:41
void Set(Type xyzw)
Sets all 4 components to this value.
Definition Vec4_inl.h:121
const plVec4Template< Type > CompMul(const plVec4Template< Type > &rhs) const
Returns the component-wise multiplication of *this and rhs.
Definition Vec4_inl.h:355
const plVec4Template< Type > CompMax(const plVec4Template< Type > &rhs) const
Returns the component-wise maximum of *this and rhs.
Definition Vec4_inl.h:336
constexpr PL_ALWAYS_INLINE T Min(T f1, T f2)
Returns the smaller value, f1 or f2.
Definition Math_inl.h:27
PL_ALWAYS_INLINE double Round(double f)
Rounds f to the next integer.
Definition MathDouble_inl.h:35
PL_ALWAYS_INLINE double Sqrt(double f)
Returns the square root of f.
Definition MathDouble_inl.h:99
bool IsZero(Type f, Type fEpsilon)
Checks whether the given number is close to zero.
Definition Math_inl.h:288
PL_ALWAYS_INLINE Type Trunc(Type f)
Returns the integer-part of f (removes the fraction).
Definition Math_inl.h:296
constexpr PL_ALWAYS_INLINE T Abs(T f)
Returns the absolute value of f.
Definition Math_inl.h:21
constexpr PL_ALWAYS_INLINE T Max(T f1, T f2)
Returns the greater value, f1 or f2.
Definition Math_inl.h:39