Plasma Engine  2.0
Loading...
Searching...
No Matches
Vec4_inl.h
1#pragma once
2
3#include <Foundation/Math/Vec2.h>
4#include <Foundation/Math/Vec3.h>
5
6// *** Vec2 and Vec3 Code ***
7// Cannot put this into the Vec3_inl.h file, that would result in circular dependencies
8
9template <typename Type>
10PL_FORCE_INLINE const plVec3Template<Type> plVec2Template<Type>::GetAsVec3(Type z) const
11{
12 PL_NAN_ASSERT(this);
13
14 return plVec3Template<Type>(x, y, z);
15}
16
17template <typename Type>
18PL_FORCE_INLINE const plVec4Template<Type> plVec2Template<Type>::GetAsVec4(Type z, Type w) const
19{
20 PL_NAN_ASSERT(this);
21
22 return plVec4Template<Type>(x, y, z, w);
24
25template <typename Type>
27{
28 // don't assert here, as the 3rd and 4th component may be NaN when this is fine, e.g. during interop with the SIMD classes
29 // PL_NAN_ASSERT(this);
30
31 return plVec2Template<Type>(x, y);
33
34template <typename Type>
35PL_FORCE_INLINE const plVec4Template<Type> plVec3Template<Type>::GetAsVec4(Type w) const
36{
37 PL_NAN_ASSERT(this);
38
39 return plVec4Template<Type>(x, y, z, w);
40}
41
42template <typename Type>
44{
45 // don't assert here, as the 4th component may be NaN when this is fine, e.g. during interop with the SIMD classes
46 // PL_NAN_ASSERT(this);
47
48 return plVec4Template<Type>(x, y, z, 1);
49}
50
51template <typename Type>
53{
54 // don't assert here, as the 4th component may be NaN when this is fine, e.g. during interop with the SIMD classes
55 // PL_NAN_ASSERT(this);
56
57 return plVec4Template<Type>(x, y, z, 0);
58}
59
60// *****************
61
62template <typename Type>
64{
65#if PL_ENABLED(PL_MATH_CHECK_FOR_NAN)
66 // Initialize all data to NaN in debug mode to find problems with uninitialized data easier.
67 const Type TypeNaN = plMath::NaN<Type>();
68 x = TypeNaN;
69 y = TypeNaN;
70 z = 0;
71 w = 0;
72#endif
73}
75template <typename Type>
76PL_ALWAYS_INLINE plVec4Template<Type>::plVec4Template(Type x, Type y, Type z, Type w)
77 : x(x)
78 , y(y)
79 , z(z)
80 , w(w)
81{
82}
83
84template <typename Type>
86 : x(vXyz.x)
87 , y(vXyz.y)
88 , z(vXyz.z)
89 , w(w)
90{
91}
92
93template <typename Type>
95 : x(v)
96 , y(v)
97 , z(v)
98 , w(v)
99{
100}
101
102template <typename Type>
104{
105 // don't assert here, as the 4th component may be NaN when this is fine, e.g. during interop with the SIMD classes
106 // PL_NAN_ASSERT(this);
107
109}
110
111template <typename Type>
113{
114 // don't assert here, as the 4th component may be NaN when this is fine, e.g. during interop with the SIMD classes
115 // PL_NAN_ASSERT(this);
116
117 return plVec3Template<Type>(x, y, z);
119
120template <typename Type>
121PL_ALWAYS_INLINE void plVec4Template<Type>::Set(Type xyzw)
122{
123 x = xyzw;
124 y = xyzw;
125 z = xyzw;
126 w = xyzw;
128
129template <typename Type>
130PL_ALWAYS_INLINE void plVec4Template<Type>::Set(Type inX, Type inY, Type inZ, Type inW)
131{
132 x = inX;
133 y = inY;
134 z = inZ;
135 w = inW;
137
138template <typename Type>
140{
141 x = y = z = w = 0;
143
144template <typename Type>
145PL_IMPLEMENT_IF_FLOAT_TYPE PL_ALWAYS_INLINE Type plVec4Template<Type>::GetLength() const
146{
147 return (plMath::Sqrt(GetLengthSquared()));
149
150template <typename Type>
151PL_FORCE_INLINE Type plVec4Template<Type>::GetLengthSquared() const
152{
153 PL_NAN_ASSERT(this);
155 return (x * x + y * y + z * z + w * w);
156}
158template <typename Type>
159PL_IMPLEMENT_IF_FLOAT_TYPE PL_FORCE_INLINE Type plVec4Template<Type>::GetLengthAndNormalize()
161 const Type fLength = GetLength();
162 *this /= fLength;
163 return fLength;
164}
165
166template <typename Type>
167PL_IMPLEMENT_IF_FLOAT_TYPE PL_FORCE_INLINE const plVec4Template<Type> plVec4Template<Type>::GetNormalized() const
168{
169 const Type fLen = GetLength();
170
171 const Type fLengthInv = plMath::Invert(fLen);
172 return plVec4Template<Type>(x * fLengthInv, y * fLengthInv, z * fLengthInv, w * fLengthInv);
173}
174
175template <typename Type>
176PL_IMPLEMENT_IF_FLOAT_TYPE PL_ALWAYS_INLINE void plVec4Template<Type>::Normalize()
177{
178 *this /= GetLength();
179}
180
181template <typename Type>
182PL_IMPLEMENT_IF_FLOAT_TYPE inline plResult plVec4Template<Type>::NormalizeIfNotZero(const plVec4Template<Type>& vFallback, Type fEpsilon)
183{
184 PL_NAN_ASSERT(&vFallback);
185
186 const Type fLength = GetLength();
187
188 if (!plMath::IsFinite(fLength) || plMath::IsZero(fLength, fEpsilon))
189 {
190 *this = vFallback;
191 return PL_FAILURE;
192 }
193
194 *this /= fLength;
195 return PL_SUCCESS;
196}
197
201template <typename Type>
202PL_IMPLEMENT_IF_FLOAT_TYPE inline bool plVec4Template<Type>::IsNormalized(Type fEpsilon /* = plMath::HugeEpsilon<Type>() */) const
203{
204 const Type t = GetLengthSquared();
205 return plMath::IsEqual(t, (Type)1, fEpsilon);
206}
207
208template <typename Type>
210{
211 PL_NAN_ASSERT(this);
212
213 return ((x == 0.0f) && (y == 0.0f) && (z == 0.0f) && (w == 0.0f));
214}
215
216template <typename Type>
217inline bool plVec4Template<Type>::IsZero(Type fEpsilon) const
218{
219 PL_NAN_ASSERT(this);
220
221 return (plMath::IsZero(x, fEpsilon) && plMath::IsZero(y, fEpsilon) && plMath::IsZero(z, fEpsilon) && plMath::IsZero(w, fEpsilon));
222}
223
224template <typename Type>
226{
227 if (plMath::IsNaN(x))
228 return true;
229 if (plMath::IsNaN(y))
230 return true;
231 if (plMath::IsNaN(z))
232 return true;
233 if (plMath::IsNaN(w))
234 return true;
235
236 return false;
237}
238
239template <typename Type>
241{
242 if (!plMath::IsFinite(x))
243 return false;
244 if (!plMath::IsFinite(y))
245 return false;
246 if (!plMath::IsFinite(z))
247 return false;
248 if (!plMath::IsFinite(w))
249 return false;
250
251 return true;
252}
253
254template <typename Type>
256{
257 PL_NAN_ASSERT(this);
258
259 return plVec4Template<Type>(-x, -y, -z, -w);
260}
261
262template <typename Type>
264{
265 x += vCc.x;
266 y += vCc.y;
267 z += vCc.z;
268 w += vCc.w;
269
270 PL_NAN_ASSERT(this);
271}
272
273template <typename Type>
275{
276 x -= vCc.x;
277 y -= vCc.y;
278 z -= vCc.z;
279 w -= vCc.w;
280
281 PL_NAN_ASSERT(this);
282}
283
284template <typename Type>
285PL_FORCE_INLINE void plVec4Template<Type>::operator*=(Type f)
286{
287 x *= f;
288 y *= f;
289 z *= f;
290 w *= f;
291
292 PL_NAN_ASSERT(this);
293}
294
295template <typename Type>
296PL_FORCE_INLINE void plVec4Template<Type>::operator/=(Type f)
297{
298 if constexpr (std::is_floating_point_v<Type>)
299 {
300 const Type f_inv = plMath::Invert(f);
301 x *= f_inv;
302 y *= f_inv;
303 z *= f_inv;
304 w *= f_inv;
305 }
306 else
307 {
308 x /= f;
309 y /= f;
310 z /= f;
311 w /= f;
312 }
313
314 PL_NAN_ASSERT(this);
315}
316
317template <typename Type>
318PL_FORCE_INLINE Type plVec4Template<Type>::Dot(const plVec4Template<Type>& rhs) const
319{
320 PL_NAN_ASSERT(this);
321 PL_NAN_ASSERT(&rhs);
322
323 return ((x * rhs.x) + (y * rhs.y) + (z * rhs.z) + (w * rhs.w));
324}
325
326template <typename Type>
328{
329 PL_NAN_ASSERT(this);
330 PL_NAN_ASSERT(&rhs);
331
332 return plVec4Template<Type>(plMath::Min(x, rhs.x), plMath::Min(y, rhs.y), plMath::Min(z, rhs.z), plMath::Min(w, rhs.w));
333}
334
335template <typename Type>
337{
338 PL_NAN_ASSERT(this);
339 PL_NAN_ASSERT(&rhs);
340
341 return plVec4Template<Type>(plMath::Max(x, rhs.x), plMath::Max(y, rhs.y), plMath::Max(z, rhs.z), plMath::Max(w, rhs.w));
342}
343
344template <typename Type>
346{
347 PL_NAN_ASSERT(this);
348 PL_NAN_ASSERT(&vLow);
349 PL_NAN_ASSERT(&vHigh);
350
351 return plVec4Template<Type>(plMath::Clamp(x, vLow.x, vHigh.x), plMath::Clamp(y, vLow.y, vHigh.y), plMath::Clamp(z, vLow.z, vHigh.z), plMath::Clamp(w, vLow.w, vHigh.w));
352}
353
354template <typename Type>
356{
357 PL_NAN_ASSERT(this);
358 PL_NAN_ASSERT(&rhs);
359
360 return plVec4Template<Type>(x * rhs.x, y * rhs.y, z * rhs.z, w * rhs.w);
361}
362
363PL_MSVC_ANALYSIS_WARNING_PUSH
364PL_MSVC_ANALYSIS_WARNING_DISABLE(4723)
365template <typename Type>
366inline const plVec4Template<Type> plVec4Template<Type>::CompDiv(const plVec4Template<Type>& rhs) const
367{
368 PL_NAN_ASSERT(this);
369 PL_NAN_ASSERT(&rhs);
370
371 return plVec4Template<Type>(x / rhs.x, y / rhs.y, z / rhs.z, w / rhs.w);
372}
373PL_MSVC_ANALYSIS_WARNING_POP
374
375template <typename Type>
377{
378 PL_NAN_ASSERT(this);
379
381}
382
383template <typename Type>
384PL_FORCE_INLINE const plVec4Template<Type> operator+(const plVec4Template<Type>& v1, const plVec4Template<Type>& v2)
385{
386 PL_NAN_ASSERT(&v1);
387 PL_NAN_ASSERT(&v2);
388
389 return plVec4Template<Type>(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z, v1.w + v2.w);
390}
391
392template <typename Type>
393PL_FORCE_INLINE const plVec4Template<Type> operator-(const plVec4Template<Type>& v1, const plVec4Template<Type>& v2)
394{
395 PL_NAN_ASSERT(&v1);
396 PL_NAN_ASSERT(&v2);
397
398 return plVec4Template<Type>(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z, v1.w - v2.w);
399}
400
401template <typename Type>
402PL_FORCE_INLINE const plVec4Template<Type> operator*(Type f, const plVec4Template<Type>& v)
403{
404 PL_NAN_ASSERT(&v);
405
406 return plVec4Template<Type>(v.x * f, v.y * f, v.z * f, v.w * f);
407}
408
409template <typename Type>
410PL_FORCE_INLINE const plVec4Template<Type> operator*(const plVec4Template<Type>& v, Type f)
411{
412 PL_NAN_ASSERT(&v);
413
414 return plVec4Template<Type>(v.x * f, v.y * f, v.z * f, v.w * f);
415}
416
417template <typename Type>
418PL_FORCE_INLINE const plVec4Template<Type> operator/(const plVec4Template<Type>& v, Type f)
419{
420 PL_NAN_ASSERT(&v);
421
422 if constexpr (std::is_floating_point_v<Type>)
423 {
424 // multiplication is much faster than division
425 const Type f_inv = plMath::Invert(f);
426 return plVec4Template<Type>(v.x * f_inv, v.y * f_inv, v.z * f_inv, v.w * f_inv);
427 }
428 else
429 {
430 return plVec4Template<Type>(v.x / f, v.y / f, v.z / f, v.w / f);
431 }
432}
433
434template <typename Type>
436{
437 PL_NAN_ASSERT(this);
438 PL_NAN_ASSERT(&rhs);
439
440 return ((x == rhs.x) && (y == rhs.y) && (z == rhs.z) && (w == rhs.w));
441}
442
443template <typename Type>
444inline bool plVec4Template<Type>::IsEqual(const plVec4Template<Type>& rhs, Type fEpsilon) const
445{
446 PL_NAN_ASSERT(this);
447 PL_NAN_ASSERT(&rhs);
448
449 return (plMath::IsEqual(x, rhs.x, fEpsilon) && plMath::IsEqual(y, rhs.y, fEpsilon) && plMath::IsEqual(z, rhs.z, fEpsilon) && plMath::IsEqual(w, rhs.w, fEpsilon));
450}
451
452template <typename Type>
453PL_ALWAYS_INLINE bool operator==(const plVec4Template<Type>& v1, const plVec4Template<Type>& v2)
454{
455 return v1.IsIdentical(v2);
456}
457
458template <typename Type>
459PL_ALWAYS_INLINE bool operator!=(const plVec4Template<Type>& v1, const plVec4Template<Type>& v2)
460{
461 return !v1.IsIdentical(v2);
462}
463
464template <typename Type>
465PL_FORCE_INLINE bool operator<(const plVec4Template<Type>& v1, const plVec4Template<Type>& v2)
466{
467 PL_NAN_ASSERT(&v1);
468 PL_NAN_ASSERT(&v2);
469
470 if (v1.x < v2.x)
471 return true;
472 if (v1.x > v2.x)
473 return false;
474 if (v1.y < v2.y)
475 return true;
476 if (v1.y > v2.y)
477 return false;
478 if (v1.z < v2.z)
479 return true;
480 if (v1.z > v2.z)
481 return false;
482
483 return (v1.w < v2.w);
484}
A 2-component vector class.
Definition Vec2.h:14
const plVec3Template< Type > GetAsVec3(Type z) const
Returns an plVec3Template with x,y from this vector and z set by the parameter.
Definition Vec4_inl.h:10
const plVec4Template< Type > GetAsVec4(Type z, Type w) const
Returns an plVec4Template with x,y from this vector and z and w set by the parameters.
Definition Vec4_inl.h:18
A 3-component vector class.
Definition Vec3.h:9
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 > GetAsPositionVec4() const
Returns an plVec4Template with x,y,z from this vector and w set 1.
Definition Vec4_inl.h:43
const plVec4Template< Type > GetAsDirectionVec4() const
Returns an plVec4Template with x,y,z from this vector and w set 0.
Definition Vec4_inl.h:52
const plVec2Template< Type > GetAsVec2() const
Returns an plVec2Template with x and y from this vector.
Definition Vec4_inl.h:26
A 4-component vector class.
Definition Vec4.h:9
PL_DECLARE_IF_FLOAT_TYPE bool IsNormalized(Type fEpsilon=plMath::HugeEpsilon< Type >()) const
Returns, whether the squared length of this vector is between 0.999f and 1.001f.
Definition Vec4_inl.h:202
PL_DECLARE_IF_FLOAT_TYPE plResult NormalizeIfNotZero(const plVec4Template< Type > &vFallback=plVec4Template< Type >(1, 0, 0, 0), Type fEpsilon=plMath::SmallEpsilon< Type >())
Tries to normalize this vector. If the vector is too close to zero, PL_FAILURE is returned and the ve...
Definition Vec4_inl.h:182
plVec4Template()
Default-constructed vector is uninitialized (for speed)
Definition Vec4_inl.h:63
const plVec4Template< Type > CompMin(const plVec4Template< Type > &rhs) const
Returns the component-wise minimum of *this and rhs.
Definition Vec4_inl.h:327
bool IsZero() const
Returns, whether this vector is (0, 0, 0, 0).
Definition Vec4_inl.h:209
bool IsEqual(const plVec4Template< Type > &rhs, Type fEpsilon) const
Equality Check with epsilon.
Definition Vec4_inl.h:444
void SetZero()
Sets the vector to all zero.
Definition Vec4_inl.h:139
PL_DECLARE_IF_FLOAT_TYPE Type GetLengthAndNormalize()
Normalizes this vector and returns its previous length in one operation. More efficient than calling ...
Definition Vec4_inl.h:159
const plVec3Template< Type > GetAsVec3() const
Returns an plVec3Template with x,y and z from this vector.
Definition Vec4_inl.h:112
void operator-=(const plVec4Template< Type > &vCc)
Subtracts cc component-wise from this vector.
Definition Vec4_inl.h:274
bool IsNaN() const
Returns true, if any of x, y, z or w is NaN.
Definition Vec4_inl.h:225
const plVec4Template< Type > CompClamp(const plVec4Template< Type > &vLow, const plVec4Template< Type > &vHigh) const
Returns the component-wise clamped value of *this between low and high.
Definition Vec4_inl.h:345
PL_DECLARE_IF_FLOAT_TYPE void Normalize()
Normalizes this vector.
Definition Vec4_inl.h:176
const plVec4Template< Type > operator-() const
Returns the negation of this vector.
Definition Vec4_inl.h:255
void operator/=(Type f)
Divides all components of this vector by f.
Definition Vec4_inl.h:296
const plVec4Template< Type > Abs() const
brief Returns the component-wise absolute of *this.
Definition Vec4_inl.h:376
PL_DECLARE_IF_FLOAT_TYPE const plVec4Template< Type > GetNormalized() const
Returns a normalized version of this vector, leaves the vector itself unchanged.
Definition Vec4_inl.h:167
Type Dot(const plVec4Template< Type > &rhs) const
Returns the dot-product of the two vectors (commutative, order does not matter).
Definition Vec4_inl.h:318
void operator*=(Type f)
Multiplies all components of this vector with f.
Definition Vec4_inl.h:285
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
void operator+=(const plVec4Template< Type > &vCc)
Adds cc component-wise to this vector.
Definition Vec4_inl.h:263
bool IsIdentical(const plVec4Template< Type > &rhs) const
Equality Check (bitwise).
Definition Vec4_inl.h:435
const plVec4Template< Type > CompMax(const plVec4Template< Type > &rhs) const
Returns the component-wise maximum of *this and rhs.
Definition Vec4_inl.h:336
const plVec2Template< Type > GetAsVec2() const
Returns an plVec2Template with x and y from this vector.
Definition Vec4_inl.h:103
bool IsValid() const
Checks that all components are finite numbers.
Definition Vec4_inl.h:240
Type GetLengthSquared() const
Returns the squared length. Faster, since no square-root is taken. Useful, if one only wants to compa...
Definition Vec4_inl.h:151
PL_DECLARE_IF_FLOAT_TYPE Type GetLength() const
Returns the length of the vector.
Definition Vec4_inl.h:145
constexpr PL_ALWAYS_INLINE T Min(T f1, T f2)
Returns the smaller value, f1 or f2.
Definition Math_inl.h:27
constexpr Type Invert(Type f)
Returns 1 / f.
Definition Math_inl.h:63
constexpr PL_ALWAYS_INLINE T Clamp(T value, T min_val, T max_val)
Clamps "value" to the range [min; max]. Returns "value", if it is inside the range already.
Definition Math_inl.h:51
constexpr TYPE NaN()
Returns the value for NaN as the template type. Returns zero, if the type does not support NaN.
Definition Constants_inl.h:58
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
constexpr bool IsEqual(Type lhs, Type rhs, Type fEpsilon)
Checks, whether fValue is in the range [fDesired - fMaxImprecision; fDesired + fMaxImprecision].
Definition Math_inl.h:276
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
Default enum for returning failure or success, instead of using a bool.
Definition Types.h:54