diff --git a/src/Math/Matrix3.h b/src/Math/Matrix3.h index 20910638d..ddf8431ae 100644 --- a/src/Math/Matrix3.h +++ b/src/Math/Matrix3.h @@ -83,6 +83,23 @@ template class Matrix3: public Matrix<3, T> { ); } + /** + * @brief Create matrix from rotation/scaling part and translation part + * @param rotationScaling Rotation/scaling part (upper-left 2x2 + * matrix) + * @param translation Translation part (first two elements of + * third column) + * + * @see rotationScaling() const, translation() const + */ + static Matrix3 from(const Matrix<2, T>& rotationScaling, const Vector2& translation = Vector2()) { + return from( + Vector3(rotationScaling[0], T(0)), + Vector3(rotationScaling[1], T(0)), + Vector3(translation, T(1)) + ); + } + /** @copydoc Matrix::Matrix(ZeroType) */ inline constexpr explicit Matrix3(typename Matrix<3, T>::ZeroType): Matrix<3, T>(Matrix<3, T>::Zero) {} @@ -107,7 +124,8 @@ template class Matrix3: public Matrix<3, T> { * @brief 2D rotation and scaling part of the matrix * * Upper-left 2x2 part of the matrix. - * @see rotation() const, rotation(T), Matrix4::rotationScaling() const + * @see from(const Matrix<2, T>&, const Vector2&), rotation() const, + * rotation(T), Matrix4::rotationScaling() const */ inline Matrix<2, T> rotationScaling() const { return Matrix<2, T>::from( diff --git a/src/Math/Matrix4.h b/src/Math/Matrix4.h index 899374fa7..2d669a7fc 100644 --- a/src/Math/Matrix4.h +++ b/src/Math/Matrix4.h @@ -173,6 +173,24 @@ template class Matrix4: public Matrix<4, T> { ); } + /** + * @brief Create matrix from rotation/scaling part and translation part + * @param rotationScaling Rotation/scaling part (upper-left 3x3 + * matrix) + * @param translation Translation part (first three elements of + * fourth column) + * + * @see rotationScaling() const, translation() const + */ + static Matrix4 from(const Matrix<3, T>& rotationScaling, const Vector3& translation = Vector3()) { + return from( + Vector4(rotationScaling[0], T(0)), + Vector4(rotationScaling[1], T(0)), + Vector4(rotationScaling[2], T(0)), + Vector4(translation, T(1)) + ); + } + /** @copydoc Matrix::Matrix(ZeroType) */ inline constexpr explicit Matrix4(typename Matrix<4, T>::ZeroType): Matrix<4, T>(Matrix<4, T>::Zero) {} @@ -198,8 +216,8 @@ template class Matrix4: public Matrix<4, T> { * @brief 3D rotation and scaling part of the matrix * * Upper-left 3x3 part of the matrix. - * @see rotation() const, rotation(T, const Vector3&), - * Matrix3::rotationScaling() const + * @see from(const Matrix<3, T>&, const Vector3&), rotation() const, + * rotation(T, const Vector3&), Matrix3::rotationScaling() const */ inline Matrix<3, T> rotationScaling() const { /* Not Matrix3, because it is for affine 2D transformations */ @@ -224,7 +242,6 @@ template class Matrix4: public Matrix<4, T> { (*this)[2].xyz().normalized()); } - /** * @brief Right-pointing 3D vector * diff --git a/src/Math/Test/Matrix3Test.cpp b/src/Math/Test/Matrix3Test.cpp index 0e7adb44b..a7e51a5e2 100644 --- a/src/Math/Test/Matrix3Test.cpp +++ b/src/Math/Test/Matrix3Test.cpp @@ -36,6 +36,7 @@ Matrix3Test::Matrix3Test() { &Matrix3Test::translation, &Matrix3Test::scaling, &Matrix3Test::rotation, + &Matrix3Test::fromParts, &Matrix3Test::rotationScalingPart, &Matrix3Test::rotationPart, &Matrix3Test::vectorParts, @@ -95,6 +96,29 @@ void Matrix3Test::rotation() { CORRADE_COMPARE(Matrix3::rotation(deg(15.0f)), matrix); } +void Matrix3Test::fromParts() { + Matrix2 rotationScaling( + 3.0f, 5.0f, + 4.0f, 4.0f + ); + + Vector2 translation(7.0f, -1.0f); + + Matrix3 expected( + 3.0f, 5.0f, 0.0f, + 4.0f, 4.0f, 0.0f, + 7.0f, -1.0f, 1.0f + ); + CORRADE_COMPARE(Matrix3::from(rotationScaling, translation), expected); + + Matrix3 expectedNoRotation( + 3.0f, 5.0f, 0.0f, + 4.0f, 4.0f, 0.0f, + 0.0f, 0.0f, 1.0f + ); + CORRADE_COMPARE(Matrix3::from(rotationScaling), expectedNoRotation); +} + void Matrix3Test::rotationScalingPart() { Matrix3 m( 3.0f, 5.0f, 8.0f, diff --git a/src/Math/Test/Matrix3Test.h b/src/Math/Test/Matrix3Test.h index 0b189e726..9a34ff78e 100644 --- a/src/Math/Test/Matrix3Test.h +++ b/src/Math/Test/Matrix3Test.h @@ -28,6 +28,7 @@ class Matrix3Test: public Corrade::TestSuite::Tester { void translation(); void scaling(); void rotation(); + void fromParts(); void rotationScalingPart(); void rotationPart(); void vectorParts(); diff --git a/src/Math/Test/Matrix4Test.cpp b/src/Math/Test/Matrix4Test.cpp index 7761bd8b7..9e79985cd 100644 --- a/src/Math/Test/Matrix4Test.cpp +++ b/src/Math/Test/Matrix4Test.cpp @@ -39,6 +39,7 @@ Matrix4Test::Matrix4Test() { &Matrix4Test::rotationX, &Matrix4Test::rotationY, &Matrix4Test::rotationZ, + &Matrix4Test::fromParts, &Matrix4Test::rotationScalingPart, &Matrix4Test::rotationPart, &Matrix4Test::vectorParts, @@ -135,6 +136,32 @@ void Matrix4Test::rotationZ() { CORRADE_COMPARE(Matrix4::rotationZ(rad(Math::Constants::pi()/7)), matrix); } +void Matrix4Test::fromParts() { + Matrix3 rotationScaling( + 3.0f, 5.0f, 8.0f, + 4.0f, 4.0f, 7.0f, + 7.0f, -1.0f, 8.0f + ); + + Vector3 translation(9.0f, 4.0f, 5.0f); + + Matrix4 expected( + 3.0f, 5.0f, 8.0f, 0.0f, + 4.0f, 4.0f, 7.0f, 0.0f, + 7.0f, -1.0f, 8.0f, 0.0f, + 9.0f, 4.0f, 5.0f, 1.0f + ); + CORRADE_COMPARE(Matrix4::from(rotationScaling, translation), expected); + + Matrix4 expectedNoTranslation( + 3.0f, 5.0f, 8.0f, 0.0f, + 4.0f, 4.0f, 7.0f, 0.0f, + 7.0f, -1.0f, 8.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + ); + CORRADE_COMPARE(Matrix4::from(rotationScaling), expectedNoTranslation); +} + void Matrix4Test::rotationScalingPart() { Matrix4 m( 3.0f, 5.0f, 8.0f, 4.0f, diff --git a/src/Math/Test/Matrix4Test.h b/src/Math/Test/Matrix4Test.h index f00ac7393..238fa1cc2 100644 --- a/src/Math/Test/Matrix4Test.h +++ b/src/Math/Test/Matrix4Test.h @@ -31,6 +31,7 @@ class Matrix4Test: public Corrade::TestSuite::Tester { void rotationX(); void rotationY(); void rotationZ(); + void fromParts(); void rotationScalingPart(); void rotationPart(); void vectorParts();