/
redgpu
/
ezEngine
Обзор
Документация
Войти
/
redgpu
/
ezEngine
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
dev
Code/Engine/Foundation/Math/Mat4.h
262 строки
12 KB
Trevor Cash
Update (Templatize) Primative Type Tests to test both float and double versions. (#1785)
27 янв 2026, 09:34
Не верифицирован
27 янв 2026, 09:34
6a0df83
Код
Авторство
О чём код?
#pragma once #include <Foundation/Math/Math.h> #include <Foundation/Math/Angle.h> #include <Foundation/Math/Vec3.h> #include <Foundation/Math/Vec4.h> /// \brief 4x4 matrix template for 3D transformations and projection operations. /// /// Matrix layout: /// ``` /// | m00 m10 m20 m30 | Column 0: (m00, m01, m02, m03) /// | m01 m11 m21 m31 | Column 1: (m10, m11, m12, m13) /// | m02 m12 m22 m32 | Column 2: (m20, m21, m22, m23) /// | m03 m13 m23 m33 | Column 3: (m30, m31, m32, m33) /// ``` template <typename Type> class ezMat4Template { public: EZ_DECLARE_POD_TYPE(); using ComponentType = Type; // *** Data *** public: // The elements are stored in column-major order. // That means first is column 0 (with elements of row 0, row 1, row 2, row 3), // then column 1, then column 2 and finally column 3 /// \brief The matrix as a 16-element Type array (column-major) Type m_fElementsCM[16]; EZ_ALWAYS_INLINE Type& Element(ezInt32 iColumn, ezInt32 iRow) { return m_fElementsCM[iColumn * 4 + iRow]; } EZ_ALWAYS_INLINE Type Element(ezInt32 iColumn, ezInt32 iRow) const { return m_fElementsCM[iColumn * 4 + iRow]; } // *** Constructors *** public: /// \brief Default Constructor DOES NOT INITIALIZE the matrix, at all. ezMat4Template(); // [tested] /// \brief Copies 16 values from pData into the matrix. Can handle the data in row-major or column-major order. /// /// \param pData /// The array of Type values from which to set the matrix data. /// \param layout /// The layout in which pData stores the matrix. The data will get transposed, if necessary. /// The data should be in column-major format, if you want to prevent unnecessary transposes. ezMat4Template(const Type* const pData, ezMatrixLayout::Enum layout); // [tested] /// \brief Sets each element manually: Naming is "column-n row-m" ezMat4Template(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); // [tested] /// \brief Creates a transformation matrix from a rotation and a translation. ezMat4Template(const ezMat3Template<Type>& mRotation, const ezVec3Template<Type>& vTranslation); // [tested] #if EZ_ENABLED(EZ_MATH_CHECK_FOR_NAN) void AssertNotNaN() const { EZ_ASSERT_ALWAYS(!IsNaN(), "This object contains NaN values. This can happen when you forgot to initialize it before using it. Please " "check that all code-paths properly initialize this object."); } #endif /// \brief Returns a zero matrix. [[nodiscard]] static ezMat4Template<Type> MakeZero(); /// \brief Returns an identity matrix. [[nodiscard]] static ezMat4Template<Type> MakeIdentity(); /// \brief Creates a matrix from 16 values that are in row-major layout. [[nodiscard]] static ezMat4Template<Type> MakeFromRowMajorArray(const Type* const pData); /// \brief Creates a matrix from 16 values that are in column-major layout. [[nodiscard]] static ezMat4Template<Type> MakeFromColumnMajorArray(const Type* const pData); /// \brief Creates a matrix from 16 values. Naming is "column-n row-m" [[nodiscard]] static ezMat4Template<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); /// \brief Creates a matrix with all zero values, except the last column, which is set to x, y, z, 1 [[nodiscard]] static ezMat4Template<Type> MakeTranslation(const ezVec3Template<Type>& vTranslation); /// \brief Creates a transformation matrix from a rotation and a translation. [[nodiscard]] static ezMat4Template<Type> MakeTransformation(const ezMat3Template<Type>& mRotation, const ezVec3Template<Type>& vTranslation); /// \brief Creates a matrix with all zero values, except along the diagonal, which is set to x, y, z, 1 [[nodiscard]] static ezMat4Template<Type> MakeScaling(const ezVec3Template<Type>& vScale); /// \brief Creates a matrix that is a rotation matrix around the X-axis. [[nodiscard]] static ezMat4Template<Type> MakeRotationX(ezAngleTemplate<Type> angle); /// \brief Creates a matrix that is a rotation matrix around the Y-axis. [[nodiscard]] static ezMat4Template<Type> MakeRotationY(ezAngleTemplate<Type> angle); /// \brief Creates a matrix that is a rotation matrix around the Z-axis. [[nodiscard]] static ezMat4Template<Type> MakeRotationZ(ezAngleTemplate<Type> angle); /// \brief Creates a matrix that is a rotation matrix around the given axis. [[nodiscard]] static ezMat4Template<Type> MakeAxisRotation(const ezVec3Template<Type>& vAxis, ezAngleTemplate<Type> angle); /// \brief Copies the 16 values of this matrix into the given array. 'layout' defines whether the data should end up in column-major or /// row-major format. void GetAsArray(Type* out_pData, ezMatrixLayout::Enum layout) const; // [tested] /// \brief Sets a transformation matrix from a rotation and a translation. void SetTransformationMatrix(const ezMat3Template<Type>& mRotation, const ezVec3Template<Type>& vTranslation); // [tested] // *** Special matrix constructors *** public: /// \brief Sets all elements to zero. void SetZero(); // [tested] /// \brief Sets all elements to zero, except the diagonal, which is set to one. void SetIdentity(); // [tested] // *** Common Matrix Operations *** public: /// \brief Transposes this matrix. void Transpose(); // [tested] /// \brief Returns the transpose of this matrix. const ezMat4Template<Type> GetTranspose() const; // [tested] /// \brief Inverts this matrix. Return value indicates whether the matrix could be inverted. ezResult Invert(Type fEpsilon = ezMath::SmallEpsilon<Type>()); // [tested] /// \brief Returns the inverse of this matrix. const ezMat4Template<Type> GetInverse(Type fEpsilon = ezMath::SmallEpsilon<Type>()) const; // [tested] // *** Checks *** public: /// \brief Checks whether all elements are zero. bool IsZero(Type fEpsilon = ezMath::DefaultEpsilon<Type>()) const; // [tested] /// \brief Checks whether this is an identity matrix. bool IsIdentity(Type fEpsilon = ezMath::DefaultEpsilon<Type>()) const; // [tested] /// \brief Checks whether all components are finite numbers. bool IsValid() const; // [tested] /// \brief Checks whether any component is NaN. bool IsNaN() const; // [tested] // *** Special Accessors *** public: /// \brief Returns all 4 components of the i-th row. ezVec4Template<Type> GetRow(ezUInt32 uiRow) const; // [tested] /// \brief Sets all 4 components of the i-th row. void SetRow(ezUInt32 uiRow, const ezVec4Template<Type>& vRow); // [tested] /// \brief Returns all 4 components of the i-th column. ezVec4Template<Type> GetColumn(ezUInt32 uiColumn) const; // [tested] /// \brief Sets all 4 components of the i-th column. void SetColumn(ezUInt32 uiColumn, const ezVec4Template<Type>& vColumn); // [tested] /// \brief Returns all 4 components on the diagonal of the matrix. ezVec4Template<Type> GetDiagonal() const; // [tested] /// \brief Sets all 4 components on the diagonal of the matrix. void SetDiagonal(const ezVec4Template<Type>& vDiag); // [tested] /// \brief Returns the first 3 components of the last column. const ezVec3Template<Type> GetTranslationVector() const; // [tested] /// \brief Sets the first 3 components of the last column. void SetTranslationVector(const ezVec3Template<Type>& v); // [tested] /// \brief Sets the 3x3 rotational part of the matrix. void SetRotationalPart(const ezMat3Template<Type>& mRotation); // [tested] /// \brief Returns the 3x3 rotational and scaling part of the matrix. const ezMat3Template<Type> GetRotationalPart() const; // [tested] /// \brief Returns the 3 scaling factors that are encoded in the matrix. const ezVec3Template<Type> GetScalingFactors() const; // [tested] /// \brief Tries to set the three scaling factors in the matrix. Returns EZ_FAILURE if the matrix columns cannot be normalized and thus no /// rescaling is possible. ezResult SetScalingFactors(const ezVec3Template<Type>& vXYZ, Type fEpsilon = ezMath::DefaultEpsilon<Type>()); // [tested] // *** Operators *** public: /// \brief Matrix-vector multiplication, assuming the 4th component of the vector is one (default behavior). const ezVec3Template<Type> TransformPosition(const ezVec3Template<Type>& v) const; // [tested] /// \brief Matrix-vector multiplication, assuming the 4th component of the vector is one (default behavior). void TransformPosition(ezVec3Template<Type>* pV, ezUInt32 uiNumVectors, ezUInt32 uiStride = sizeof(ezVec3Template<Type>)) const; // [tested] /// \brief Matrix-vector multiplication, assuming the 4th component of the vector is zero. So, rotation/scaling only. Useful as an /// optimization. const ezVec3Template<Type> TransformDirection(const ezVec3Template<Type>& v) const; // [tested] /// \brief Matrix-vector multiplication, assuming the 4th component of the vector is zero. So, rotation/scaling only. Useful as an /// optimization. void TransformDirection(ezVec3Template<Type>* pV, ezUInt32 uiNumVectors, ezUInt32 uiStride = sizeof(ezVec3Template<Type>)) const; // [tested] /// \brief Matrix-vector multiplication. const ezVec4Template<Type> Transform(const ezVec4Template<Type>& v) const; // [tested] /// \brief Matrix-vector multiplication. void Transform(ezVec4Template<Type>* pV, ezUInt32 uiNumVectors, ezUInt32 uiStride = sizeof(ezVec4Template<Type>)) const; // [tested] /// \brief Component-wise multiplication (commutative) void operator*=(Type f); // [tested] /// \brief Component-wise division void operator/=(Type f); // [tested] /// \brief Equality Check bool IsIdentical(const ezMat4Template<Type>& rhs) const; // [tested] /// \brief Equality Check with epsilon bool IsEqual(const ezMat4Template<Type>& rhs, Type fEpsilon) const; // [tested] }; // *** free functions *** /// \brief Matrix-Matrix multiplication template <typename Type> const ezMat4Template<Type> operator*(const ezMat4Template<Type>& m1, const ezMat4Template<Type>& m2); // [tested] /// \brief Matrix-vector multiplication template <typename Type> const ezVec3Template<Type> operator*(const ezMat4Template<Type>& m, const ezVec3Template<Type>& v); // [tested] /// \brief Matrix-vector multiplication template <typename Type> const ezVec4Template<Type> operator*(const ezMat4Template<Type>& m, const ezVec4Template<Type>& v); // [tested] /// \brief Component-wise multiplication (commutative) template <typename Type> const ezMat4Template<Type> operator*(const ezMat4Template<Type>& m1, Type f); // [tested] /// \brief Component-wise multiplication (commutative) template <typename Type> const ezMat4Template<Type> operator*(Type f, const ezMat4Template<Type>& m1); // [tested] /// \brief Component-wise division template <typename Type> const ezMat4Template<Type> operator/(const ezMat4Template<Type>& m1, Type f); // [tested] /// \brief Adding two matrices (component-wise) template <typename Type> const ezMat4Template<Type> operator+(const ezMat4Template<Type>& m1, const ezMat4Template<Type>& m2); // [tested] /// \brief Subtracting two matrices (component-wise) template <typename Type> const ezMat4Template<Type> operator-(const ezMat4Template<Type>& m1, const ezMat4Template<Type>& m2); // [tested] /// \brief Comparison Operator == template <typename Type> bool operator==(const ezMat4Template<Type>& lhs, const ezMat4Template<Type>& rhs); // [tested] /// \brief Comparison Operator != template <typename Type> bool operator!=(const ezMat4Template<Type>& lhs, const ezMat4Template<Type>& rhs); // [tested] #include <Foundation/Math/Implementation/Mat4_inl.h>