From 2cee5f7e1053a76e62e95543ceccf1001b53ca25 Mon Sep 17 00:00:00 2001 From: marauder2k7 Date: Sun, 28 Jul 2024 09:02:49 +0100 Subject: [PATCH] mul and operators add mul functions and operators code conformity changes --- Engine/source/math/mMatrix.cpp | 40 +++++++++- Engine/source/math/mMatrix.h | 141 ++++++++++++++++++++++++++++++++- 2 files changed, 175 insertions(+), 6 deletions(-) diff --git a/Engine/source/math/mMatrix.cpp b/Engine/source/math/mMatrix.cpp index 90928153f..9c75d740b 100644 --- a/Engine/source/math/mMatrix.cpp +++ b/Engine/source/math/mMatrix.cpp @@ -380,15 +380,15 @@ Matrix& Matrix::inverse() DATA_TYPE pivotVal = augmentedMatrix(i, i); // scale the pivot - for (U32 j = 0; j < 2 * size; ++j) { + for (U32 j = 0; j < 2 * size; j++) { augmentedMatrix(i, j) /= pivotVal; } // Eliminate the current column in all other rows - for (std::size_t k = 0; k < size; k++) { + for (U32 k = 0; k < size; k++) { if (k != i) { DATA_TYPE factor = augmentedMatrix(k, i); - for (std::size_t j = 0; j < 2 * size; ++j) { + for (U32 j = 0; j < 2 * size; j++) { augmentedMatrix(k, j) -= factor * augmentedMatrix(i, j); } } @@ -466,6 +466,40 @@ Matrix& Matrix::setTensorProduct(c return (*this); } +template +void Matrix::mul(Box3F& box) const +{ + AssertFatal(rows == 4 && cols == 4, "Multiplying Box3F with matrix requires 4x4"); + + // Create an array of all 8 corners of the box + Point3F corners[8] = { + Point3F(box.minExtents.x, box.minExtents.y, box.minExtents.z), + Point3F(box.minExtents.x, box.minExtents.y, box.maxExtents.z), + Point3F(box.minExtents.x, box.maxExtents.y, box.minExtents.z), + Point3F(box.minExtents.x, box.maxExtents.y, box.maxExtents.z), + Point3F(box.maxExtents.x, box.minExtents.y, box.minExtents.z), + Point3F(box.maxExtents.x, box.minExtents.y, box.maxExtents.z), + Point3F(box.maxExtents.x, box.maxExtents.y, box.minExtents.z), + Point3F(box.maxExtents.x, box.maxExtents.y, box.maxExtents.z), + }; + + for (U32 i = 0; i < 8; i++) { + corners[i] = (*this) * corners[i]; + } + + box.minExtents = corners[0]; + box.maxExtents = corners[0]; + for (U32 i = 1; i < 8; ++i) { + box.minExtents.x = mMin(box.minExtents.x, corners[i].x); + box.minExtents.y = mMin(box.minExtents.y, corners[i].y); + box.minExtents.z = mMin(box.minExtents.z, corners[i].z); + + box.maxExtents.x = mMax(box.maxExtents.x, corners[i].x); + box.maxExtents.y = mMax(box.maxExtents.y, corners[i].y); + box.maxExtents.z = mMax(box.maxExtents.z, corners[i].z); + } +} + template bool Matrix::isAffine() const { diff --git a/Engine/source/math/mMatrix.h b/Engine/source/math/mMatrix.h index e2717e985..98785dd54 100644 --- a/Engine/source/math/mMatrix.h +++ b/Engine/source/math/mMatrix.h @@ -674,7 +674,61 @@ public: void setRow(S32 row, const Point4F& cptr); void setRow(S32 row, const Point3F& cptr); - + + ///< M * a -> M + Matrix& mul(const Matrix& a) + { return *this * a; } + ///< a * M -> M + Matrix& mulL(const Matrix& a) + { return *this = a * *this; } + ///< a * b -> M + Matrix& mul(const Matrix& a, const Matrix& b) + { return *this = a * b; } + ///< M * a -> M + Matrix& mul(const F32 a) + { return *this * a; } + ///< a * b -> M + Matrix& mul(const Matrix& a, const F32 b) + { return *this = a * b; } + + + ///< M * p -> p (full [4x4] * [1x4]) + void mul(Point4F& p) const { p = *this * p; } + ///< M * p -> p (assume w = 1.0f) + void mulP(Point3F& p) const { p = *this * p; } + ///< M * p -> d (assume w = 1.0f) + void mulP(const Point3F& p, Point3F* d) const { *d = *this * p; } + ///< M * v -> v (assume w = 0.0f) + void mulV(VectorF& v) const + { + AssertFatal(rows == 4 && cols == 4, "Multiplying VectorF with matrix requires 4x4"); + VectorF result( + (*this)(0, 0) * v.x + (*this)(0, 1) * v.y + (*this)(0, 2) * v.z, + (*this)(1, 0) * v.x + (*this)(1, 1) * v.y + (*this)(1, 2) * v.z, + (*this)(2, 0) * v.x + (*this)(2, 1) * v.y + (*this)(2, 2) * v.z + ); + + v = result; + + } + ///< M * v -> d (assume w = 0.0f) + void mulV(const VectorF& v, Point3F* d) const + { + AssertFatal(rows == 4 && cols == 4, "Multiplying VectorF with matrix requires 4x4"); + VectorF result( + (*this)(0, 0) * v.x + (*this)(0, 1) * v.y + (*this)(0, 2) * v.z, + (*this)(1, 0) * v.x + (*this)(1, 1) * v.y + (*this)(1, 2) * v.z, + (*this)(2, 0) * v.x + (*this)(2, 1) * v.y + (*this)(2, 2) * v.z + ); + + d->x = result.x; + d->y = result.y; + d->z = result.z; + } + + ///< Axial box -> Axial Box (too big a function to be inline) + void mul(Box3F& box) const; + // ------ Getters ------ bool isAffine() const; bool isIdentity() const; @@ -710,17 +764,98 @@ public: // ------ Operators ------ + Matrix operator * (const Matrix& other) const { + Matrix result; + + for (U32 i = 0; i < rows; i++) { + for (U32 j = 0; j < cols; j++) { + result(i, j) = 0; + for (U32 k = 0; k < cols; k++) { + result(i, j) += (*this)(i, k) * other(k, j); + } + } + } + + return result; + } + + Matrix operator *= (const Matrix& other) { + *this = *this * other; + return *this; + } + + Matrix operator * (const DATA_TYPE scalar) const { + Matrix result; + for (U32 i = 0; i < rows; i++) { + for (U32 j = 0; j < cols; j++) { + result(i, j) = (*this)(i, j) * scalar; + } + } + + return result; + } + Matrix& operator *= (const DATA_TYPE scalar) { + for (U32 i = 0; i < rows; i++) { + for (U32 j = 0; j < cols; j++) { + (*this)(i, j) *= scalar; + } + } + + return *this; + } + + Point3F operator*(const Point3F& point) const { + AssertFatal(rows == 4 && cols == 4, "Multiplying point3 with matrix requires 4x4"); + return Point3F( + (*this)(0, 0) * point.x + (*this)(0, 1) * point.y + (*this)(0, 2) * point.z + (*this)(0, 3), + (*this)(1, 0) * point.x + (*this)(1, 1) * point.y + (*this)(1, 2) * point.z + (*this)(1, 3), + (*this)(2, 0) * point.x + (*this)(2, 1) * point.y + (*this)(2, 2) * point.z + (*this)(2, 3) + ); + } + + Point4F operator*(const Point4F& point) const { + AssertFatal(rows == 4 && cols == 4, "Multiplying point4 with matrix requires 4x4"); + return Point4F( + (*this)(0, 0) * point.x + (*this)(0, 1) * point.y + (*this)(0, 2) * point.z + (*this)(0, 3) * point.w, + (*this)(1, 0) * point.x + (*this)(1, 1) * point.y + (*this)(1, 2) * point.z + (*this)(1, 3) * point.w, + (*this)(2, 0) * point.x + (*this)(2, 1) * point.y + (*this)(2, 2) * point.z + (*this)(2, 3) * point.w, + (*this)(3, 0) * point.x + (*this)(3, 1) * point.y + (*this)(3, 2) * point.z + (*this)(3, 3) * point.w + ); + } + + Matrix& operator = (const Matrix& other) { + if (this != &other) { + std::copy(other.data, other.data + rows * cols, this->data); + } + + return *this; + } + + bool operator == (const Matrix& other) const { + for (U32 i = 0; i < rows; i++) { + for (U32 j = 0; j < cols; j++) { + if ((*this)(i, j) != other(i, j)) + return false; + } + } + return true; + } + + bool operator != (const Matrix& other) const { + return !(*this == other); + } + operator DATA_TYPE* () { return (data); } operator const DATA_TYPE* () const { return (DATA_TYPE*)(data); } - DATA_TYPE& operator()(U32 row, U32 col) { + DATA_TYPE& operator () (U32 row, U32 col) { if (row >= rows || col >= cols) AssertFatal(false, "Matrix indices out of range"); return data[col * rows + row]; } - const DATA_TYPE& operator()(U32 row, U32 col) const { + const DATA_TYPE& operator () (U32 row, U32 col) const { if (row >= rows || col >= cols) AssertFatal(false, "Matrix indices out of range");