3#include <Foundation/Math/Mat3.h>
5template <
typename Type>
8#if PL_ENABLED(PL_MATH_CHECK_FOR_NAN)
11 for (plUInt32 i = 0; i < 16; ++i)
12 m_fElementsCM[i] = TypeNaN;
16template <
typename Type>
25 for (
int i = 0; i < 4; ++i)
27 Element(0, i) = pData[i * 4 + 0];
28 Element(1, i) = pData[i * 4 + 1];
29 Element(2, i) = pData[i * 4 + 2];
30 Element(3, i) = pData[i * 4 + 3];
35template <
typename Type>
36plMat4Template<Type>::plMat4Template(Type c1r1, Type c2r1, Type c3r1, Type c4r1, Type c1r2, Type c2r2, Type c3r2, Type c4r2, Type c1r3, Type c2r3,
37 Type c3r3, Type c4r3, Type c1r4, Type c2r4, Type c3r4, Type c4r4)
57template <
typename Type>
60 SetTransformationMatrix(mRotation, vTranslation);
63template <
typename Type>
74template <
typename Type>
97template <
typename Type>
101 for (
int i = 0; i < 4; ++i)
103 res.Element(0, i) = pData[i * 4 + 0];
104 res.Element(1, i) = pData[i * 4 + 1];
105 res.Element(2, i) = pData[i * 4 + 2];
106 res.Element(3, i) = pData[i * 4 + 3];
111template <
typename Type>
119template <
typename Type>
120plMat4Template<Type> plMat4Template<Type>::MakeFromValues(Type c1r1, Type c2r1, Type c3r1, Type c4r1, Type c1r2, Type c2r2, Type c3r2, Type c4r2, Type c1r3, Type c2r3, Type c3r3, Type c4r3, Type c1r4, Type c2r4, Type c3r4, Type c4r4)
123 res.Element(0, 0) = c1r1;
124 res.Element(1, 0) = c2r1;
125 res.Element(2, 0) = c3r1;
126 res.Element(3, 0) = c4r1;
127 res.Element(0, 1) = c1r2;
128 res.Element(1, 1) = c2r2;
129 res.Element(2, 1) = c3r2;
130 res.Element(3, 1) = c4r2;
131 res.Element(0, 2) = c1r3;
132 res.Element(1, 2) = c2r3;
133 res.Element(2, 2) = c3r3;
134 res.Element(3, 2) = c4r3;
135 res.Element(0, 3) = c1r4;
136 res.Element(1, 3) = c2r4;
137 res.Element(2, 3) = c3r4;
138 res.Element(3, 3) = c4r4;
142template <
typename Type>
145 return plMat4Template<Type>::MakeFromValues(1, 0, 0, vTranslation.x, 0, 1, 0, vTranslation.y, 0, 0, 1, vTranslation.z, 0, 0, 0, 1);
149template <
typename Type>
157template <
typename Type>
161 res.Element(0, 0) = vScale.x;
162 res.Element(1, 0) = 0;
163 res.Element(2, 0) = 0;
164 res.Element(3, 0) = 0;
165 res.Element(0, 1) = 0;
166 res.Element(1, 1) = vScale.y;
167 res.Element(2, 1) = 0;
168 res.Element(3, 1) = 0;
169 res.Element(0, 2) = 0;
170 res.Element(1, 2) = 0;
171 res.Element(2, 2) = vScale.z;
172 res.Element(3, 2) = 0;
173 res.Element(0, 3) = 0;
174 res.Element(1, 3) = 0;
175 res.Element(2, 3) = 0;
176 res.Element(3, 3) = 1;
180template <
typename Type>
186 return plMat4Template<Type>::MakeFromValues(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, fCos, -fSin, 0.0f, 0.0f, fSin, fCos, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
189template <
typename Type>
195 return plMat4Template<Type>::MakeFromValues(fCos, 0.0f, fSin, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, -fSin, 0.0f, fCos, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
198template <
typename Type>
204 return plMat4Template<Type>::MakeFromValues(fCos, -fSin, 0.0f, 0.0f, fSin, fCos, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
207template <
typename Type>
210 SetRotationalPart(mRotation);
211 SetTranslationVector(vTranslation);
215template <
typename Type>
226 for (
int i = 0; i < 4; ++i)
228 out_pData[i * 4 + 0] = Element(0, i);
229 out_pData[i * 4 + 1] = Element(1, i);
230 out_pData[i * 4 + 2] = Element(2, i);
231 out_pData[i * 4 + 3] = Element(3, i);
236template <
typename Type>
242template <
typename Type>
245 *
this = MakeIdentity();
248template <
typename Type>
259template <
typename Type>
267template <
typename Type>
272 PL_ASSERT_DEBUG(res.Succeeded(),
"Could not invert the given Mat4.");
273 PL_IGNORE_UNUSED(res);
277template <
typename Type>
281 PL_ASSERT_DEBUG(uiRow <= 3,
"Invalid Row Index {0}", uiRow);
284 r.x = Element(0, uiRow);
285 r.y = Element(1, uiRow);
286 r.z = Element(2, uiRow);
287 r.w = Element(3, uiRow);
292template <
typename Type>
295 PL_ASSERT_DEBUG(uiRow <= 3,
"Invalid Row Index {0}", uiRow);
297 Element(0, uiRow) = vRow.x;
298 Element(1, uiRow) = vRow.y;
299 Element(2, uiRow) = vRow.z;
300 Element(3, uiRow) = vRow.w;
303template <
typename Type>
307 PL_ASSERT_DEBUG(uiColumn <= 3,
"Invalid Column Index {0}", uiColumn);
310 r.x = Element(uiColumn, 0);
311 r.y = Element(uiColumn, 1);
312 r.z = Element(uiColumn, 2);
313 r.w = Element(uiColumn, 3);
318template <
typename Type>
321 PL_ASSERT_DEBUG(uiColumn <= 3,
"Invalid Column Index {0}", uiColumn);
323 Element(uiColumn, 0) = vColumn.x;
324 Element(uiColumn, 1) = vColumn.y;
325 Element(uiColumn, 2) = vColumn.z;
326 Element(uiColumn, 3) = vColumn.w;
329template <
typename Type>
337template <
typename Type>
340 Element(0, 0) = vDiag.x;
341 Element(1, 1) = vDiag.y;
342 Element(2, 2) = vDiag.z;
343 Element(3, 3) = vDiag.w;
346template <
typename Type>
350 r.x = Element(0, 0) * v.x + Element(1, 0) * v.y + Element(2, 0) * v.z + Element(3, 0);
351 r.y = Element(0, 1) * v.x + Element(1, 1) * v.y + Element(2, 1) * v.z + Element(3, 1);
352 r.z = Element(0, 2) * v.x + Element(1, 2) * v.y + Element(2, 2) * v.z + Element(3, 2);
358template <
typename Type>
361 PL_ASSERT_DEBUG(pV !=
nullptr,
"Array must not be nullptr.");
366 for (plUInt32 i = 0; i < uiNumVectors; ++i)
368 *pCur = TransformPosition(*pCur);
373template <
typename Type>
377 r.x = Element(0, 0) * v.x + Element(1, 0) * v.y + Element(2, 0) * v.z;
378 r.y = Element(0, 1) * v.x + Element(1, 1) * v.y + Element(2, 1) * v.z;
379 r.z = Element(0, 2) * v.x + Element(1, 2) * v.y + Element(2, 2) * v.z;
385template <
typename Type>
389 PL_ASSERT_DEBUG(pV !=
nullptr,
"Array must not be nullptr.");
394 for (plUInt32 i = 0; i < uiNumVectors; ++i)
396 *pCur = TransformDirection(*pCur);
401template <
typename Type>
405 r.x = Element(0, 0) * v.x + Element(1, 0) * v.y + Element(2, 0) * v.z + Element(3, 0) * v.w;
406 r.y = Element(0, 1) * v.x + Element(1, 1) * v.y + Element(2, 1) * v.z + Element(3, 1) * v.w;
407 r.z = Element(0, 2) * v.x + Element(1, 2) * v.y + Element(2, 2) * v.z + Element(3, 2) * v.w;
408 r.w = Element(0, 3) * v.x + Element(1, 3) * v.y + Element(2, 3) * v.z + Element(3, 3) * v.w;
414template <
typename Type>
417 PL_ASSERT_DEBUG(pV !=
nullptr,
"Array must not be nullptr.");
422 for (plUInt32 i = 0; i < uiNumVectors; ++i)
424 *pCur = Transform(*pCur);
429template <
typename Type>
437template <
typename Type>
445template <
typename Type>
448 for (plUInt32 col = 0; col < 3; ++col)
450 for (plUInt32 row = 0; row < 3; ++row)
452 Element(col, row) = mRotation.Element(col, row);
457template <
typename Type>
462 for (plUInt32 col = 0; col < 3; ++col)
464 for (plUInt32 row = 0; row < 3; ++row)
466 r.Element(col, row) = Element(col, row);
474template <
typename Type>
477 for (plInt32 i = 0; i < 16; ++i)
478 m_fElementsCM[i] *= f;
483template <
typename Type>
491template <
typename Type>
495 for (plInt32 i = 0; i < 4; ++i)
497 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) +
498 m1.Element(3, i) * m2.Element(0, 3);
499 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) +
500 m1.Element(3, i) * m2.Element(1, 3);
501 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) +
502 m1.Element(3, i) * m2.Element(2, 3);
503 r.Element(3, i) = m1.Element(0, i) * m2.Element(3, 0) + m1.Element(1, i) * m2.Element(3, 1) + m1.Element(2, i) * m2.Element(3, 2) +
504 m1.Element(3, i) * m2.Element(3, 3);
511template <
typename Type>
517template <
typename Type>
527template <
typename Type>
528PL_FORCE_INLINE Type GetDeterminantOf3x3SubMatrix(
const plMat4Template<Type>& m, plInt32 i, plInt32 j)
530 const plInt32 si0 = 0 + ((i <= 0) ? 1 : 0);
531 const plInt32 si1 = 1 + ((i <= 1) ? 1 : 0);
532 const plInt32 si2 = 2 + ((i <= 2) ? 1 : 0);
534 const plInt32 sj0 = 0 + ((j <= 0) ? 1 : 0);
535 const plInt32 sj1 = 1 + ((j <= 1) ? 1 : 0);
536 const plInt32 sj2 = 2 + ((j <= 2) ? 1 : 0);
538 Type fDet2 = ((m.Element(sj0, si0) * m.Element(sj1, si1) * m.Element(sj2, si2) + m.Element(sj1, si0) * m.Element(sj2, si1) * m.Element(sj0, si2) +
539 m.Element(sj2, si0) * m.Element(sj0, si1) * m.Element(sj1, si2)) -
540 (m.Element(sj0, si2) * m.Element(sj1, si1) * m.Element(sj2, si0) + m.Element(sj1, si2) * m.Element(sj2, si1) * m.Element(sj0, si0) +
541 m.Element(sj2, si2) * m.Element(sj0, si1) * m.Element(sj1, si0)));
546template <
typename Type>
551 det += m.Element(0, 0) * GetDeterminantOf3x3SubMatrix(m, 0, 0);
552 det += -m.Element(1, 0) * GetDeterminantOf3x3SubMatrix(m, 0, 1);
553 det += m.Element(2, 0) * GetDeterminantOf3x3SubMatrix(m, 0, 2);
554 det += -m.Element(3, 0) * GetDeterminantOf3x3SubMatrix(m, 0, 3);
562template <
typename Type>
565 return operator*(m1, f);
568template <
typename Type>
573 for (plUInt32 i = 0; i < 16; ++i)
580template <
typename Type>
586template <
typename Type>
591 for (plUInt32 i = 0; i < 16; ++i)
598template <
typename Type>
603 for (plUInt32 i = 0; i < 16; ++i)
610template <
typename Type>
616 for (plUInt32 i = 0; i < 16; ++i)
625template <
typename Type>
631 PL_ASSERT_DEBUG(fEpsilon >= 0.0f,
"Epsilon may not be negative.");
633 for (plUInt32 i = 0; i < 16; ++i)
642template <
typename Type>
648template <
typename Type>
654template <
typename Type>
659 for (plUInt32 i = 0; i < 16; ++i)
668template <
typename Type>
712template <
typename Type>
715 for (plUInt32 i = 0; i < 16; ++i)
717 if (!plMath::IsFinite(m_fElementsCM[i]))
724template <
typename Type>
727 for (plUInt32 i = 0; i < 16; ++i)
729 if (plMath::IsNaN(m_fElementsCM[i]))
736template <
typename Type>
749template <
typename Type>
756 if (tx.
SetLength(vXYZ.x, fEpsilon) == PL_FAILURE)
758 if (ty.
SetLength(vXYZ.y, fEpsilon) == PL_FAILURE)
760 if (tz.
SetLength(vXYZ.z, fEpsilon) == PL_FAILURE)
764 Element(0, 0) = tx.x;
765 Element(0, 1) = tx.y;
766 Element(0, 2) = tx.z;
767 Element(1, 0) = ty.x;
768 Element(1, 1) = ty.y;
769 Element(1, 2) = ty.z;
770 Element(2, 0) = tz.x;
771 Element(2, 1) = tz.y;
772 Element(2, 2) = tz.z;
777#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
A 4x4 component matrix class.
Definition Mat4.h:11
plMat4Template()
Default Constructor DOES NOT INITIALIZE the matrix, at all.
Definition Mat4_inl.h:6
void SetIdentity()
Sets all elements to zero, except the diagonal, which is set to one.
Definition Mat4_inl.h:243
const plVec3Template< Type > GetTranslationVector() const
Returns the first 3 components of the last column.
Definition Mat4_inl.h:430
static plMat4Template< Type > MakeIdentity()
Returns an identity matrix.
Definition Mat4_inl.h:75
static plMat4Template< Type > MakeScaling(const plVec3Template< Type > &vScale)
Creates a matrix with all zero values, except along the diagonal, which is set to x,...
Definition Mat4_inl.h:158
plVec4Template< Type > GetColumn(plUInt32 uiColumn) const
Returns all 4 components of the i-th column.
Definition Mat4_inl.h:304
static plMat4Template< Type > MakeTransformation(const plMat3Template< Type > &mRotation, const plVec3Template< Type > &vTranslation)
Creates a transformation matrix from a rotation and a translation.
Definition Mat4_inl.h:150
const plMat3Template< Type > GetRotationalPart() const
Returns the 3x3 rotational and scaling part of the matrix.
Definition Mat4_inl.h:458
static plMat4Template< Type > MakeFromValues(Type c1r1, Type c2r1, Type c3r1, Type c4r1, Type c1r2, Type c2r2, Type c3r2, Type c4r2, Type c1r3, Type c2r3, Type c3r3, Type c4r3, Type c1r4, Type c2r4, Type c3r4, Type c4r4)
Creates a matrix from 16 values. Naming is "column-n row-m".
Definition Mat4_inl.h:120
static plMat4Template< Type > MakeFromRowMajorArray(const Type *const pData)
Creates a matrix from 16 values that are in row-major layout.
Definition Mat4_inl.h:98
bool IsValid() const
Checks whether all components are finite numbers.
Definition Mat4_inl.h:713
static plMat4Template< Type > MakeRotationY(plAngle angle)
Creates a matrix that is a rotation matrix around the Y-axis.
Definition Mat4_inl.h:190
static plMat4Template< Type > MakeRotationX(plAngle angle)
Creates a matrix that is a rotation matrix around the X-axis.
Definition Mat4_inl.h:181
void SetTranslationVector(const plVec3Template< Type > &v)
Sets the first 3 components of the last column.
Definition Mat4_inl.h:438
Type m_fElementsCM[16]
The matrix as a 16-element Type array (column-major)
Definition Mat4.h:24
plVec4Template< Type > GetDiagonal() const
Returns all 4 components on the diagonal of the matrix.
Definition Mat4_inl.h:330
const plVec3Template< Type > TransformPosition(const plVec3Template< Type > &v) const
Matrix-vector multiplication, assuming the 4th component of the vector is one (default behavior).
Definition Mat4_inl.h:347
const plMat4Template< Type > GetTranspose() const
Returns the transpose of this matrix.
Definition Mat4_inl.h:260
const plVec4Template< Type > Transform(const plVec4Template< Type > &v) const
Matrix-vector multiplication.
Definition Mat4_inl.h:402
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 Mat4_inl.h:750
static plMat4Template< Type > MakeRotationZ(plAngle angle)
Creates a matrix that is a rotation matrix around the Z-axis.
Definition Mat4_inl.h:199
void SetDiagonal(const plVec4Template< Type > &vDiag)
Sets all 4 components on the diagonal of the matrix.
Definition Mat4_inl.h:338
void Transpose()
Transposes this matrix.
Definition Mat4_inl.h:249
static plMat4Template< Type > MakeTranslation(const plVec3Template< Type > &vTranslation)
Creates a matrix with all zero values, except the last column, which is set to x, y,...
Definition Mat4_inl.h:143
static plMat4Template< Type > MakeZero()
Returns a zero matrix.
Definition Mat4_inl.h:64
const plVec3Template< Type > TransformDirection(const plVec3Template< Type > &v) const
Matrix-vector multiplication, assuming the 4th component of the vector is zero. So,...
Definition Mat4_inl.h:374
bool IsZero(Type fEpsilon=plMath::DefaultEpsilon< Type >()) const
Checks whether all elements are zero.
Definition Mat4_inl.h:655
void SetTransformationMatrix(const plMat3Template< Type > &mRotation, const plVec3Template< Type > &vTranslation)
Sets a transformation matrix from a rotation and a translation.
Definition Mat4_inl.h:208
bool IsIdentity(Type fEpsilon=plMath::DefaultEpsilon< Type >()) const
Checks whether this is an identity matrix.
Definition Mat4_inl.h:669
void SetRotationalPart(const plMat3Template< Type > &mRotation)
Sets the 3x3 rotational part of the matrix.
Definition Mat4_inl.h:446
bool IsIdentical(const plMat4Template< Type > &rhs) const
Equality Check.
Definition Mat4_inl.h:611
bool IsNaN() const
Checks whether any component is NaN.
Definition Mat4_inl.h:725
void SetColumn(plUInt32 uiColumn, const plVec4Template< Type > &vColumn)
Sets all 4 components of the i-th column.
Definition Mat4_inl.h:319
plVec4Template< Type > GetRow(plUInt32 uiRow) const
Returns all 4 components of the i-th row.
Definition Mat4_inl.h:278
const plVec3Template< Type > GetScalingFactors() const
Returns the 3 scaling factors that are encoded in the matrix.
Definition Mat4_inl.h:737
void GetAsArray(Type *out_pData, plMatrixLayout::Enum layout) const
Copies the 16 values of this matrix into the given array. 'layout' defines whether the data should en...
Definition Mat4_inl.h:216
const plMat4Template< Type > GetInverse(Type fEpsilon=plMath::SmallEpsilon< Type >()) const
Returns the inverse of this matrix.
Definition Mat4_inl.h:268
void operator*=(Type f)
Component-wise multiplication (commutative)
Definition Mat4_inl.h:475
void operator/=(Type f)
Component-wise division.
Definition Mat4_inl.h:484
bool IsEqual(const plMat4Template< Type > &rhs, Type fEpsilon) const
Equality Check with epsilon.
Definition Mat4_inl.h:626
plResult Invert(Type fEpsilon=plMath::SmallEpsilon< Type >())
Inverts this matrix. Return value indicates whether the matrix could be inverted.
Definition AllClasses_inl.h:310
void SetRow(plUInt32 uiRow, const plVec4Template< Type > &vRow)
Sets all 4 components of the i-th row.
Definition Mat4_inl.h:293
static plMat4Template< Type > MakeFromColumnMajorArray(const Type *const pData)
Creates a matrix from 16 values that are in column-major layout.
Definition Mat4_inl.h:112
void SetZero()
Sets all elements to zero.
Definition Mat4_inl.h:237
static T * AddByteOffset(T *pPtr, std::ptrdiff_t offset)
Returns the address stored in ptr plus the given byte offset iOffset, cast to type T.
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
A 4-component vector class.
Definition Vec4.h:9
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