diff --git a/src/Math/Matrix.h b/src/Math/Matrix.h index f639cd96a..11f1c739e 100644 --- a/src/Math/Matrix.h +++ b/src/Math/Matrix.h @@ -108,7 +108,8 @@ template class Matrix: public RectangularMatrix class Matrix3: public Matrix<3, T> { /** @brief Copy constructor */ inline constexpr Matrix3(const RectangularMatrix<3, 3, T>& other): Matrix<3, T>(other) {} + /** + * @brief Check whether the matrix represents rigid transformation + * + * Rigid transformation consists only of rotation and translation (i.e. + * no scaling or projection). + * @see isOrthogonal() + */ + inline bool isRigidTransformation() const { + return rotationScaling().isOrthogonal() && row(2) == Vector3(T(0), T(0), T(1)); + } + /** * @brief 2D rotation and scaling part of the matrix * diff --git a/src/Math/Matrix4.h b/src/Math/Matrix4.h index 3676f5ecc..fdefc41b1 100644 --- a/src/Math/Matrix4.h +++ b/src/Math/Matrix4.h @@ -283,6 +283,17 @@ template class Matrix4: public Matrix<4, T> { /** @brief Copy constructor */ inline constexpr Matrix4(const RectangularMatrix<4, 4, T>& other): Matrix<4, T>(other) {} + /** + * @brief Check whether the matrix represents rigid transformation + * + * Rigid transformation consists only of rotation and translation (i.e. + * no scaling or projection). + * @see isOrthogonal() + */ + inline bool isRigidTransformation() const { + return rotationScaling().isOrthogonal() && row(3) == Vector4(T(0), T(0), T(0), T(1)); + } + /** * @brief 3D rotation and scaling part of the matrix * diff --git a/src/Math/Test/Matrix3Test.cpp b/src/Math/Test/Matrix3Test.cpp index ce0423c6e..71a14458e 100644 --- a/src/Math/Test/Matrix3Test.cpp +++ b/src/Math/Test/Matrix3Test.cpp @@ -40,6 +40,8 @@ class Matrix3Test: public Corrade::TestSuite::Tester { void constructConversion(); void constructCopy(); + void isRigidTransformation(); + void translation(); void scaling(); void rotation(); @@ -69,6 +71,8 @@ Matrix3Test::Matrix3Test() { &Matrix3Test::constructConversion, &Matrix3Test::constructCopy, + &Matrix3Test::isRigidTransformation, + &Matrix3Test::translation, &Matrix3Test::scaling, &Matrix3Test::rotation, @@ -143,6 +147,18 @@ void Matrix3Test::constructCopy() { {7.9f, -1.0f, 8.0f})); } +void Matrix3Test::isRigidTransformation() { + CORRADE_VERIFY(!Matrix3({1.0f, 0.0f, 0.0f}, + {0.1f, 1.0f, 0.0f}, + {5.0f, 4.0f, 1.0f}).isRigidTransformation()); + CORRADE_VERIFY(!Matrix3({1.0f, 0.0f, 0.0f}, + {0.0f, 1.0f, 1.0f}, + {5.0f, 4.0f, 0.0f}).isRigidTransformation()); + CORRADE_VERIFY(Matrix3({1.0f, 0.0f, 0.0f}, + {0.0f, 1.0f, 0.0f}, + {5.0f, 4.0f, 1.0f}).isRigidTransformation()); +} + void Matrix3Test::translation() { constexpr Matrix3 a = Matrix3::translation({3.0f, 1.0f}); CORRADE_COMPARE(a, Matrix3({1.0f, 0.0f, 0.0f}, diff --git a/src/Math/Test/Matrix4Test.cpp b/src/Math/Test/Matrix4Test.cpp index c201a5688..c7e2826c9 100644 --- a/src/Math/Test/Matrix4Test.cpp +++ b/src/Math/Test/Matrix4Test.cpp @@ -40,6 +40,8 @@ class Matrix4Test: public Corrade::TestSuite::Tester { void constructConversion(); void constructCopy(); + void isRigidTransformation(); + void translation(); void scaling(); void rotation(); @@ -75,6 +77,8 @@ Matrix4Test::Matrix4Test() { &Matrix4Test::constructConversion, &Matrix4Test::constructCopy, + &Matrix4Test::isRigidTransformation, + &Matrix4Test::translation, &Matrix4Test::scaling, &Matrix4Test::rotation, @@ -164,6 +168,21 @@ void Matrix4Test::constructCopy() { {7.9f, -1.0f, 8.0f, -1.5f})); } +void Matrix4Test::isRigidTransformation() { + CORRADE_VERIFY(!Matrix4({1.0f, 0.0f, 0.0f, 0.0f}, + {0.0f, 1.0f, 0.0f, 0.0f}, + {0.0f, 0.1f, 1.0f, 0.0f}, + {5.0f, 4.0f, 0.5f, 1.0f}).isRigidTransformation()); + CORRADE_VERIFY(!Matrix4({1.0f, 0.0f, 0.0f, 0.0f}, + {0.1f, 1.0f, 0.0f, 0.0f}, + {0.0f, 0.0f, 1.0f, 1.0f}, + {5.0f, 4.0f, 0.5f, 0.0f}).isRigidTransformation()); + CORRADE_VERIFY(Matrix4({1.0f, 0.0f, 0.0f, 0.0f}, + {0.0f, 1.0f, 0.0f, 0.0f}, + {0.0f, 0.0f, 1.0f, 0.0f}, + {5.0f, 4.0f, 0.5f, 1.0f}).isRigidTransformation()); +} + void Matrix4Test::translation() { constexpr Matrix4 a = Matrix4::translation({3.0f, 1.0f, 2.0f}); CORRADE_COMPARE(a, Matrix4({1.0f, 0.0f, 0.0f, 0.0f},