From be63652df65bdd5ec87523c4bd6aa46a099204f2 Mon Sep 17 00:00:00 2001 From: Leonetienne Date: Sun, 6 Mar 2022 19:58:59 +0100 Subject: [PATCH] Moved everything in namespace Leonetienne::Eule --- Eule/Collider.h | 2 +- Eule/Constants.h | 18 +- Eule/Math.cpp | 37 +- Eule/Math.h | 2 +- Eule/Matrix4x4.cpp | 1182 ++++++++++++++--------------- Eule/Matrix4x4.h | 2 +- Eule/Quaternion.cpp | 2 +- Eule/Quaternion.h | 2 +- Eule/Random.cpp | 89 +-- Eule/Random.h | 2 +- Eule/Rect.h | 2 +- Eule/TrapazoidalPrismCollider.cpp | 2 +- Eule/TrapazoidalPrismCollider.h | 2 +- Eule/Vector2.cpp | 6 +- Eule/Vector2.h | 2 +- Eule/Vector3.cpp | 8 +- Eule/Vector3.h | 2 +- Eule/Vector4.cpp | 10 +- Eule/Vector4.h | 2 +- 19 files changed, 661 insertions(+), 713 deletions(-) diff --git a/Eule/Collider.h b/Eule/Collider.h index 27cf6cd..67269ff 100644 --- a/Eule/Collider.h +++ b/Eule/Collider.h @@ -1,7 +1,7 @@ #pragma once #include "Vector3.h" -namespace Eule +namespace Leonetienne::Eule { /** Abstract class of a collider domain. * Specializations describe a shape in 3d space, and provide implementations of the methods below, diff --git a/Eule/Constants.h b/Eule/Constants.h index 0fc2462..f0629b2 100644 --- a/Eule/Constants.h +++ b/Eule/Constants.h @@ -2,14 +2,16 @@ // Pretty sure the compiler will optimize these calculations out... -//! Pi up to 50 decimal places -static constexpr double PI = 3.14159265358979323846264338327950288419716939937510; +namespace Leonetienne::Eule { + //! Pi up to 50 decimal places + static constexpr double PI = 3.14159265358979323846264338327950288419716939937510; -//! Pi divided by two -static constexpr double HALF_PI = 1.57079632679489661923132169163975144209858469968755; + //! Pi divided by two + static constexpr double HALF_PI = 1.57079632679489661923132169163975144209858469968755; -//! Factor to convert degrees to radians -static constexpr double Deg2Rad = 0.0174532925199432957692369076848861271344287188854172222222222222; + //! Factor to convert degrees to radians + static constexpr double Deg2Rad = 0.0174532925199432957692369076848861271344287188854172222222222222; -//! Factor to convert radians to degrees -static constexpr double Rad2Deg = 57.295779513082320876798154814105170332405472466564427711013084788; + //! Factor to convert radians to degrees + static constexpr double Rad2Deg = 57.295779513082320876798154814105170332405472466564427711013084788; +} diff --git a/Eule/Math.cpp b/Eule/Math.cpp index 4c8a3c7..7824e1d 100644 --- a/Eule/Math.cpp +++ b/Eule/Math.cpp @@ -2,28 +2,27 @@ #include "Constants.h" #include -using namespace Eule; +namespace Leonetienne::Eule { -int Math::Mod(const int numerator, const int denominator) -{ - if (denominator == 0) - throw std::logic_error("Division by zero"); + int Math::Mod(const int numerator, const int denominator) { + if (denominator == 0) + throw std::logic_error("Division by zero"); - // Quick optimizations: + // Quick optimizations: - // -> 0/n is always 0 - if (numerator == 0) - return 0; + // -> 0/n is always 0 + if (numerator == 0) + return 0; - // -> operator% works for a > 0 && b > 0 - if (denominator > 0 && numerator > 0) - return numerator % denominator; + // -> operator% works for a > 0 && b > 0 + if (denominator > 0 && numerator > 0) + return numerator % denominator; - // Else: generalized formula - return (denominator + (numerator % denominator)) % denominator; -} - -double Math::Oscillate(const double a, const double b, const double counter, const double speed) -{ - return (sin(counter * speed * PI - HALF_PI) * 0.5 + 0.5) * (b - a) + a; + // Else: generalized formula + return (denominator + (numerator % denominator)) % denominator; + } + + double Math::Oscillate(const double a, const double b, const double counter, const double speed) { + return (sin(counter * speed * PI - HALF_PI) * 0.5 + 0.5) * (b - a) + a; + } } diff --git a/Eule/Math.h b/Eule/Math.h index af9fcf6..4894803 100644 --- a/Eule/Math.h +++ b/Eule/Math.h @@ -2,7 +2,7 @@ #include #include -namespace Eule +namespace Leonetienne::Eule { /** Math utility class containing basic functions. */ diff --git a/Eule/Matrix4x4.cpp b/Eule/Matrix4x4.cpp index ee85582..c35d73a 100644 --- a/Eule/Matrix4x4.cpp +++ b/Eule/Matrix4x4.cpp @@ -7,653 +7,607 @@ #include #endif -using namespace Eule; +namespace Leonetienne::Eule { -Matrix4x4::Matrix4x4() -{ - // Create identity matrix - for (std::size_t i = 0; i < 4; i++) - for (std::size_t j = 0; j < 4; j++) - v[i][j] = double(i == j); - - return; -} + Matrix4x4::Matrix4x4() { + // Create identity matrix + for (std::size_t i = 0; i < 4; i++) + for (std::size_t j = 0; j < 4; j++) + v[i][j] = double(i == j); -Matrix4x4::Matrix4x4(const Matrix4x4& other) -{ - v = other.v; - return; -} + return; + } -Matrix4x4::Matrix4x4(Matrix4x4&& other) noexcept -{ - v = std::move(other.v); - return; -} - -Matrix4x4 Matrix4x4::operator*(const Matrix4x4& other) const -{ - Matrix4x4 newMatrix; - newMatrix.p = 1; - - #ifndef _EULE_NO_INTRINSICS_ - - - /* <= Matrix3x3 multiplication => */ - - // Load matrix components - __m256d __va1 = _mm256_set_pd(v[0][0], v[0][0], v[0][0], v[1][0]); - __m256d __va2 = _mm256_set_pd(v[1][0], v[1][0], v[2][0], v[2][0]); - - __m256d __oa1 = _mm256_set_pd(other[0][0], other[0][1], other[0][2], other[0][0]); - __m256d __oa2 = _mm256_set_pd(other[0][1], other[0][2], other[0][0], other[0][1]); - - __m256d __vb1 = _mm256_set_pd(v[0][1], v[0][1], v[0][1], v[1][1]); - __m256d __vb2 = _mm256_set_pd(v[1][1], v[1][1], v[2][1], v[2][1]); - - __m256d __ob1 = _mm256_set_pd(other[1][0], other[1][1], other[1][2], other[1][0]); - __m256d __ob2 = _mm256_set_pd(other[1][1], other[1][2], other[1][0], other[1][1]); - - __m256d __vc1 = _mm256_set_pd(v[0][2], v[0][2], v[0][2], v[1][2]); - __m256d __vc2 = _mm256_set_pd(v[1][2], v[1][2], v[2][2], v[2][2]); - - __m256d __oc1 = _mm256_set_pd(other[2][0], other[2][1], other[2][2], other[2][0]); - __m256d __oc2 = _mm256_set_pd(other[2][1], other[2][2], other[2][0], other[2][1]); - - // Initialize sums - __m256d __sum1 = _mm256_set1_pd(0); - __m256d __sum2 = _mm256_set1_pd(0); - - // Let's multiply-add them together - // First, the first block - __sum1 = _mm256_fmadd_pd(__va1, __oa1, __sum1); - __sum1 = _mm256_fmadd_pd(__vb1, __ob1, __sum1); - __sum1 = _mm256_fmadd_pd(__vc1, __oc1, __sum1); - - // Then the second block - __sum2 = _mm256_fmadd_pd(__va2, __oa2, __sum2); - __sum2 = _mm256_fmadd_pd(__vb2, __ob2, __sum2); - __sum2 = _mm256_fmadd_pd(__vc2, __oc2, __sum2); - - // Retrieve results - double sum1[4]; - double sum2[4]; - - _mm256_storeu_pd(sum1, __sum1); - _mm256_storeu_pd(sum2, __sum2); - - // Apply results - // Block 1 - newMatrix[0][0] = sum1[3]; - newMatrix[0][1] = sum1[2]; - newMatrix[0][2] = sum1[1]; - newMatrix[1][0] = sum1[0]; - - // Block 2 - newMatrix[1][1] = sum2[3]; - newMatrix[1][2] = sum2[2]; - newMatrix[2][0] = sum2[1]; - newMatrix[2][1] = sum2[0]; - - // Does not fit in the intrinsic calculation. Might just calculate 'by hand'. - newMatrix[2][2] = (v[2][0] * other[0][2]) + (v[2][1] * other[1][2]) + (v[2][2] * other[2][2]); - - - /* <= Translation component => */ - - // Load translation components into registers - __m256d __transSelf = _mm256_set_pd(0, l, h, d); - __m256d __transOther = _mm256_set_pd(0, other.l, other.h, other.d); - - // Let's add them - __m256d __sum = _mm256_add_pd(__transSelf, __transOther); - - // Retrieve results - double sum[4]; - _mm256_storeu_pd(sum, __sum); - - // Apply them - newMatrix.d = sum[0]; - newMatrix.h = sum[1]; - newMatrix.l = sum[2]; - - #else - - - // Rotation, Scaling - newMatrix[0][0] = (v[0][0] * other[0][0]) + (v[0][1] * other[1][0]) + (v[0][2] * other[2][0]); - newMatrix[0][1] = (v[0][0] * other[0][1]) + (v[0][1] * other[1][1]) + (v[0][2] * other[2][1]); - newMatrix[0][2] = (v[0][0] * other[0][2]) + (v[0][1] * other[1][2]) + (v[0][2] * other[2][2]); - - newMatrix[1][0] = (v[1][0] * other[0][0]) + (v[1][1] * other[1][0]) + (v[1][2] * other[2][0]); - newMatrix[1][1] = (v[1][0] * other[0][1]) + (v[1][1] * other[1][1]) + (v[1][2] * other[2][1]); - newMatrix[1][2] = (v[1][0] * other[0][2]) + (v[1][1] * other[1][2]) + (v[1][2] * other[2][2]); - - newMatrix[2][0] = (v[2][0] * other[0][0]) + (v[2][1] * other[1][0]) + (v[2][2] * other[2][0]); - newMatrix[2][1] = (v[2][0] * other[0][1]) + (v[2][1] * other[1][1]) + (v[2][2] * other[2][1]); - newMatrix[2][2] = (v[2][0] * other[0][2]) + (v[2][1] * other[1][2]) + (v[2][2] * other[2][2]); - - - // Translation - newMatrix[0][3] = v[0][3] + other[0][3]; - newMatrix[1][3] = v[1][3] + other[1][3]; - newMatrix[2][3] = v[2][3] + other[2][3]; - - #endif - - return newMatrix; -} - -void Matrix4x4::operator*=(const Matrix4x4& other) -{ - *this = *this * other; - return; -} - -Matrix4x4 Matrix4x4::operator/(const Matrix4x4& other) const -{ - return *this * other.Inverse3x3(); -} - -void Matrix4x4::operator/=(const Matrix4x4& other) -{ - *this = *this * other.Inverse3x3(); - return; -} - -Matrix4x4 Matrix4x4::operator*(const double scalar) const -{ - Matrix4x4 m; - - #ifndef _EULE_NO_INTRINSICS_ - - // Load matrix rows - __m256d __row0 = _mm256_set_pd(v[0][3], v[0][2], v[0][1], v[0][0]); - __m256d __row1 = _mm256_set_pd(v[1][3], v[1][2], v[1][1], v[1][0]); - __m256d __row2 = _mm256_set_pd(v[2][3], v[2][2], v[2][1], v[2][0]); - __m256d __row3 = _mm256_set_pd(v[3][3], v[3][2], v[3][1], v[3][0]); - - // Load scalar - __m256d __scalar = _mm256_set1_pd(scalar); - - // Scale values - __m256d __sr0 = _mm256_mul_pd(__row0, __scalar); - __m256d __sr1 = _mm256_mul_pd(__row1, __scalar); - __m256d __sr2 = _mm256_mul_pd(__row2, __scalar); - __m256d __sr3 = _mm256_mul_pd(__row3, __scalar); - - // Extract results - _mm256_storeu_pd(m.v[0].data(), __sr0); - _mm256_storeu_pd(m.v[1].data(), __sr1); - _mm256_storeu_pd(m.v[2].data(), __sr2); - _mm256_storeu_pd(m.v[3].data(), __sr3); - - #else - - for (std::size_t x = 0; x < 4; x++) - for (std::size_t y = 0; y < 4; y++) - m[x][y] = v[x][y] * scalar; - - #endif - - return m; -} - -void Matrix4x4::operator*=(const double scalar) -{ - *this = *this * scalar; - return; -} - -Matrix4x4 Matrix4x4::operator/(const double denominator) const -{ - const double precomputeDivision = 1.0 / denominator; - - return *this * precomputeDivision; -} - -void Matrix4x4::operator/=(const double denominator) -{ - *this = *this / denominator; - return; -} - -Matrix4x4 Matrix4x4::operator+(const Matrix4x4& other) const -{ - Matrix4x4 m; - - #ifndef _EULE_NO_INTRINSICS_ - - // Load matrix rows - __m256d __row0a = _mm256_set_pd(v[0][3], v[0][2], v[0][1], v[0][0]); - __m256d __row1a = _mm256_set_pd(v[1][3], v[1][2], v[1][1], v[1][0]); - __m256d __row2a = _mm256_set_pd(v[2][3], v[2][2], v[2][1], v[2][0]); - __m256d __row3a = _mm256_set_pd(v[3][3], v[3][2], v[3][1], v[3][0]); - - __m256d __row0b = _mm256_set_pd(other[0][3], other[0][2], other[0][1], other[0][0]); - __m256d __row1b = _mm256_set_pd(other[1][3], other[1][2], other[1][1], other[1][0]); - __m256d __row2b = _mm256_set_pd(other[2][3], other[2][2], other[2][1], other[2][0]); - __m256d __row3b = _mm256_set_pd(other[3][3], other[3][2], other[3][1], other[3][0]); - - // Add rows - __m256d __sr0 = _mm256_add_pd(__row0a, __row0b); - __m256d __sr1 = _mm256_add_pd(__row1a, __row1b); - __m256d __sr2 = _mm256_add_pd(__row2a, __row2b); - __m256d __sr3 = _mm256_add_pd(__row3a, __row3b); - - // Extract results - _mm256_storeu_pd(m.v[0].data(), __sr0); - _mm256_storeu_pd(m.v[1].data(), __sr1); - _mm256_storeu_pd(m.v[2].data(), __sr2); - _mm256_storeu_pd(m.v[3].data(), __sr3); - - #else - - for (std::size_t x = 0; x < 4; x++) - for (std::size_t y = 0; y < 4; y++) - m[x][y] = v[x][y] + other[x][y]; - - #endif - - return m; -} - -void Matrix4x4::operator+=(const Matrix4x4& other) -{ - #ifndef _EULE_NO_INTRINSICS_ - // Doing it again is a tad directer, and thus faster. We avoid an intermittent Matrix4x4 instance - - // Load matrix rows - __m256d __row0a = _mm256_set_pd(v[0][3], v[0][2], v[0][1], v[0][0]); - __m256d __row1a = _mm256_set_pd(v[1][3], v[1][2], v[1][1], v[1][0]); - __m256d __row2a = _mm256_set_pd(v[2][3], v[2][2], v[2][1], v[2][0]); - __m256d __row3a = _mm256_set_pd(v[3][3], v[3][2], v[3][1], v[3][0]); - - __m256d __row0b = _mm256_set_pd(other[0][3], other[0][2], other[0][1], other[0][0]); - __m256d __row1b = _mm256_set_pd(other[1][3], other[1][2], other[1][1], other[1][0]); - __m256d __row2b = _mm256_set_pd(other[2][3], other[2][2], other[2][1], other[2][0]); - __m256d __row3b = _mm256_set_pd(other[3][3], other[3][2], other[3][1], other[3][0]); - - // Add rows - __m256d __sr0 = _mm256_add_pd(__row0a, __row0b); - __m256d __sr1 = _mm256_add_pd(__row1a, __row1b); - __m256d __sr2 = _mm256_add_pd(__row2a, __row2b); - __m256d __sr3 = _mm256_add_pd(__row3a, __row3b); - - // Extract results - _mm256_storeu_pd(v[0].data(), __sr0); - _mm256_storeu_pd(v[1].data(), __sr1); - _mm256_storeu_pd(v[2].data(), __sr2); - _mm256_storeu_pd(v[3].data(), __sr3); - - #else - - *this = *this + other; - - #endif - - return; -} - -Matrix4x4 Matrix4x4::operator-(const Matrix4x4& other) const -{ - Matrix4x4 m; - - #ifndef _EULE_NO_INTRINSICS_ - - // Load matrix rows - __m256d __row0a = _mm256_set_pd(v[0][3], v[0][2], v[0][1], v[0][0]); - __m256d __row1a = _mm256_set_pd(v[1][3], v[1][2], v[1][1], v[1][0]); - __m256d __row2a = _mm256_set_pd(v[2][3], v[2][2], v[2][1], v[2][0]); - __m256d __row3a = _mm256_set_pd(v[3][3], v[3][2], v[3][1], v[3][0]); - - __m256d __row0b = _mm256_set_pd(other[0][3], other[0][2], other[0][1], other[0][0]); - __m256d __row1b = _mm256_set_pd(other[1][3], other[1][2], other[1][1], other[1][0]); - __m256d __row2b = _mm256_set_pd(other[2][3], other[2][2], other[2][1], other[2][0]); - __m256d __row3b = _mm256_set_pd(other[3][3], other[3][2], other[3][1], other[3][0]); - - // Subtract rows - __m256d __sr0 = _mm256_sub_pd(__row0a, __row0b); - __m256d __sr1 = _mm256_sub_pd(__row1a, __row1b); - __m256d __sr2 = _mm256_sub_pd(__row2a, __row2b); - __m256d __sr3 = _mm256_sub_pd(__row3a, __row3b); - - // Extract results - _mm256_storeu_pd(m.v[0].data(), __sr0); - _mm256_storeu_pd(m.v[1].data(), __sr1); - _mm256_storeu_pd(m.v[2].data(), __sr2); - _mm256_storeu_pd(m.v[3].data(), __sr3); - - #else - - for (std::size_t x = 0; x < 4; x++) - for (std::size_t y = 0; y < 4; y++) - m[x][y] = v[x][y] - other[x][y]; - - #endif - - return m; -} - -void Matrix4x4::operator-=(const Matrix4x4& other) -{ - #ifndef _EULE_NO_INTRINSICS_ - // Doing it again is a tad directer, and thus faster. We avoid an intermittent Matrix4x4 instance - - // Load matrix rows - __m256d __row0a = _mm256_set_pd(v[0][3], v[0][2], v[0][1], v[0][0]); - __m256d __row1a = _mm256_set_pd(v[1][3], v[1][2], v[1][1], v[1][0]); - __m256d __row2a = _mm256_set_pd(v[2][3], v[2][2], v[2][1], v[2][0]); - __m256d __row3a = _mm256_set_pd(v[3][3], v[3][2], v[3][1], v[3][0]); - - __m256d __row0b = _mm256_set_pd(other[0][3], other[0][2], other[0][1], other[0][0]); - __m256d __row1b = _mm256_set_pd(other[1][3], other[1][2], other[1][1], other[1][0]); - __m256d __row2b = _mm256_set_pd(other[2][3], other[2][2], other[2][1], other[2][0]); - __m256d __row3b = _mm256_set_pd(other[3][3], other[3][2], other[3][1], other[3][0]); - - // Subtract rows - __m256d __sr0 = _mm256_sub_pd(__row0a, __row0b); - __m256d __sr1 = _mm256_sub_pd(__row1a, __row1b); - __m256d __sr2 = _mm256_sub_pd(__row2a, __row2b); - __m256d __sr3 = _mm256_sub_pd(__row3a, __row3b); - - // Extract results - _mm256_storeu_pd(v[0].data(), __sr0); - _mm256_storeu_pd(v[1].data(), __sr1); - _mm256_storeu_pd(v[2].data(), __sr2); - _mm256_storeu_pd(v[3].data(), __sr3); - - #else - - * this = *this - other; - - #endif - - return; -} - -std::array& Matrix4x4::operator[](std::size_t y) -{ - return v[y]; -} - -const std::array& Matrix4x4::operator[](std::size_t y) const -{ - return v[y]; -} - -void Matrix4x4::operator=(const Matrix4x4& other) -{ - v = other.v; - return; -} - -void Matrix4x4::operator=(Matrix4x4&& other) noexcept -{ - v = std::move(other.v); - return; -} - -bool Matrix4x4::operator==(const Matrix4x4& other) -{ - return v == other.v; -} - -bool Matrix4x4::operator!=(const Matrix4x4& other) -{ - return !operator==(other); -} - -bool Matrix4x4::operator==(const Matrix4x4& other) const -{ - return v == other.v; -} - -bool Matrix4x4::operator!=(const Matrix4x4& other) const -{ - return !operator==(other); -} - -const Vector3d Matrix4x4::GetTranslationComponent() const -{ - return Vector3d(d, h, l); -} - -void Matrix4x4::SetTranslationComponent(const Vector3d& trans) -{ - d = trans.x; - h = trans.y; - l = trans.z; - return; -} - -Matrix4x4 Matrix4x4::DropTranslationComponents() const -{ - Matrix4x4 m(*this); - m.d = 0; - m.h = 0; - m.l = 0; - return m; -} - -Matrix4x4 Matrix4x4::Transpose3x3() const -{ - Matrix4x4 trans(*this); // Keep other cells - - for (std::size_t i = 0; i < 3; i++) - for (std::size_t j = 0; j < 3; j++) - trans[j][i] = v[i][j]; - - return trans; -} - -Matrix4x4 Matrix4x4::Transpose4x4() const -{ - Matrix4x4 trans; - - for (std::size_t i = 0; i < 4; i++) - for (std::size_t j = 0; j < 4; j++) - trans[j][i] = v[i][j]; - - return trans; -} - -Matrix4x4 Matrix4x4::Multiply4x4(const Matrix4x4& o) const -{ - Matrix4x4 m; - - m[0][0] = (v[0][0]*o[0][0]) + (v[0][1]*o[1][0]) + (v[0][2]*o[2][0]) + (v[0][3]*o[3][0]); - m[0][1] = (v[0][0]*o[0][1]) + (v[0][1]*o[1][1]) + (v[0][2]*o[2][1]) + (v[0][3]*o[3][1]); - m[0][2] = (v[0][0]*o[0][2]) + (v[0][1]*o[1][2]) + (v[0][2]*o[2][2]) + (v[0][3]*o[3][2]); - m[0][3] = (v[0][0]*o[0][3]) + (v[0][1]*o[1][3]) + (v[0][2]*o[2][3]) + (v[0][3]*o[3][3]); - - m[1][0] = (v[1][0]*o[0][0]) + (v[1][1]*o[1][0]) + (v[1][2]*o[2][0]) + (v[1][3]*o[3][0]); - m[1][1] = (v[1][0]*o[0][1]) + (v[1][1]*o[1][1]) + (v[1][2]*o[2][1]) + (v[1][3]*o[3][1]); - m[1][2] = (v[1][0]*o[0][2]) + (v[1][1]*o[1][2]) + (v[1][2]*o[2][2]) + (v[1][3]*o[3][2]); - m[1][3] = (v[1][0]*o[0][3]) + (v[1][1]*o[1][3]) + (v[1][2]*o[2][3]) + (v[1][3]*o[3][3]); - - m[2][0] = (v[2][0]*o[0][0]) + (v[2][1]*o[1][0]) + (v[2][2]*o[2][0]) + (v[2][3]*o[3][0]); - m[2][1] = (v[2][0]*o[0][1]) + (v[2][1]*o[1][1]) + (v[2][2]*o[2][1]) + (v[2][3]*o[3][1]); - m[2][2] = (v[2][0]*o[0][2]) + (v[2][1]*o[1][2]) + (v[2][2]*o[2][2]) + (v[2][3]*o[3][2]); - m[2][3] = (v[2][0]*o[0][3]) + (v[2][1]*o[1][3]) + (v[2][2]*o[2][3]) + (v[2][3]*o[3][3]); - - m[3][0] = (v[3][0]*o[0][0]) + (v[3][1]*o[1][0]) + (v[3][2]*o[2][0]) + (v[3][3]*o[3][0]); - m[3][1] = (v[3][0]*o[0][1]) + (v[3][1]*o[1][1]) + (v[3][2]*o[2][1]) + (v[3][3]*o[3][1]); - m[3][2] = (v[3][0]*o[0][2]) + (v[3][1]*o[1][2]) + (v[3][2]*o[2][2]) + (v[3][3]*o[3][2]); - m[3][3] = (v[3][0]*o[0][3]) + (v[3][1]*o[1][3]) + (v[3][2]*o[2][3]) + (v[3][3]*o[3][3]); - - return m; -} - -Matrix4x4 Matrix4x4::GetCofactors(std::size_t p, std::size_t q, std::size_t n) const -{ - if (n > 4) - throw std::runtime_error("Dimension out of range! 0 <= n <= 4"); - - Matrix4x4 cofs; - - std::size_t i = 0; - std::size_t j = 0; - - for (std::size_t y = 0; y < n; y++) - for (std::size_t x = 0; x < n; x++) - { - if ((y != p) && (x != q)) - { - cofs[i][j] = v[y][x]; - j++; - } - - if (j == n - 1) - { - j = 0; - i++; - } - } - - return cofs; -} + Matrix4x4::Matrix4x4(const Matrix4x4 &other) { + v = other.v; + return; + } + + Matrix4x4::Matrix4x4(Matrix4x4 &&other) noexcept { + v = std::move(other.v); + return; + } + + Matrix4x4 Matrix4x4::operator*(const Matrix4x4 &other) const { + Matrix4x4 newMatrix; + newMatrix.p = 1; + +#ifndef _EULE_NO_INTRINSICS_ + + + /* <= Matrix3x3 multiplication => */ + + // Load matrix components + __m256d __va1 = _mm256_set_pd(v[0][0], v[0][0], v[0][0], v[1][0]); + __m256d __va2 = _mm256_set_pd(v[1][0], v[1][0], v[2][0], v[2][0]); + + __m256d __oa1 = _mm256_set_pd(other[0][0], other[0][1], other[0][2], other[0][0]); + __m256d __oa2 = _mm256_set_pd(other[0][1], other[0][2], other[0][0], other[0][1]); + + __m256d __vb1 = _mm256_set_pd(v[0][1], v[0][1], v[0][1], v[1][1]); + __m256d __vb2 = _mm256_set_pd(v[1][1], v[1][1], v[2][1], v[2][1]); + + __m256d __ob1 = _mm256_set_pd(other[1][0], other[1][1], other[1][2], other[1][0]); + __m256d __ob2 = _mm256_set_pd(other[1][1], other[1][2], other[1][0], other[1][1]); + + __m256d __vc1 = _mm256_set_pd(v[0][2], v[0][2], v[0][2], v[1][2]); + __m256d __vc2 = _mm256_set_pd(v[1][2], v[1][2], v[2][2], v[2][2]); + + __m256d __oc1 = _mm256_set_pd(other[2][0], other[2][1], other[2][2], other[2][0]); + __m256d __oc2 = _mm256_set_pd(other[2][1], other[2][2], other[2][0], other[2][1]); + + // Initialize sums + __m256d __sum1 = _mm256_set1_pd(0); + __m256d __sum2 = _mm256_set1_pd(0); + + // Let's multiply-add them together + // First, the first block + __sum1 = _mm256_fmadd_pd(__va1, __oa1, __sum1); + __sum1 = _mm256_fmadd_pd(__vb1, __ob1, __sum1); + __sum1 = _mm256_fmadd_pd(__vc1, __oc1, __sum1); + + // Then the second block + __sum2 = _mm256_fmadd_pd(__va2, __oa2, __sum2); + __sum2 = _mm256_fmadd_pd(__vb2, __ob2, __sum2); + __sum2 = _mm256_fmadd_pd(__vc2, __oc2, __sum2); + + // Retrieve results + double sum1[4]; + double sum2[4]; + + _mm256_storeu_pd(sum1, __sum1); + _mm256_storeu_pd(sum2, __sum2); + + // Apply results + // Block 1 + newMatrix[0][0] = sum1[3]; + newMatrix[0][1] = sum1[2]; + newMatrix[0][2] = sum1[1]; + newMatrix[1][0] = sum1[0]; + + // Block 2 + newMatrix[1][1] = sum2[3]; + newMatrix[1][2] = sum2[2]; + newMatrix[2][0] = sum2[1]; + newMatrix[2][1] = sum2[0]; + + // Does not fit in the intrinsic calculation. Might just calculate 'by hand'. + newMatrix[2][2] = (v[2][0] * other[0][2]) + (v[2][1] * other[1][2]) + (v[2][2] * other[2][2]); + + + /* <= Translation component => */ + + // Load translation components into registers + __m256d __transSelf = _mm256_set_pd(0, l, h, d); + __m256d __transOther = _mm256_set_pd(0, other.l, other.h, other.d); + + // Let's add them + __m256d __sum = _mm256_add_pd(__transSelf, __transOther); + + // Retrieve results + double sum[4]; + _mm256_storeu_pd(sum, __sum); + + // Apply them + newMatrix.d = sum[0]; + newMatrix.h = sum[1]; + newMatrix.l = sum[2]; + +#else + + + // Rotation, Scaling + newMatrix[0][0] = (v[0][0] * other[0][0]) + (v[0][1] * other[1][0]) + (v[0][2] * other[2][0]); + newMatrix[0][1] = (v[0][0] * other[0][1]) + (v[0][1] * other[1][1]) + (v[0][2] * other[2][1]); + newMatrix[0][2] = (v[0][0] * other[0][2]) + (v[0][1] * other[1][2]) + (v[0][2] * other[2][2]); + + newMatrix[1][0] = (v[1][0] * other[0][0]) + (v[1][1] * other[1][0]) + (v[1][2] * other[2][0]); + newMatrix[1][1] = (v[1][0] * other[0][1]) + (v[1][1] * other[1][1]) + (v[1][2] * other[2][1]); + newMatrix[1][2] = (v[1][0] * other[0][2]) + (v[1][1] * other[1][2]) + (v[1][2] * other[2][2]); + + newMatrix[2][0] = (v[2][0] * other[0][0]) + (v[2][1] * other[1][0]) + (v[2][2] * other[2][0]); + newMatrix[2][1] = (v[2][0] * other[0][1]) + (v[2][1] * other[1][1]) + (v[2][2] * other[2][1]); + newMatrix[2][2] = (v[2][0] * other[0][2]) + (v[2][1] * other[1][2]) + (v[2][2] * other[2][2]); + + + // Translation + newMatrix[0][3] = v[0][3] + other[0][3]; + newMatrix[1][3] = v[1][3] + other[1][3]; + newMatrix[2][3] = v[2][3] + other[2][3]; + +#endif + + return newMatrix; + } + + void Matrix4x4::operator*=(const Matrix4x4 &other) { + *this = *this * other; + return; + } + + Matrix4x4 Matrix4x4::operator/(const Matrix4x4 &other) const { + return *this * other.Inverse3x3(); + } + + void Matrix4x4::operator/=(const Matrix4x4 &other) { + *this = *this * other.Inverse3x3(); + return; + } + + Matrix4x4 Matrix4x4::operator*(const double scalar) const { + Matrix4x4 m; + +#ifndef _EULE_NO_INTRINSICS_ + + // Load matrix rows + __m256d __row0 = _mm256_set_pd(v[0][3], v[0][2], v[0][1], v[0][0]); + __m256d __row1 = _mm256_set_pd(v[1][3], v[1][2], v[1][1], v[1][0]); + __m256d __row2 = _mm256_set_pd(v[2][3], v[2][2], v[2][1], v[2][0]); + __m256d __row3 = _mm256_set_pd(v[3][3], v[3][2], v[3][1], v[3][0]); + + // Load scalar + __m256d __scalar = _mm256_set1_pd(scalar); + + // Scale values + __m256d __sr0 = _mm256_mul_pd(__row0, __scalar); + __m256d __sr1 = _mm256_mul_pd(__row1, __scalar); + __m256d __sr2 = _mm256_mul_pd(__row2, __scalar); + __m256d __sr3 = _mm256_mul_pd(__row3, __scalar); + + // Extract results + _mm256_storeu_pd(m.v[0].data(), __sr0); + _mm256_storeu_pd(m.v[1].data(), __sr1); + _mm256_storeu_pd(m.v[2].data(), __sr2); + _mm256_storeu_pd(m.v[3].data(), __sr3); + +#else + + for (std::size_t x = 0; x < 4; x++) + for (std::size_t y = 0; y < 4; y++) + m[x][y] = v[x][y] * scalar; + +#endif + + return m; + } + + void Matrix4x4::operator*=(const double scalar) { + *this = *this * scalar; + return; + } + + Matrix4x4 Matrix4x4::operator/(const double denominator) const { + const double precomputeDivision = 1.0 / denominator; + + return *this * precomputeDivision; + } + + void Matrix4x4::operator/=(const double denominator) { + *this = *this / denominator; + return; + } + + Matrix4x4 Matrix4x4::operator+(const Matrix4x4 &other) const { + Matrix4x4 m; + +#ifndef _EULE_NO_INTRINSICS_ + + // Load matrix rows + __m256d __row0a = _mm256_set_pd(v[0][3], v[0][2], v[0][1], v[0][0]); + __m256d __row1a = _mm256_set_pd(v[1][3], v[1][2], v[1][1], v[1][0]); + __m256d __row2a = _mm256_set_pd(v[2][3], v[2][2], v[2][1], v[2][0]); + __m256d __row3a = _mm256_set_pd(v[3][3], v[3][2], v[3][1], v[3][0]); + + __m256d __row0b = _mm256_set_pd(other[0][3], other[0][2], other[0][1], other[0][0]); + __m256d __row1b = _mm256_set_pd(other[1][3], other[1][2], other[1][1], other[1][0]); + __m256d __row2b = _mm256_set_pd(other[2][3], other[2][2], other[2][1], other[2][0]); + __m256d __row3b = _mm256_set_pd(other[3][3], other[3][2], other[3][1], other[3][0]); + + // Add rows + __m256d __sr0 = _mm256_add_pd(__row0a, __row0b); + __m256d __sr1 = _mm256_add_pd(__row1a, __row1b); + __m256d __sr2 = _mm256_add_pd(__row2a, __row2b); + __m256d __sr3 = _mm256_add_pd(__row3a, __row3b); + + // Extract results + _mm256_storeu_pd(m.v[0].data(), __sr0); + _mm256_storeu_pd(m.v[1].data(), __sr1); + _mm256_storeu_pd(m.v[2].data(), __sr2); + _mm256_storeu_pd(m.v[3].data(), __sr3); + +#else + + for (std::size_t x = 0; x < 4; x++) + for (std::size_t y = 0; y < 4; y++) + m[x][y] = v[x][y] + other[x][y]; + +#endif + + return m; + } + + void Matrix4x4::operator+=(const Matrix4x4 &other) { +#ifndef _EULE_NO_INTRINSICS_ + // Doing it again is a tad directer, and thus faster. We avoid an intermittent Matrix4x4 instance + + // Load matrix rows + __m256d __row0a = _mm256_set_pd(v[0][3], v[0][2], v[0][1], v[0][0]); + __m256d __row1a = _mm256_set_pd(v[1][3], v[1][2], v[1][1], v[1][0]); + __m256d __row2a = _mm256_set_pd(v[2][3], v[2][2], v[2][1], v[2][0]); + __m256d __row3a = _mm256_set_pd(v[3][3], v[3][2], v[3][1], v[3][0]); + + __m256d __row0b = _mm256_set_pd(other[0][3], other[0][2], other[0][1], other[0][0]); + __m256d __row1b = _mm256_set_pd(other[1][3], other[1][2], other[1][1], other[1][0]); + __m256d __row2b = _mm256_set_pd(other[2][3], other[2][2], other[2][1], other[2][0]); + __m256d __row3b = _mm256_set_pd(other[3][3], other[3][2], other[3][1], other[3][0]); + + // Add rows + __m256d __sr0 = _mm256_add_pd(__row0a, __row0b); + __m256d __sr1 = _mm256_add_pd(__row1a, __row1b); + __m256d __sr2 = _mm256_add_pd(__row2a, __row2b); + __m256d __sr3 = _mm256_add_pd(__row3a, __row3b); + + // Extract results + _mm256_storeu_pd(v[0].data(), __sr0); + _mm256_storeu_pd(v[1].data(), __sr1); + _mm256_storeu_pd(v[2].data(), __sr2); + _mm256_storeu_pd(v[3].data(), __sr3); + +#else + + *this = *this + other; + +#endif + + return; + } + + Matrix4x4 Matrix4x4::operator-(const Matrix4x4 &other) const { + Matrix4x4 m; + +#ifndef _EULE_NO_INTRINSICS_ + + // Load matrix rows + __m256d __row0a = _mm256_set_pd(v[0][3], v[0][2], v[0][1], v[0][0]); + __m256d __row1a = _mm256_set_pd(v[1][3], v[1][2], v[1][1], v[1][0]); + __m256d __row2a = _mm256_set_pd(v[2][3], v[2][2], v[2][1], v[2][0]); + __m256d __row3a = _mm256_set_pd(v[3][3], v[3][2], v[3][1], v[3][0]); + + __m256d __row0b = _mm256_set_pd(other[0][3], other[0][2], other[0][1], other[0][0]); + __m256d __row1b = _mm256_set_pd(other[1][3], other[1][2], other[1][1], other[1][0]); + __m256d __row2b = _mm256_set_pd(other[2][3], other[2][2], other[2][1], other[2][0]); + __m256d __row3b = _mm256_set_pd(other[3][3], other[3][2], other[3][1], other[3][0]); + + // Subtract rows + __m256d __sr0 = _mm256_sub_pd(__row0a, __row0b); + __m256d __sr1 = _mm256_sub_pd(__row1a, __row1b); + __m256d __sr2 = _mm256_sub_pd(__row2a, __row2b); + __m256d __sr3 = _mm256_sub_pd(__row3a, __row3b); + + // Extract results + _mm256_storeu_pd(m.v[0].data(), __sr0); + _mm256_storeu_pd(m.v[1].data(), __sr1); + _mm256_storeu_pd(m.v[2].data(), __sr2); + _mm256_storeu_pd(m.v[3].data(), __sr3); + +#else + + for (std::size_t x = 0; x < 4; x++) + for (std::size_t y = 0; y < 4; y++) + m[x][y] = v[x][y] - other[x][y]; + +#endif + + return m; + } + + void Matrix4x4::operator-=(const Matrix4x4 &other) { +#ifndef _EULE_NO_INTRINSICS_ + // Doing it again is a tad directer, and thus faster. We avoid an intermittent Matrix4x4 instance + + // Load matrix rows + __m256d __row0a = _mm256_set_pd(v[0][3], v[0][2], v[0][1], v[0][0]); + __m256d __row1a = _mm256_set_pd(v[1][3], v[1][2], v[1][1], v[1][0]); + __m256d __row2a = _mm256_set_pd(v[2][3], v[2][2], v[2][1], v[2][0]); + __m256d __row3a = _mm256_set_pd(v[3][3], v[3][2], v[3][1], v[3][0]); + + __m256d __row0b = _mm256_set_pd(other[0][3], other[0][2], other[0][1], other[0][0]); + __m256d __row1b = _mm256_set_pd(other[1][3], other[1][2], other[1][1], other[1][0]); + __m256d __row2b = _mm256_set_pd(other[2][3], other[2][2], other[2][1], other[2][0]); + __m256d __row3b = _mm256_set_pd(other[3][3], other[3][2], other[3][1], other[3][0]); + + // Subtract rows + __m256d __sr0 = _mm256_sub_pd(__row0a, __row0b); + __m256d __sr1 = _mm256_sub_pd(__row1a, __row1b); + __m256d __sr2 = _mm256_sub_pd(__row2a, __row2b); + __m256d __sr3 = _mm256_sub_pd(__row3a, __row3b); + + // Extract results + _mm256_storeu_pd(v[0].data(), __sr0); + _mm256_storeu_pd(v[1].data(), __sr1); + _mm256_storeu_pd(v[2].data(), __sr2); + _mm256_storeu_pd(v[3].data(), __sr3); + +#else + + *this = *this - other; + +#endif + + return; + } + + std::array &Matrix4x4::operator[](std::size_t y) { + return v[y]; + } + + const std::array &Matrix4x4::operator[](std::size_t y) const { + return v[y]; + } + + void Matrix4x4::operator=(const Matrix4x4 &other) { + v = other.v; + return; + } + + void Matrix4x4::operator=(Matrix4x4 &&other) noexcept { + v = std::move(other.v); + return; + } + + bool Matrix4x4::operator==(const Matrix4x4 &other) { + return v == other.v; + } + + bool Matrix4x4::operator!=(const Matrix4x4 &other) { + return !operator==(other); + } + + bool Matrix4x4::operator==(const Matrix4x4 &other) const { + return v == other.v; + } + + bool Matrix4x4::operator!=(const Matrix4x4 &other) const { + return !operator==(other); + } + + const Vector3d Matrix4x4::GetTranslationComponent() const { + return Vector3d(d, h, l); + } + + void Matrix4x4::SetTranslationComponent(const Vector3d &trans) { + d = trans.x; + h = trans.y; + l = trans.z; + return; + } + + Matrix4x4 Matrix4x4::DropTranslationComponents() const { + Matrix4x4 m(*this); + m.d = 0; + m.h = 0; + m.l = 0; + return m; + } + + Matrix4x4 Matrix4x4::Transpose3x3() const { + Matrix4x4 trans(*this); // Keep other cells + + for (std::size_t i = 0; i < 3; i++) + for (std::size_t j = 0; j < 3; j++) + trans[j][i] = v[i][j]; + + return trans; + } + + Matrix4x4 Matrix4x4::Transpose4x4() const { + Matrix4x4 trans; + + for (std::size_t i = 0; i < 4; i++) + for (std::size_t j = 0; j < 4; j++) + trans[j][i] = v[i][j]; + + return trans; + } + + Matrix4x4 Matrix4x4::Multiply4x4(const Matrix4x4 &o) const { + Matrix4x4 m; + + m[0][0] = (v[0][0] * o[0][0]) + (v[0][1] * o[1][0]) + (v[0][2] * o[2][0]) + (v[0][3] * o[3][0]); + m[0][1] = (v[0][0] * o[0][1]) + (v[0][1] * o[1][1]) + (v[0][2] * o[2][1]) + (v[0][3] * o[3][1]); + m[0][2] = (v[0][0] * o[0][2]) + (v[0][1] * o[1][2]) + (v[0][2] * o[2][2]) + (v[0][3] * o[3][2]); + m[0][3] = (v[0][0] * o[0][3]) + (v[0][1] * o[1][3]) + (v[0][2] * o[2][3]) + (v[0][3] * o[3][3]); + + m[1][0] = (v[1][0] * o[0][0]) + (v[1][1] * o[1][0]) + (v[1][2] * o[2][0]) + (v[1][3] * o[3][0]); + m[1][1] = (v[1][0] * o[0][1]) + (v[1][1] * o[1][1]) + (v[1][2] * o[2][1]) + (v[1][3] * o[3][1]); + m[1][2] = (v[1][0] * o[0][2]) + (v[1][1] * o[1][2]) + (v[1][2] * o[2][2]) + (v[1][3] * o[3][2]); + m[1][3] = (v[1][0] * o[0][3]) + (v[1][1] * o[1][3]) + (v[1][2] * o[2][3]) + (v[1][3] * o[3][3]); + + m[2][0] = (v[2][0] * o[0][0]) + (v[2][1] * o[1][0]) + (v[2][2] * o[2][0]) + (v[2][3] * o[3][0]); + m[2][1] = (v[2][0] * o[0][1]) + (v[2][1] * o[1][1]) + (v[2][2] * o[2][1]) + (v[2][3] * o[3][1]); + m[2][2] = (v[2][0] * o[0][2]) + (v[2][1] * o[1][2]) + (v[2][2] * o[2][2]) + (v[2][3] * o[3][2]); + m[2][3] = (v[2][0] * o[0][3]) + (v[2][1] * o[1][3]) + (v[2][2] * o[2][3]) + (v[2][3] * o[3][3]); + + m[3][0] = (v[3][0] * o[0][0]) + (v[3][1] * o[1][0]) + (v[3][2] * o[2][0]) + (v[3][3] * o[3][0]); + m[3][1] = (v[3][0] * o[0][1]) + (v[3][1] * o[1][1]) + (v[3][2] * o[2][1]) + (v[3][3] * o[3][1]); + m[3][2] = (v[3][0] * o[0][2]) + (v[3][1] * o[1][2]) + (v[3][2] * o[2][2]) + (v[3][3] * o[3][2]); + m[3][3] = (v[3][0] * o[0][3]) + (v[3][1] * o[1][3]) + (v[3][2] * o[2][3]) + (v[3][3] * o[3][3]); + + return m; + } + + Matrix4x4 Matrix4x4::GetCofactors(std::size_t p, std::size_t q, std::size_t n) const { + if (n > 4) + throw std::runtime_error("Dimension out of range! 0 <= n <= 4"); + + Matrix4x4 cofs; + + std::size_t i = 0; + std::size_t j = 0; + + for (std::size_t y = 0; y < n; y++) + for (std::size_t x = 0; x < n; x++) { + if ((y != p) && (x != q)) { + cofs[i][j] = v[y][x]; + j++; + } + + if (j == n - 1) { + j = 0; + i++; + } + } + + return cofs; + } /* * BEGIN_REF * https://www.geeksforgeeks.org/adjoint-inverse-matrix/ */ -double Matrix4x4::Determinant(std::size_t n) const -{ - if (n > 4) - throw std::runtime_error("Dimension out of range! 0 <= n <= 4"); + double Matrix4x4::Determinant(std::size_t n) const { + if (n > 4) + throw std::runtime_error("Dimension out of range! 0 <= n <= 4"); - double d = 0; - double sign = 1; + double d = 0; + double sign = 1; - if (n == 1) - return v[0][0]; + if (n == 1) + return v[0][0]; - for (std::size_t x = 0; x < n; x++) - { - Matrix4x4 cofs = GetCofactors(0, x, n); + for (std::size_t x = 0; x < n; x++) { + Matrix4x4 cofs = GetCofactors(0, x, n); - d += sign * v[0][x] * cofs.Determinant(n - 1); - sign = -sign; - } + d += sign * v[0][x] * cofs.Determinant(n - 1); + sign = -sign; + } - return d; -} + return d; + } -Matrix4x4 Matrix4x4::Adjoint(std::size_t n) const -{ - if (n > 4) - throw std::runtime_error("Dimension out of range! 0 <= n <= 4"); + Matrix4x4 Matrix4x4::Adjoint(std::size_t n) const { + if (n > 4) + throw std::runtime_error("Dimension out of range! 0 <= n <= 4"); - Matrix4x4 adj; - double sign = 1; + Matrix4x4 adj; + double sign = 1; - for (std::size_t i = 0; i < n; i++) - for (std::size_t j = 0; j < n; j++) - { - Matrix4x4 cofs = GetCofactors(i, j, n); + for (std::size_t i = 0; i < n; i++) + for (std::size_t j = 0; j < n; j++) { + Matrix4x4 cofs = GetCofactors(i, j, n); - // sign of adj[j][i] positive if sum of row - // and column indexes is even. - sign = ((i + j) % 2 == 0) ? 1 : -1; + // sign of adj[j][i] positive if sum of row + // and column indexes is even. + sign = ((i + j) % 2 == 0) ? 1 : -1; - // Interchanging rows and columns to get the - // transpose of the cofactor matrix - adj[j][i] = sign * (cofs.Determinant(n - 1)); - } + // Interchanging rows and columns to get the + // transpose of the cofactor matrix + adj[j][i] = sign * (cofs.Determinant(n - 1)); + } - return adj; -} + return adj; + } -Matrix4x4 Matrix4x4::Inverse3x3() const -{ - Matrix4x4 inv; + Matrix4x4 Matrix4x4::Inverse3x3() const { + Matrix4x4 inv; - double det = Determinant(3); - if (det == 0.0) - throw std::runtime_error("Matrix3x3 not inversible!"); + double det = Determinant(3); + if (det == 0.0) + throw std::runtime_error("Matrix3x3 not inversible!"); - Matrix4x4 adj = Adjoint(3); + Matrix4x4 adj = Adjoint(3); - for (std::size_t i = 0; i < 3; i++) - for (std::size_t j = 0; j < 3; j++) - inv[i][j] = adj[i][j] / det; + for (std::size_t i = 0; i < 3; i++) + for (std::size_t j = 0; j < 3; j++) + inv[i][j] = adj[i][j] / det; - inv.SetTranslationComponent(-GetTranslationComponent()); + inv.SetTranslationComponent(-GetTranslationComponent()); - return inv; -} + return inv; + } -Matrix4x4 Matrix4x4::Inverse4x4() const -{ - Matrix4x4 inv; + Matrix4x4 Matrix4x4::Inverse4x4() const { + Matrix4x4 inv; - double det = Determinant(4); - if (det == 0.0) - throw std::runtime_error("Matrix4x4 not inversible!"); + double det = Determinant(4); + if (det == 0.0) + throw std::runtime_error("Matrix4x4 not inversible!"); - Matrix4x4 adj = Adjoint(4); + Matrix4x4 adj = Adjoint(4); - for (std::size_t i = 0; i < 4; i++) - for (std::size_t j = 0; j < 4; j++) - inv[i][j] = adj[i][j] / det; + for (std::size_t i = 0; i < 4; i++) + for (std::size_t j = 0; j < 4; j++) + inv[i][j] = adj[i][j] / det; - return inv; -} + return inv; + } /* * END REF */ -bool Matrix4x4::IsInversible3x3() const -{ - return (Determinant(3) != 0); -} - -bool Matrix4x4::IsInversible4x4() const -{ - return (Determinant(4) != 0); -} - -bool Matrix4x4::Similar(const Matrix4x4& other, double epsilon) const -{ - for (std::size_t i = 0; i < 4; i++) - for (std::size_t j = 0; j < 4; j++) - if (!Math::Similar(v[i][j], other[i][j], epsilon)) - return false; - - return true; -} - -namespace Eule -{ - std::ostream& operator<< (std::ostream& os, const Matrix4x4& m) - { - os << std::endl; - - for (std::size_t y = 0; y < 4; y++) - { - for (std::size_t x = 0; x < 4; x++) - os << " | " << m[y][x]; - - os << " |" << std::endl; - } - - return os; - } - - std::wostream& operator<< (std::wostream& os, const Matrix4x4& m) - { - os << std::endl; - - for (std::size_t y = 0; y < 4; y++) - { - for (std::size_t x = 0; x < 4; x++) - os << L" | " << m[y][x]; - - os << L" |" << std::endl; - } - - return os; - } + bool Matrix4x4::IsInversible3x3() const { + return (Determinant(3) != 0); + } + + bool Matrix4x4::IsInversible4x4() const { + return (Determinant(4) != 0); + } + + bool Matrix4x4::Similar(const Matrix4x4 &other, double epsilon) const { + for (std::size_t i = 0; i < 4; i++) + for (std::size_t j = 0; j < 4; j++) + if (!Math::Similar(v[i][j], other[i][j], epsilon)) + return false; + + return true; + } + + namespace Eule { + std::ostream &operator<<(std::ostream &os, const Matrix4x4 &m) { + os << std::endl; + + for (std::size_t y = 0; y < 4; y++) { + for (std::size_t x = 0; x < 4; x++) + os << " | " << m[y][x]; + + os << " |" << std::endl; + } + + return os; + } + + std::wostream &operator<<(std::wostream &os, const Matrix4x4 &m) { + os << std::endl; + + for (std::size_t y = 0; y < 4; y++) { + for (std::size_t x = 0; x < 4; x++) + os << L" | " << m[y][x]; + + os << L" |" << std::endl; + } + + return os; + } + } } diff --git a/Eule/Matrix4x4.h b/Eule/Matrix4x4.h index b27c010..3b68276 100644 --- a/Eule/Matrix4x4.h +++ b/Eule/Matrix4x4.h @@ -3,7 +3,7 @@ #include #include -namespace Eule +namespace Leonetienne::Eule { template class Vector3; diff --git a/Eule/Quaternion.cpp b/Eule/Quaternion.cpp index 79fd915..8e38de1 100644 --- a/Eule/Quaternion.cpp +++ b/Eule/Quaternion.cpp @@ -10,7 +10,7 @@ #include "gcccompat.h" #endif -namespace Eule { +namespace Leonetienne::Eule { Quaternion::Quaternion() { diff --git a/Eule/Quaternion.h b/Eule/Quaternion.h index 5a13de6..200fbf4 100644 --- a/Eule/Quaternion.h +++ b/Eule/Quaternion.h @@ -4,7 +4,7 @@ #include "Matrix4x4.h" #include -namespace Eule +namespace Leonetienne::Eule { /** 3D rotation representation */ diff --git a/Eule/Random.cpp b/Eule/Random.cpp index 589b632..a472855 100644 --- a/Eule/Random.cpp +++ b/Eule/Random.cpp @@ -2,75 +2,68 @@ #include #include -using namespace Eule; - +namespace Leonetienne::Eule { // Checks if the random number generator is initialized. Does nothing if it is, initializes if it isn't. #define MAKE_SURE_RNG_IS_INITIALIZED if (!isRngInitialized) InitRng(); -void Random::InitRng() -{ - // Create truly random source (from hardware events) - std::random_device randomSource; + void Random::InitRng() { + // Create truly random source (from hardware events) + std::random_device randomSource; - // Generate enough truly random values to populate the entire state of the mersenne twister - std::array seedValues; - std::generate_n(seedValues.data(), seedValues.size(), std::ref(randomSource)); - std::seed_seq seedSequence(seedValues.begin(), seedValues.end()); + // Generate enough truly random values to populate the entire state of the mersenne twister + std::array seedValues; + std::generate_n(seedValues.data(), seedValues.size(), std::ref(randomSource)); + std::seed_seq seedSequence(seedValues.begin(), seedValues.end()); - // Seed the mersenne twister with these values - rng = std::mt19937(seedSequence); + // Seed the mersenne twister with these values + rng = std::mt19937(seedSequence); - isRngInitialized = true; + isRngInitialized = true; - return; -} + return; + } // Will return a random double between 0 and 1 -double Random::RandomFloat() -{ - MAKE_SURE_RNG_IS_INITIALIZED; + double Random::RandomFloat() { + MAKE_SURE_RNG_IS_INITIALIZED; - return (rng() % 694206942069ll) / 694206942069.0; -} + return (rng() % 694206942069ll) / 694206942069.0; + } // Will return a random unsigned integer. -unsigned int Random::RandomUint() -{ - MAKE_SURE_RNG_IS_INITIALIZED; + unsigned int Random::RandomUint() { + MAKE_SURE_RNG_IS_INITIALIZED; - return rng(); -} + return rng(); + } // Will return a random integer -unsigned int Random::RandomInt() -{ - MAKE_SURE_RNG_IS_INITIALIZED; + unsigned int Random::RandomInt() { + MAKE_SURE_RNG_IS_INITIALIZED; - // Since this is supposed to return a random value anyways, - // we can let the random uint overflow without any problems. - return (int)rng(); -} + // Since this is supposed to return a random value anyways, + // we can let the random uint overflow without any problems. + return (int) rng(); + } // Will return a random double within a range // These bounds are INCLUSIVE! -double Random::RandomRange(double min, double max) -{ - return (RandomFloat() * (max - min)) + min; -} + double Random::RandomRange(double min, double max) { + return (RandomFloat() * (max - min)) + min; + } // Will return a random integer within a range. This is faster than '(int)RandomRange(x,y)' // These bounds are INCLUSIVE! -int Random::RandomIntRange(int min, int max) -{ - MAKE_SURE_RNG_IS_INITIALIZED; + int Random::RandomIntRange(int min, int max) { + MAKE_SURE_RNG_IS_INITIALIZED; - return (rng() % (max + 1 - min)) + min; + return (rng() % (max + 1 - min)) + min; + } + + bool Random::RandomChance(const double chance) { + return RandomFloat() <= chance; + } + + std::mt19937 Random::rng; + bool Random::isRngInitialized = false; } - -bool Random::RandomChance(const double chance) -{ - return RandomFloat() <= chance; -} - -std::mt19937 Random::rng; -bool Random::isRngInitialized = false; diff --git a/Eule/Random.h b/Eule/Random.h index 912a5f8..20ef78f 100644 --- a/Eule/Random.h +++ b/Eule/Random.h @@ -1,7 +1,7 @@ #pragma once #include -namespace Eule +namespace Leonetienne::Eule { /** Extensive random number generator */ diff --git a/Eule/Rect.h b/Eule/Rect.h index 05c2039..e5ad4ec 100644 --- a/Eule/Rect.h +++ b/Eule/Rect.h @@ -1,7 +1,7 @@ #pragma once #include "../Eule/Vector2.h" -namespace Eule +namespace Leonetienne::Eule { /** Trivial data structure representing a rectangle */ diff --git a/Eule/TrapazoidalPrismCollider.cpp b/Eule/TrapazoidalPrismCollider.cpp index f423812..a729c5b 100644 --- a/Eule/TrapazoidalPrismCollider.cpp +++ b/Eule/TrapazoidalPrismCollider.cpp @@ -1,6 +1,6 @@ #include "TrapazoidalPrismCollider.h" -using namespace Eule; +using namespace Leonetienne::Eule; TrapazoidalPrismCollider::TrapazoidalPrismCollider() { diff --git a/Eule/TrapazoidalPrismCollider.h b/Eule/TrapazoidalPrismCollider.h index 1dda614..a95242e 100644 --- a/Eule/TrapazoidalPrismCollider.h +++ b/Eule/TrapazoidalPrismCollider.h @@ -3,7 +3,7 @@ #include "Collider.h" #include -namespace Eule +namespace Leonetienne::Eule { /** A collider describing a trapazoidal prism. * A trapazoidal prism is basically a box, but each vertex can be manipulated individually, altering diff --git a/Eule/Vector2.cpp b/Eule/Vector2.cpp index 25eddc8..0f1398b 100644 --- a/Eule/Vector2.cpp +++ b/Eule/Vector2.cpp @@ -19,7 +19,7 @@ The T=int instantiation only exists to store a value-pair of two ints. Not so-much as a vector in terms of vector calculus. */ -namespace Eule { +namespace Leonetienne::Eule { template Vector2::operator Vector3() const @@ -322,8 +322,8 @@ namespace Eule { bool Vector2::Similar(const Vector2& other, double epsilon) const { return - (::Eule::Math::Similar(x, other.x, epsilon)) && - (::Eule::Math::Similar(y, other.y, epsilon)) + (::Leonetienne::Eule::Math::Similar(x, other.x, epsilon)) && + (::Leonetienne::Eule::Math::Similar(y, other.y, epsilon)) ; } diff --git a/Eule/Vector2.h b/Eule/Vector2.h index 810d522..3ef292a 100644 --- a/Eule/Vector2.h +++ b/Eule/Vector2.h @@ -2,7 +2,7 @@ #include #include -namespace Eule { +namespace Leonetienne::Eule { template class Vector3; diff --git a/Eule/Vector3.cpp b/Eule/Vector3.cpp index 9f09945..794e594 100644 --- a/Eule/Vector3.cpp +++ b/Eule/Vector3.cpp @@ -19,7 +19,7 @@ The T=int instantiation only exists to store a value-pair of two ints. Not so-much as a vector in terms of vector calculus. */ -namespace Eule { +namespace Leonetienne::Eule { template Vector3::operator Vector2() const { @@ -235,9 +235,9 @@ namespace Eule { bool Vector3::Similar(const Vector3& other, double epsilon) const { return - (::Eule::Math::Similar(x, other.x, epsilon)) && - (::Eule::Math::Similar(y, other.y, epsilon)) && - (::Eule::Math::Similar(z, other.z, epsilon)) + (::Leonetienne::Eule::Math::Similar(x, other.x, epsilon)) && + (::Leonetienne::Eule::Math::Similar(y, other.y, epsilon)) && + (::Leonetienne::Eule::Math::Similar(z, other.z, epsilon)) ; } diff --git a/Eule/Vector3.h b/Eule/Vector3.h index c8dd141..a4ff071 100644 --- a/Eule/Vector3.h +++ b/Eule/Vector3.h @@ -5,7 +5,7 @@ #include #include "Matrix4x4.h" -namespace Eule { +namespace Leonetienne::Eule { template class Vector2; diff --git a/Eule/Vector4.cpp b/Eule/Vector4.cpp index 5fd23b6..caa9983 100644 --- a/Eule/Vector4.cpp +++ b/Eule/Vector4.cpp @@ -19,7 +19,7 @@ The T=int instantiation only exists to store a value-pair of two ints. Not so-much as a vector in terms of vector calculus. */ -namespace Eule { +namespace Leonetienne::Eule { template Vector4::operator Vector2() const @@ -183,10 +183,10 @@ namespace Eule { bool Vector4::Similar(const Vector4& other, double epsilon) const { return - (::Eule::Math::Similar(x, other.x, epsilon)) && - (::Eule::Math::Similar(y, other.y, epsilon)) && - (::Eule::Math::Similar(z, other.z, epsilon)) && - (::Eule::Math::Similar(w, other.w, epsilon)) + (::Leonetienne::Eule::Math::Similar(x, other.x, epsilon)) && + (::Leonetienne::Eule::Math::Similar(y, other.y, epsilon)) && + (::Leonetienne::Eule::Math::Similar(z, other.z, epsilon)) && + (::Leonetienne::Eule::Math::Similar(w, other.w, epsilon)) ; } diff --git a/Eule/Vector4.h b/Eule/Vector4.h index 0f34b4f..d423404 100644 --- a/Eule/Vector4.h +++ b/Eule/Vector4.h @@ -5,7 +5,7 @@ #include #include "Matrix4x4.h" -namespace Eule +namespace Leonetienne::Eule { template class Vector2; template class Vector3;