Browse Source

Math: added Matrix[34]::rotationNormalized().

Useful to pass normal matrices to shader, namely with recent commit
b349ca54ad.
pull/277/head
Vladimír Vondruš 13 years ago
parent
commit
20dcab0c88
  1. 24
      src/Math/Matrix3.h
  2. 25
      src/Math/Matrix4.h
  3. 20
      src/Math/Test/Matrix3Test.cpp
  4. 22
      src/Math/Test/Matrix4Test.cpp

24
src/Math/Matrix3.h

@ -163,20 +163,36 @@ template<class T> class Matrix3: public Matrix<3, T> {
* @brief 2D rotation and scaling part of the matrix
*
* Upper-left 2x2 part of the matrix.
* @see from(const Matrix<2, T>&, const Vector2&), rotation() const,
* rotation(T), Matrix4::rotationScaling() const
* @todo extract rotation with assert for no scaling
* @see from(const Matrix<2, T>&, const Vector2&), rotation() const
* rotationNormalized(), rotation(T),
* Matrix4::rotationScaling() const
*/
constexpr Matrix<2, T> rotationScaling() const {
return {(*this)[0].xy(),
(*this)[1].xy()};
}
/**
* @brief 2D rotation part of the matrix assuming there is no scaling
*
* Similar to @ref rotationScaling(), but additionally checks that the
* base vectors are normalized.
* @see rotation() const, @ref Matrix4::rotationNormalized()
* @todo assert also orthogonality or this is good enough?
*/
Matrix<2, T> rotationNormalized() const {
CORRADE_ASSERT((*this)[0].xy().isNormalized() && (*this)[1].xy().isNormalized(),
"Math::Matrix3::rotationNormalized(): the rotation part is not normalized", {});
return {(*this)[0].xy(),
(*this)[1].xy()};
}
/**
* @brief 2D rotation part of the matrix
*
* Normalized upper-left 2x2 part of the matrix.
* @see rotationScaling() const, rotation(T), Matrix4::rotation() const
* @see rotationNormalized(), rotationScaling() const, rotation(T),
* Matrix4::rotation() const
* @todo assert uniform scaling (otherwise this would be garbage)
*/
Matrix<2, T> rotation() const {

25
src/Math/Matrix4.h

@ -227,8 +227,8 @@ template<class T> class Matrix4: public Matrix<4, T> {
*
* Upper-left 3x3 part of the matrix.
* @see from(const Matrix<3, T>&, const Vector3&), rotation() const,
* rotation(T, const Vector3&), Matrix3::rotationScaling() const
* @todo extract rotation with assert for no scaling
* rotationNormalized(), rotation(T, const Vector3&),
* Matrix3::rotationScaling() const
*/
/* Not Matrix3, because it is for affine 2D transformations */
constexpr Matrix<3, T> rotationScaling() const {
@ -237,12 +237,29 @@ template<class T> class Matrix4: public Matrix<4, T> {
(*this)[2].xyz()};
}
/**
* @brief 3D rotation part of the matrix assuming there is no scaling
*
* Similar to @ref rotationScaling(), but additionally checks that the
* base vectors are normalized.
* @see rotation() const, @ref Matrix3::rotationNormalized()
* @todo assert also orthogonality or this is good enough?
*/
/* Not Matrix3, because it is for affine 2D transformations */
Matrix<3, T> rotationNormalized() const {
CORRADE_ASSERT((*this)[0].xyz().isNormalized() && (*this)[1].xyz().isNormalized() && (*this)[2].xyz().isNormalized(),
"Math::Matrix4::rotationNormalized(): the rotation part is not normalized", {});
return {(*this)[0].xyz(),
(*this)[1].xyz(),
(*this)[2].xyz()};
}
/**
* @brief 3D rotation part of the matrix
*
* Normalized upper-left 3x3 part of the matrix.
* @see rotationScaling() const, rotation(T, const Vector3&),
* Matrix3::rotation() const
* @see rotationNormalized(), rotationScaling() const,
* rotation(T, const Vector3&), Matrix3::rotation() const
* @todo assert uniform scaling (otherwise this would be garbage)
*/
/* Not Matrix3, because it is for affine 2D transformations */

20
src/Math/Test/Matrix3Test.cpp

@ -76,6 +76,7 @@ class Matrix3Test: public Corrade::TestSuite::Tester {
void projection();
void fromParts();
void rotationScalingPart();
void rotationNormalizedPart();
void rotationPart();
void vectorParts();
void invertedRigid();
@ -110,6 +111,7 @@ Matrix3Test::Matrix3Test() {
&Matrix3Test::projection,
&Matrix3Test::fromParts,
&Matrix3Test::rotationScalingPart,
&Matrix3Test::rotationNormalizedPart,
&Matrix3Test::rotationPart,
&Matrix3Test::vectorParts,
&Matrix3Test::invertedRigid,
@ -285,6 +287,24 @@ void Matrix3Test::rotationScalingPart() {
Vector2(4.0f, 4.0f)));
}
void Matrix3Test::rotationNormalizedPart() {
std::ostringstream o;
Error::setOutput(&o);
Matrix3 a({1.0f, 0.0f, 8.0f},
{1.0f, 0.1f, 7.0f},
{7.0f, -1.0f, 8.0f});
a.rotationNormalized();
CORRADE_COMPARE(o.str(), "Math::Matrix3::rotationNormalized(): the rotation part is not normalized\n");
Matrix3 b({ 0.965926f, 0.258819f, 1.0f},
{-0.258819f, 0.965926f, 3.0f},
{ 0.0f, 0.0f, 1.0f});
CORRADE_COMPARE(b.rotationNormalized(), Matrix2(Vector2( 0.965926f, 0.258819f),
Vector2(-0.258819f, 0.965926f)));
}
void Matrix3Test::rotationPart() {
Matrix3 rotation = Matrix3::rotation(Deg(15.0f));
Matrix2 expectedRotationPart(Vector2( 0.965926f, 0.258819f),

22
src/Math/Test/Matrix4Test.cpp

@ -83,6 +83,7 @@ class Matrix4Test: public Corrade::TestSuite::Tester {
void perspectiveProjectionFov();
void fromParts();
void rotationScalingPart();
void rotationNormalizedPart();
void rotationPart();
void vectorParts();
void invertedRigid();
@ -122,6 +123,7 @@ Matrix4Test::Matrix4Test() {
&Matrix4Test::perspectiveProjectionFov,
&Matrix4Test::fromParts,
&Matrix4Test::rotationScalingPart,
&Matrix4Test::rotationNormalizedPart,
&Matrix4Test::rotationPart,
&Matrix4Test::vectorParts,
&Matrix4Test::invertedRigid,
@ -368,6 +370,26 @@ void Matrix4Test::rotationScalingPart() {
Vector3(7.0f, -1.0f, 8.0f)));
}
void Matrix4Test::rotationNormalizedPart() {
std::ostringstream o;
Error::setOutput(&o);
Matrix4 a({0.0f, 0.0f, 1.0f, 4.0f},
{1.0f, 0.0f, 0.0f, 3.0f},
{0.0f, -1.0f, 0.1f, 0.0f},
{9.0f, 4.0f, 5.0f, 9.0f});
a.rotationNormalized();
CORRADE_COMPARE(o.str(), "Math::Matrix4::rotationNormalized(): the rotation part is not normalized\n");
Matrix4 b({ 0.35612214f, -0.80181062f, 0.47987163f, 1.0f},
{ 0.47987163f, 0.59757638f, 0.6423595f, 3.0f},
{-0.80181062f, 0.0015183985f, 0.59757638f, 4.0f},
{ 0.0f, 0.0f, 0.0f, 1.0f});
CORRADE_COMPARE(b.rotationNormalized(), Matrix3(Vector3( 0.35612214f, -0.80181062f, 0.47987163f),
Vector3( 0.47987163f, 0.59757638f, 0.6423595f),
Vector3(-0.80181062f, 0.0015183985f, 0.59757638f)));
}
void Matrix4Test::rotationPart() {
Matrix4 rotation = Matrix4::rotation(Deg(-74.0f), Vector3(-1.0f, 2.0f, 2.0f).normalized());
Matrix3 expectedRotationPart(Vector3( 0.35612214f, -0.80181062f, 0.47987163f),

Loading…
Cancel
Save