Plasma Engine  2.0
Loading...
Searching...
No Matches
Mat3_inl.h
1#pragma once
2
3#include <Foundation/Memory/MemoryUtils.h>
4
5template <typename Type>
7{
8#if PL_ENABLED(PL_MATH_CHECK_FOR_NAN)
9 // Initialize all data to NaN in debug mode to find problems with uninitialized data easier.
10 const Type TypeNaN = plMath::NaN<Type>();
11 for (plUInt32 i = 0; i < 9; ++i)
12 m_fElementsCM[i] = TypeNaN;
13#endif
14}
15
16template <typename Type>
17void plMat3Template<Type>::GetAsArray(Type* out_pData, plMatrixLayout::Enum layout) const
18{
19 PL_NAN_ASSERT(this);
20
21 if (layout == plMatrixLayout::ColumnMajor)
22 {
23 plMemoryUtils::Copy(out_pData, m_fElementsCM, 9);
24 }
25 else
26 {
27 for (int i = 0; i < 3; ++i)
28 {
29 out_pData[i * 3 + 0] = Element(0, i);
30 out_pData[i * 3 + 1] = Element(1, i);
31 out_pData[i * 3 + 2] = Element(2, i);
32 }
33 }
34}
35
36template <typename Type>
38{
40
41 for (plUInt32 i = 0; i < PL_ARRAY_SIZE(res.m_fElementsCM); ++i)
42 res.m_fElementsCM[i] = 0.0f;
43
44 return res;
46
47template <typename Type>
49{
51 res.m_fElementsCM[0] = 1.0f;
52 res.m_fElementsCM[1] = 0.0f;
53 res.m_fElementsCM[2] = 0.0f;
54 res.m_fElementsCM[3] = 0.0f;
55 res.m_fElementsCM[4] = 1.0f;
56 res.m_fElementsCM[5] = 0.0f;
57 res.m_fElementsCM[6] = 0.0f;
58 res.m_fElementsCM[7] = 0.0f;
59 res.m_fElementsCM[8] = 1.0f;
60 return res;
61}
62
63template <typename Type>
65{
67 for (int i = 0; i < 3; ++i)
68 {
69 res.Element(0, i) = pData[i * 3 + 0];
70 res.Element(1, i) = pData[i * 3 + 1];
71 res.Element(2, i) = pData[i * 3 + 2];
72 }
73 return res;
74}
75
76template <typename Type>
78{
81 return res;
82}
83
84template <typename Type>
85plMat3Template<Type> plMat3Template<Type>::MakeFromValues(Type c1r1, Type c2r1, Type c3r1, Type c1r2, Type c2r2, Type c3r2, Type c1r3, Type c2r3, Type c3r3)
86{
88 res.Element(0, 0) = c1r1;
89 res.Element(1, 0) = c2r1;
90 res.Element(2, 0) = c3r1;
91 res.Element(0, 1) = c1r2;
92 res.Element(1, 1) = c2r2;
93 res.Element(2, 1) = c3r2;
94 res.Element(0, 2) = c1r3;
95 res.Element(1, 2) = c2r3;
96 res.Element(2, 2) = c3r3;
97 return res;
98}
100template <typename Type>
104 res.Element(0, 0) = vScale.x;
105 res.Element(1, 0) = 0;
106 res.Element(2, 0) = 0;
107 res.Element(0, 1) = 0;
108 res.Element(1, 1) = vScale.y;
109 res.Element(2, 1) = 0;
110 res.Element(0, 2) = 0;
111 res.Element(1, 2) = 0;
112 res.Element(2, 2) = vScale.z;
113 return res;
114}
115
116template <typename Type>
118{
119 const Type fSin = plMath::Sin(angle);
120 const Type fCos = plMath::Cos(angle);
121
122 return plMat3Template<Type>::MakeFromValues(1.0f, 0.0f, 0.0f, 0.0f, fCos, -fSin, 0.0f, fSin, fCos);
123}
124
125template <typename Type>
127{
128 const Type fSin = plMath::Sin(angle);
129 const Type fCos = plMath::Cos(angle);
130
131 return plMat3Template<Type>::MakeFromValues(fCos, 0.0f, fSin, 0.0f, 1.0f, 0.0f, -fSin, 0.0f, fCos);
132}
133
134template <typename Type>
136{
137 const Type fSin = plMath::Sin(angle);
138 const Type fCos = plMath::Cos(angle);
139
140 return plMat3Template<Type>::MakeFromValues(fCos, -fSin, 0.0f, fSin, fCos, 0.0f, 0.0f, 0.0f, 1.0f);
141}
142
143template <typename Type>
145{
146 *this = MakeZero();
147}
148
149template <typename Type>
151{
152 *this = MakeIdentity();
153}
154
155template <typename Type>
157{
158 plMath::Swap(Element(0, 1), Element(1, 0));
159 plMath::Swap(Element(0, 2), Element(2, 0));
160 plMath::Swap(Element(1, 2), Element(2, 1));
161}
162
163template <typename Type>
168
169template <typename Type>
171{
172 plMat3Template<Type> Inverse = *this;
173 plResult res = Inverse.Invert(fEpsilon);
174 PL_ASSERT_DEBUG(res.Succeeded(), "Could not invert the given Mat3.");
175 PL_IGNORE_UNUSED(res);
176 return Inverse;
177}
178
179template <typename Type>
181{
182 PL_ASSERT_DEBUG(uiRow <= 2, "Invalid Row Index {0}", uiRow);
183
185 r.x = Element(0, uiRow);
186 r.y = Element(1, uiRow);
187 r.z = Element(2, uiRow);
188
189 PL_NAN_ASSERT(&r);
190 return r;
191}
192
193template <typename Type>
194void plMat3Template<Type>::SetRow(plUInt32 uiRow, const plVec3Template<Type>& vRow)
195{
196 PL_ASSERT_DEBUG(uiRow <= 2, "Invalid Row Index {0}", uiRow);
197
198 Element(0, uiRow) = vRow.x;
199 Element(1, uiRow) = vRow.y;
200 Element(2, uiRow) = vRow.z;
201}
202
203template <typename Type>
205{
206 PL_ASSERT_DEBUG(uiColumn <= 2, "Invalid Column Index {0}", uiColumn);
207
209 r.x = Element(uiColumn, 0);
210 r.y = Element(uiColumn, 1);
211 r.z = Element(uiColumn, 2);
212
213 PL_NAN_ASSERT(&r);
214 return r;
215}
216
217template <typename Type>
218void plMat3Template<Type>::SetColumn(plUInt32 uiColumn, const plVec3Template<Type>& vColumn)
219{
220 PL_ASSERT_DEBUG(uiColumn <= 2, "Invalid Column Index {0}", uiColumn);
221
222 Element(uiColumn, 0) = vColumn.x;
223 Element(uiColumn, 1) = vColumn.y;
224 Element(uiColumn, 2) = vColumn.z;
225}
226
227template <typename Type>
229{
230 PL_NAN_ASSERT(this);
231
232 return plVec3Template<Type>(Element(0, 0), Element(1, 1), Element(2, 2));
233}
234
235template <typename Type>
237{
238 Element(0, 0) = vDiag.x;
239 Element(1, 1) = vDiag.y;
240 Element(2, 2) = vDiag.z;
241}
242
243template <typename Type>
245{
247 r.x = Element(0, 0) * v.x + Element(1, 0) * v.y + Element(2, 0) * v.z;
248 r.y = Element(0, 1) * v.x + Element(1, 1) * v.y + Element(2, 1) * v.z;
249 r.z = Element(0, 2) * v.x + Element(1, 2) * v.y + Element(2, 2) * v.z;
250
251 PL_NAN_ASSERT(&r);
252 return r;
253}
254
255template <typename Type>
256PL_FORCE_INLINE void plMat3Template<Type>::operator*=(Type f)
257{
258 for (plInt32 i = 0; i < 9; ++i)
259 m_fElementsCM[i] *= f;
260
261 PL_NAN_ASSERT(this);
262}
263
264template <typename Type>
265PL_FORCE_INLINE void plMat3Template<Type>::operator/=(Type f)
266{
267 const Type fInv = plMath::Invert(f);
268
269 operator*=(fInv);
270}
271
272template <typename Type>
273const plMat3Template<Type> operator*(const plMat3Template<Type>& m1, const plMat3Template<Type>& m2)
274{
276 for (plInt32 i = 0; i < 3; ++i)
277 {
278 r.Element(0, i) = m1.Element(0, i) * m2.Element(0, 0) + m1.Element(1, i) * m2.Element(0, 1) + m1.Element(2, i) * m2.Element(0, 2);
279 r.Element(1, i) = m1.Element(0, i) * m2.Element(1, 0) + m1.Element(1, i) * m2.Element(1, 1) + m1.Element(2, i) * m2.Element(1, 2);
280 r.Element(2, i) = m1.Element(0, i) * m2.Element(2, 0) + m1.Element(1, i) * m2.Element(2, 1) + m1.Element(2, i) * m2.Element(2, 2);
281 }
282
283 PL_NAN_ASSERT(&r);
284 return r;
285}
286
287template <typename Type>
288PL_ALWAYS_INLINE const plVec3Template<Type> operator*(const plMat3Template<Type>& m, const plVec3Template<Type>& v)
289{
290 return m.TransformDirection(v);
291}
292
293
294
295// *** free functions ***
296
297template <typename Type>
298PL_ALWAYS_INLINE const plMat3Template<Type> operator*(Type f, const plMat3Template<Type>& m1)
299{
300 return operator*(m1, f);
301}
302
303template <typename Type>
304const plMat3Template<Type> operator*(const plMat3Template<Type>& m1, Type f)
305{
307
308 for (plUInt32 i = 0; i < 9; ++i)
309 r.m_fElementsCM[i] = m1.m_fElementsCM[i] * f;
310
311 PL_NAN_ASSERT(&r);
312
313 return r;
314}
315
316template <typename Type>
317PL_ALWAYS_INLINE const plMat3Template<Type> operator/(const plMat3Template<Type>& m1, Type f)
318{
319 return operator*(m1, plMath::Invert(f));
320}
321
322template <typename Type>
323const plMat3Template<Type> operator+(const plMat3Template<Type>& m1, const plMat3Template<Type>& m2)
324{
326
327 for (plUInt32 i = 0; i < 9; ++i)
328 r.m_fElementsCM[i] = m1.m_fElementsCM[i] + m2.m_fElementsCM[i];
329
330 PL_NAN_ASSERT(&r);
331
332 return r;
333}
334
335template <typename Type>
336const plMat3Template<Type> operator-(const plMat3Template<Type>& m1, const plMat3Template<Type>& m2)
337{
339
340 for (plUInt32 i = 0; i < 9; ++i)
341 r.m_fElementsCM[i] = m1.m_fElementsCM[i] - m2.m_fElementsCM[i];
342
343 PL_NAN_ASSERT(&r);
344
345 return r;
346}
347
348template <typename Type>
350{
351 PL_NAN_ASSERT(this);
352 PL_NAN_ASSERT(&rhs);
353
354 for (plUInt32 i = 0; i < 9; ++i)
355 {
356 if (m_fElementsCM[i] != rhs.m_fElementsCM[i])
357 return false;
358 }
359
360 return true;
361}
362
363template <typename Type>
364bool plMat3Template<Type>::IsEqual(const plMat3Template<Type>& rhs, Type fEpsilon) const
365{
366 PL_NAN_ASSERT(this);
367 PL_NAN_ASSERT(&rhs);
368
369 PL_ASSERT_DEBUG(fEpsilon >= 0.0f, "Epsilon may not be negative.");
370
371 for (plUInt32 i = 0; i < 9; ++i)
372 {
373 if (!plMath::IsEqual(m_fElementsCM[i], rhs.m_fElementsCM[i], fEpsilon))
374 return false;
375 }
376
377 return true;
378}
379
380template <typename Type>
381PL_ALWAYS_INLINE bool operator==(const plMat3Template<Type>& lhs, const plMat3Template<Type>& rhs)
382{
383 return lhs.IsIdentical(rhs);
384}
385
386template <typename Type>
387PL_ALWAYS_INLINE bool operator!=(const plMat3Template<Type>& lhs, const plMat3Template<Type>& rhs)
388{
389 return !lhs.IsIdentical(rhs);
390}
391
392template <typename Type>
393bool plMat3Template<Type>::IsZero(Type fEpsilon) const
394{
395 PL_NAN_ASSERT(this);
396
397 for (plUInt32 i = 0; i < 9; ++i)
398 {
399 if (!plMath::IsZero(m_fElementsCM[i], fEpsilon))
400 return false;
401 }
402
403 return true;
404}
405
406template <typename Type>
407bool plMat3Template<Type>::IsIdentity(Type fEpsilon) const
408{
409 PL_NAN_ASSERT(this);
410
411 if (!plMath::IsEqual(Element(0, 0), (Type)1, fEpsilon))
412 return false;
413 if (!plMath::IsEqual(Element(0, 1), (Type)0, fEpsilon))
414 return false;
415 if (!plMath::IsEqual(Element(0, 2), (Type)0, fEpsilon))
416 return false;
417
418 if (!plMath::IsEqual(Element(1, 0), (Type)0, fEpsilon))
419 return false;
420 if (!plMath::IsEqual(Element(1, 1), (Type)1, fEpsilon))
421 return false;
422 if (!plMath::IsEqual(Element(1, 2), (Type)0, fEpsilon))
423 return false;
424
425 if (!plMath::IsEqual(Element(2, 0), (Type)0, fEpsilon))
426 return false;
427 if (!plMath::IsEqual(Element(2, 1), (Type)0, fEpsilon))
428 return false;
429 if (!plMath::IsEqual(Element(2, 2), (Type)1, fEpsilon))
430 return false;
431
432 return true;
433}
434
435template <typename Type>
437{
438 for (plUInt32 i = 0; i < 9; ++i)
439 {
440 if (!plMath::IsFinite(m_fElementsCM[i]))
441 return false;
442 }
443
444 return true;
445}
446
447template <typename Type>
449{
450 for (plUInt32 i = 0; i < 9; ++i)
451 {
452 if (plMath::IsNaN(m_fElementsCM[i]))
453 return true;
454 }
455
456 return false;
457}
458
459template <typename Type>
461{
463
464 v.x = plVec3Template<Type>(Element(0, 0), Element(0, 1), Element(0, 2)).GetLength();
465 v.y = plVec3Template<Type>(Element(1, 0), Element(1, 1), Element(1, 2)).GetLength();
466 v.z = plVec3Template<Type>(Element(2, 0), Element(2, 1), Element(2, 2)).GetLength();
467
468 PL_NAN_ASSERT(&v);
469 return v;
470}
471
472template <typename Type>
473plResult plMat3Template<Type>::SetScalingFactors(const plVec3Template<Type>& vXYZ, Type fEpsilon /* = plMath::DefaultEpsilon<Type>() */)
474{
475 plVec3Template<Type> tx(Element(0, 0), Element(0, 1), Element(0, 2));
476 plVec3Template<Type> ty(Element(1, 0), Element(1, 1), Element(1, 2));
477 plVec3Template<Type> tz(Element(2, 0), Element(2, 1), Element(2, 2));
478
479 if (tx.SetLength(vXYZ.x, fEpsilon) == PL_FAILURE)
480 return PL_FAILURE;
481 if (ty.SetLength(vXYZ.y, fEpsilon) == PL_FAILURE)
482 return PL_FAILURE;
483 if (tz.SetLength(vXYZ.z, fEpsilon) == PL_FAILURE)
484 return PL_FAILURE;
485
486
487 Element(0, 0) = tx.x;
488 Element(0, 1) = tx.y;
489 Element(0, 2) = tx.z;
490 Element(1, 0) = ty.x;
491 Element(1, 1) = ty.y;
492 Element(1, 2) = ty.z;
493 Element(2, 0) = tz.x;
494 Element(2, 1) = tz.y;
495 Element(2, 2) = tz.z;
496
497 return PL_SUCCESS;
498}
499
500template <typename Type>
502{
503 // Using rule of Sarrus
504 Type fDeterminant = 0;
505 for (int i = 0; i < 3; i++)
506 {
507 fDeterminant += Element(i, 0) * Element((i + 1) % 3, 1) * Element((i + 2) % 3, 2);
508 fDeterminant -= Element(i, 2) * Element((i + 1) % 3, 1) * Element((i + 2) % 3, 0);
509 }
510 return fDeterminant;
511}
512
513#include <Foundation/Math/Implementation/AllClasses_inl.h>
Float wrapper struct for a safe usage and conversions of angles.
Definition Angle.h:10
A 3x3 component matrix class.
Definition Mat3.h:9
void SetDiagonal(const plVec3Template< Type > &vDiag)
Sets all 3 components on the diagonal of the matrix.
Definition Mat3_inl.h:236
bool IsZero(Type fEpsilon=plMath::DefaultEpsilon< Type >()) const
Checks whether all elements are zero.
Definition Mat3_inl.h:393
void SetZero()
Sets all elements to zero.
Definition Mat3_inl.h:144
plVec3Template< Type > GetRow(plUInt32 uiRow) const
Returns all 3 components of the i-th row.
Definition Mat3_inl.h:180
void SetColumn(plUInt32 uiColumn, const plVec3Template< Type > &vColumn)
Sets all 3 components of the i-th column.
Definition Mat3_inl.h:218
void Transpose()
Transposes this matrix.
Definition Mat3_inl.h:156
static plMat3Template< Type > MakeRotationX(plAngle angle)
Creates a matrix that is a rotation matrix around the X-axis.
Definition Mat3_inl.h:117
static plMat3Template< Type > MakeScaling(const plVec3Template< Type > &vScale)
Creates a matrix with all zero values, except along the diagonal, which is set to x,...
Definition Mat3_inl.h:101
plResult SetScalingFactors(const plVec3Template< Type > &vXYZ, Type fEpsilon=plMath::DefaultEpsilon< Type >())
Tries to set the three scaling factors in the matrix. Returns PL_FAILURE if the matrix columns cannot...
Definition Mat3_inl.h:473
static plMat3Template< Type > MakeFromRowMajorArray(const Type *const pData)
Creates a matrix from 9 values that are in row-major layout.
Definition Mat3_inl.h:64
plResult Invert(Type fEpsilon=plMath::SmallEpsilon< Type >())
Inverts this matrix. Return value indicates whether the matrix could be Inverted.
Definition AllClasses_inl.h:230
bool IsEqual(const plMat3Template< Type > &rhs, Type fEpsilon) const
Equality Check with epsilon.
Definition Mat3_inl.h:364
bool IsIdentical(const plMat3Template< Type > &rhs) const
Equality Check.
Definition Mat3_inl.h:349
static plMat3Template< Type > MakeRotationZ(plAngle angle)
Creates a matrix that is a rotation matrix around the Z-axis.
Definition Mat3_inl.h:135
plVec3Template< Type > GetDiagonal() const
Returns all 3 components on the diagonal of the matrix.
Definition Mat3_inl.h:228
void operator*=(Type f)
Component-wise multiplication (commutative)
Definition Mat3_inl.h:256
static plMat3Template< Type > MakeRotationY(plAngle angle)
Creates a matrix that is a rotation matrix around the Y-axis.
Definition Mat3_inl.h:126
const plMat3Template< Type > GetTranspose() const
Returns the transpose of this matrix.
Definition Mat3_inl.h:164
const plMat3Template< Type > GetInverse(Type fEpsilon=plMath::SmallEpsilon< Type >()) const
Returns the inverse of this matrix.
Definition Mat3_inl.h:170
void operator/=(Type f)
Component-wise division.
Definition Mat3_inl.h:265
plMat3Template()
Default Constructor DOES NOT INITIALIZE the matrix, at all.
Definition Mat3_inl.h:6
void SetIdentity()
Sets all elements to zero, except the diagonal, which is set to one.
Definition Mat3_inl.h:150
static plMat3Template< Type > MakeFromValues(Type c1r1, Type c2r1, Type c3r1, Type c1r2, Type c2r2, Type c3r2, Type c1r3, Type c2r3, Type c3r3)
Creates a matrix from 9 values. Naming is "column-n row-m".
Definition Mat3_inl.h:85
static plMat3Template< Type > MakeZero()
Returns a zero matrix.
Definition Mat3_inl.h:37
const plVec3Template< Type > TransformDirection(const plVec3Template< Type > &v) const
Matrix-vector multiplication, assuming the 4th component of the vector is zero. So,...
Definition Mat3_inl.h:244
static plMat3Template< Type > MakeIdentity()
Returns an identity matrix.
Definition Mat3_inl.h:48
bool IsIdentity(Type fEpsilon=plMath::DefaultEpsilon< Type >()) const
Checks whether this is an identity matrix.
Definition Mat3_inl.h:407
Type GetDeterminant() const
Computes the determinant of the matrix.
Definition Mat3_inl.h:501
void GetAsArray(Type *out_pData, plMatrixLayout::Enum layout) const
Copies the 9 values of this matrix into the given array. 'layout' defines whether the data should end...
Definition Mat3_inl.h:17
bool IsValid() const
Checks whether all components are finite numbers.
Definition Mat3_inl.h:436
Type m_fElementsCM[9]
The matrix as a 9-element Type array (column-major)
Definition Mat3.h:22
bool IsNaN() const
Checks whether any component is NaN.
Definition Mat3_inl.h:448
void SetRow(plUInt32 uiRow, const plVec3Template< Type > &vRow)
Sets all 3 components of the i-th row.
Definition Mat3_inl.h:194
const plVec3Template< Type > GetScalingFactors() const
Returns the 3 scaling factors that are encoded in the matrix.
Definition Mat3_inl.h:460
static plMat3Template< Type > MakeFromColumnMajorArray(const Type *const pData)
Creates a matrix from 9 values that are in column-major layout.
Definition Mat3_inl.h:77
plVec3Template< Type > GetColumn(plUInt32 uiColumn) const
Returns all 3 components of the i-th column.
Definition Mat3_inl.h:204
static void Copy(T *pDestination, const T *pSource, size_t uiCount=1)
Copies objects of type T from pSource to pDestination.
A 3-component vector class.
Definition Vec3.h:9
PL_DECLARE_IF_FLOAT_TYPE Type GetLength() const
Returns the length of the vector.
Definition Vec3_inl.h:54
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 Vec3_inl.h:60
PL_ALWAYS_INLINE float Sin(plAngle a)
***** Trigonometric Functions *****
Definition MathFloat_inl.h:62
constexpr Type Invert(Type f)
Returns 1 / f.
Definition Math_inl.h:63
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
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
PL_ALWAYS_INLINE void Swap(T &ref_f1, T &ref_f2)
Swaps the values in the two variables f1 and f2.
Definition Math_inl.h:224
PL_ALWAYS_INLINE float Cos(plAngle a)
Takes an angle, returns its cosine.
Definition MathFloat_inl.h:67
Enum
Definition Declarations.h:65
@ ColumnMajor
The matrix is stored in column-major format.
Definition Declarations.h:67
Default enum for returning failure or success, instead of using a bool.
Definition Types.h:54