Plasma Engine  2.0
Loading...
Searching...
No Matches
Vec2_inl.h
1#pragma once
2
3template <typename Type>
5{
6#if PL_ENABLED(PL_MATH_CHECK_FOR_NAN)
7 // Initialize all data to NaN in debug mode to find problems with uninitialized data easier.
8 const Type TypeNaN = plMath::NaN<Type>();
9 x = TypeNaN;
10 y = TypeNaN;
11#endif
12}
13
14template <typename Type>
15PL_ALWAYS_INLINE plVec2Template<Type>::plVec2Template(Type x, Type y)
16 : x(x)
17 , y(y)
18{
19}
20
21template <typename Type>
23 : x(v)
24 , y(v)
25{
26}
27
28template <typename Type>
29PL_ALWAYS_INLINE void plVec2Template<Type>::Set(Type xy)
31 x = xy;
32 y = xy;
34
35template <typename Type>
36PL_ALWAYS_INLINE void plVec2Template<Type>::Set(Type inX, Type inY)
37{
38 x = inX;
39 y = inY;
40}
41
42template <typename Type>
43PL_ALWAYS_INLINE void plVec2Template<Type>::SetZero()
44{
45 x = y = 0;
46}
47
48template <typename Type>
49PL_IMPLEMENT_IF_FLOAT_TYPE PL_ALWAYS_INLINE Type plVec2Template<Type>::GetLength() const
50{
51 return (plMath::Sqrt(GetLengthSquared()));
52}
53
54template <typename Type>
55PL_IMPLEMENT_IF_FLOAT_TYPE plResult plVec2Template<Type>::SetLength(Type fNewLength, Type fEpsilon /* = plMath::DefaultEpsilon<Type>() */)
56{
57 if (NormalizeIfNotZero(plVec2Template<Type>::MakeZero(), fEpsilon) == PL_FAILURE)
58 return PL_FAILURE;
59
60 *this *= fNewLength;
61 return PL_SUCCESS;
62}
63
64template <typename Type>
65PL_ALWAYS_INLINE Type plVec2Template<Type>::GetLengthSquared() const
66{
67 return (x * x + y * y);
68}
69
70template <typename Type>
71PL_IMPLEMENT_IF_FLOAT_TYPE PL_FORCE_INLINE Type plVec2Template<Type>::GetLengthAndNormalize()
72{
73 const Type fLength = GetLength();
74 *this /= fLength;
75 return fLength;
77
78template <typename Type>
79PL_IMPLEMENT_IF_FLOAT_TYPE PL_FORCE_INLINE const plVec2Template<Type> plVec2Template<Type>::GetNormalized() const
80{
81 const Type fLen = GetLength();
83 const Type fLengthInv = plMath::Invert(fLen);
84 return plVec2Template<Type>(x * fLengthInv, y * fLengthInv);
85}
86
87template <typename Type>
88PL_IMPLEMENT_IF_FLOAT_TYPE PL_ALWAYS_INLINE void plVec2Template<Type>::Normalize()
89{
90 *this /= GetLength();
91}
92
93template <typename Type>
94PL_IMPLEMENT_IF_FLOAT_TYPE inline plResult plVec2Template<Type>::NormalizeIfNotZero(const plVec2Template<Type>& vFallback, Type fEpsilon)
95{
96 PL_NAN_ASSERT(&vFallback);
98 const Type fLength = GetLength();
99
100 if (!plMath::IsFinite(fLength) || plMath::IsZero(fLength, fEpsilon))
101 {
102 *this = vFallback;
103 return PL_FAILURE;
104 }
105
106 *this /= fLength;
107 return PL_SUCCESS;
108}
109
113template <typename Type>
114PL_IMPLEMENT_IF_FLOAT_TYPE inline bool plVec2Template<Type>::IsNormalized(Type fEpsilon /* = plMath::HugeEpsilon<Type>() */) const
116 const Type t = GetLengthSquared();
117 return plMath::IsEqual(t, (Type)(1), fEpsilon);
119
120template <typename Type>
122{
123 return (x == 0 && y == 0);
124}
126template <typename Type>
127inline bool plVec2Template<Type>::IsZero(Type fEpsilon) const
129 PL_NAN_ASSERT(this);
130
131 return (plMath::IsZero(x, fEpsilon) && plMath::IsZero(y, fEpsilon));
132}
133
134template <typename Type>
136{
137 if (plMath::IsNaN(x))
138 return true;
139 if (plMath::IsNaN(y))
140 return true;
141
142 return false;
144
145template <typename Type>
147{
148 if (!plMath::IsFinite(x))
149 return false;
150 if (!plMath::IsFinite(y))
151 return false;
153 return true;
154}
156template <typename Type>
158{
159 PL_NAN_ASSERT(this);
160
161 return plVec2Template<Type>(-x, -y);
162}
163
164template <typename Type>
166{
167 x += rhs.x;
168 y += rhs.y;
169
170 PL_NAN_ASSERT(this);
171}
172
173template <typename Type>
175{
176 x -= rhs.x;
177 y -= rhs.y;
178
179 PL_NAN_ASSERT(this);
180}
181
182template <typename Type>
183PL_FORCE_INLINE void plVec2Template<Type>::operator*=(Type f)
184{
185 x *= f;
186 y *= f;
187
188 PL_NAN_ASSERT(this);
189}
190
191template <typename Type>
192PL_FORCE_INLINE void plVec2Template<Type>::operator/=(Type f)
193{
194 if constexpr (std::is_floating_point_v<Type>)
196 const Type f_inv = plMath::Invert(f);
197 x *= f_inv;
198 y *= f_inv;
200 else
201 {
202 x /= f;
203 y /= f;
204 }
205
206 PL_NAN_ASSERT(this);
207}
208
209template <typename Type>
210PL_IMPLEMENT_IF_FLOAT_TYPE inline void plVec2Template<Type>::MakeOrthogonalTo(const plVec2Template<Type>& vNormal)
211{
212 PL_ASSERT_DEBUG(vNormal.IsNormalized(), "The normal must be normalized.");
213
214 const Type fDot = this->Dot(vNormal);
215 *this -= fDot * vNormal;
216}
217
218template <typename Type>
220{
221 PL_NAN_ASSERT(this);
222 PL_ASSERT_DEBUG(!IsZero(plMath::SmallEpsilon<Type>()), "The vector must not be zero to be able to compute an orthogonal vector.");
223
224 return plVec2Template<Type>(-y, x);
225}
226
227template <typename Type>
228PL_IMPLEMENT_IF_FLOAT_TYPE inline const plVec2Template<Type> plVec2Template<Type>::GetReflectedVector(const plVec2Template<Type>& vNormal) const
229{
230 PL_ASSERT_DEBUG(vNormal.IsNormalized(), "vNormal must be normalized.");
231
232 return ((*this) - (2 * this->Dot(vNormal) * vNormal));
233}
234
235template <typename Type>
236PL_FORCE_INLINE Type plVec2Template<Type>::Dot(const plVec2Template<Type>& rhs) const
237{
238 PL_NAN_ASSERT(this);
239 PL_NAN_ASSERT(&rhs);
240
241 return ((x * rhs.x) + (y * rhs.y));
242}
243
244template <typename Type>
246{
247 PL_ASSERT_DEBUG(this->IsNormalized(), "This vector must be normalized.");
248 PL_ASSERT_DEBUG(rhs.IsNormalized(), "The other vector must be normalized.");
249
250 return plMath::ACos(static_cast<float>(plMath::Clamp<Type>(this->Dot(rhs), (Type)-1, (Type)1)));
251}
252
253template <typename Type>
255{
256 PL_NAN_ASSERT(this);
257 PL_NAN_ASSERT(&rhs);
258
259 return plVec2Template<Type>(plMath::Min(x, rhs.x), plMath::Min(y, rhs.y));
260}
261
262template <typename Type>
264{
265 PL_NAN_ASSERT(this);
266 PL_NAN_ASSERT(&rhs);
267
268 return plVec2Template<Type>(plMath::Max(x, rhs.x), plMath::Max(y, rhs.y));
269}
270
271template <typename Type>
273{
274 PL_NAN_ASSERT(this);
275 PL_NAN_ASSERT(&vLow);
276 PL_NAN_ASSERT(&vHigh);
277
278 return plVec2Template<Type>(plMath::Clamp(x, vLow.x, vHigh.x), plMath::Clamp(y, vLow.y, vHigh.y));
279}
280
281template <typename Type>
283{
284 PL_NAN_ASSERT(this);
285 PL_NAN_ASSERT(&rhs);
286
287 return plVec2Template<Type>(x * rhs.x, y * rhs.y);
288}
289
290template <typename Type>
292{
293 PL_NAN_ASSERT(this);
294 PL_NAN_ASSERT(&rhs);
295
296 return plVec2Template<Type>(x / rhs.x, y / rhs.y);
297}
298
299template <typename Type>
301{
302 PL_NAN_ASSERT(this);
303
305}
306
307template <typename Type>
308PL_FORCE_INLINE const plVec2Template<Type> operator+(const plVec2Template<Type>& v1, const plVec2Template<Type>& v2)
309{
310 PL_NAN_ASSERT(&v1);
311 PL_NAN_ASSERT(&v2);
312
313 return plVec2Template<Type>(v1.x + v2.x, v1.y + v2.y);
314}
315
316template <typename Type>
317PL_FORCE_INLINE const plVec2Template<Type> operator-(const plVec2Template<Type>& v1, const plVec2Template<Type>& v2)
318{
319 PL_NAN_ASSERT(&v1);
320 PL_NAN_ASSERT(&v2);
321
322 return plVec2Template<Type>(v1.x - v2.x, v1.y - v2.y);
323}
324
325template <typename Type>
326PL_FORCE_INLINE const plVec2Template<Type> operator*(Type f, const plVec2Template<Type>& v)
327{
328 PL_NAN_ASSERT(&v);
329
330 return plVec2Template<Type>(v.x * f, v.y * f);
331}
332
333template <typename Type>
334PL_FORCE_INLINE const plVec2Template<Type> operator*(const plVec2Template<Type>& v, Type f)
335{
336 PL_NAN_ASSERT(&v);
337
338 return plVec2Template<Type>(v.x * f, v.y * f);
339}
340
341template <typename Type>
342PL_FORCE_INLINE const plVec2Template<Type> operator/(const plVec2Template<Type>& v, Type f)
343{
344 PL_NAN_ASSERT(&v);
345
346 if constexpr (std::is_floating_point_v<Type>)
347 {
348 // multiplication is much faster than division
349 const Type f_inv = plMath::Invert(f);
350 return plVec2Template<Type>(v.x * f_inv, v.y * f_inv);
351 }
352 else
353 {
354 return plVec2Template<Type>(v.x / f, v.y / f);
355 }
356}
357
358template <typename Type>
360{
361 PL_NAN_ASSERT(this);
362 PL_NAN_ASSERT(&rhs);
363
364 return ((x == rhs.x) && (y == rhs.y));
365}
366
367template <typename Type>
368inline bool plVec2Template<Type>::IsEqual(const plVec2Template<Type>& rhs, Type fEpsilon) const
369{
370 PL_NAN_ASSERT(this);
371 PL_NAN_ASSERT(&rhs);
372
373 return (plMath::IsEqual(x, rhs.x, fEpsilon) && plMath::IsEqual(y, rhs.y, fEpsilon));
374}
375
376template <typename Type>
377PL_FORCE_INLINE bool operator==(const plVec2Template<Type>& v1, const plVec2Template<Type>& v2)
378{
379 return v1.IsIdentical(v2);
380}
381
382template <typename Type>
383PL_FORCE_INLINE bool operator!=(const plVec2Template<Type>& v1, const plVec2Template<Type>& v2)
384{
385 return !v1.IsIdentical(v2);
386}
387
388template <typename Type>
389PL_FORCE_INLINE bool operator<(const plVec2Template<Type>& v1, const plVec2Template<Type>& v2)
390{
391 PL_NAN_ASSERT(&v1);
392 PL_NAN_ASSERT(&v2);
393
394 if (v1.x < v2.x)
395 return true;
396 if (v1.x > v2.x)
397 return false;
398
399 return (v1.y < v2.y);
400}
Float wrapper struct for a safe usage and conversions of angles.
Definition Angle.h:10
A 2-component vector class.
Definition Vec2.h:14
plAngle GetAngleBetween(const plVec2Template< Type > &rhs) const
Returns the positive angle between *this and rhs.
Definition Vec2_inl.h:245
void operator-=(const plVec2Template< Type > &vCc)
Subtracts cc component-wise from this vector.
Definition Vec2_inl.h:174
PL_DECLARE_IF_FLOAT_TYPE Type GetLength() const
Returns the length of the vector.
Definition Vec2_inl.h:49
void operator+=(const plVec2Template< Type > &vCc)
Adds cc component-wise to this vector.
Definition Vec2_inl.h:165
void Set(Type xy)
Sets all components to this value.
Definition Vec2_inl.h:29
const plVec2Template< Type > GetOrthogonalVector() const
Returns some arbitrary vector orthogonal to this one. The vector is NOT normalized.
Definition Vec2_inl.h:219
PL_DECLARE_IF_FLOAT_TYPE void MakeOrthogonalTo(const plVec2Template< Type > &vNormal)
Modifies this direction vector to be orthogonal to the given (normalized) direction vector....
Definition Vec2_inl.h:210
const plVec2Template< Type > CompClamp(const plVec2Template< Type > &vLow, const plVec2Template< Type > &vHigh) const
Returns the component-wise clamped value of *this between low and high.
Definition Vec2_inl.h:272
void SetZero()
Sets the vector to all zero.
Definition Vec2_inl.h:43
const plVec2Template< Type > CompMul(const plVec2Template< Type > &rhs) const
Returns the component-wise multiplication of *this and rhs.
Definition Vec2_inl.h:282
bool IsValid() const
Checks that all components are finite numbers.
Definition Vec2_inl.h:146
PL_DECLARE_IF_FLOAT_TYPE const plVec2Template< Type > GetNormalized() const
Returns a normalized version of this vector, leaves the vector itself unchanged.
Definition Vec2_inl.h:79
void operator/=(Type f)
Divides all components of this vector by f.
Definition Vec2_inl.h:192
PL_DECLARE_IF_FLOAT_TYPE void Normalize()
Normalizes this vector.
Definition Vec2_inl.h:88
PL_DECLARE_IF_FLOAT_TYPE plResult NormalizeIfNotZero(const plVec2Template< Type > &vFallback=plVec2Template< Type >(1, 0), Type fEpsilon=plMath::DefaultEpsilon< Type >())
Tries to normalize this vector. If the vector is too close to zero, PL_FAILURE is returned and the ve...
Definition Vec2_inl.h:94
PL_DECLARE_IF_FLOAT_TYPE const plVec2Template< Type > GetReflectedVector(const plVec2Template< Type > &vNormal) const
Returns this vector reflected at vNormal.
Definition Vec2_inl.h:228
bool IsIdentical(const plVec2Template< Type > &rhs) const
Equality Check (bitwise)
Definition Vec2_inl.h:359
bool IsZero() const
Returns, whether this vector is (0, 0).
Definition Vec2_inl.h:121
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 Vec2_inl.h:114
const plVec2Template< Type > CompDiv(const plVec2Template< Type > &rhs) const
Returns the component-wise division of *this and rhs.
Definition Vec2_inl.h:291
Type Dot(const plVec2Template< Type > &rhs) const
Returns the Dot-product of the two vectors (commutative, order does not matter)
Definition Vec2_inl.h:236
bool IsNaN() const
Returns true, if any of x or y is NaN.
Definition Vec2_inl.h:135
const plVec2Template< Type > CompMax(const plVec2Template< Type > &rhs) const
Returns the component-wise maximum of *this and rhs.
Definition Vec2_inl.h:263
plVec2Template()
default-constructed vector is uninitialized (for speed)
Definition Vec2_inl.h:4
PL_DECLARE_IF_FLOAT_TYPE Type GetLengthAndNormalize()
Normalizes this vector and returns its previous length in one operation. More efficient than calling ...
Definition Vec2_inl.h:71
PL_DECLARE_IF_FLOAT_TYPE plResult SetLength(Type fNewLength, Type fEpsilon=plMath::DefaultEpsilon< Type >())
Tries to rescale the vector to the given length. If the vector is too close to zero,...
Definition Vec2_inl.h:55
Type GetLengthSquared() const
Returns the squared length. Faster, since no square-root is taken. Useful, if one only wants to compa...
Definition Vec2_inl.h:65
const plVec2Template< Type > Abs() const
brief Returns the component-wise absolute of *this.
Definition Vec2_inl.h:300
void operator*=(Type f)
Multiplies all components of this vector with f.
Definition Vec2_inl.h:183
bool IsEqual(const plVec2Template< Type > &rhs, Type fEpsilon) const
Equality Check with epsilon.
Definition Vec2_inl.h:368
const plVec2Template< Type > CompMin(const plVec2Template< Type > &rhs) const
Returns the component-wise minimum of *this and rhs.
Definition Vec2_inl.h:254
const plVec2Template< Type > operator-() const
Returns the negation of this vector.
Definition Vec2_inl.h:157
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 plAngle ACos(float f)
Returns the arcus cosinus of f.
Definition MathFloat_inl.h:82
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