Browse Source

Math: added Matrix4::lookAt().

pull/94/head
Bill Robinson 11 years ago committed by Vladimír Vondruš
parent
commit
80e01ae18d
  1. 20
      src/Magnum/Math/Matrix4.h
  2. 42
      src/Magnum/Math/Test/Matrix4Test.cpp

20
src/Magnum/Math/Matrix4.h

@ -224,6 +224,15 @@ template<class T> class Matrix4: public Matrix4x4<T> {
return perspectiveProjection(Vector2<T>(xyScale, xyScale/aspectRatio), near, far);
}
/**
* @brief Matrix oriented towards a specific point
* @param eye Location to place the matrix
* @param target Location towards which the matrix is oriented
* @param up Vector as a guide of which way is up (should not be
* the same direction as `target - eye`)
*/
static Matrix4<T> lookAt(const Vector3<T>& eye, const Vector3<T>& target, const Vector3<T>& up);
/**
* @brief Create matrix from rotation/scaling part and translation part
* @param rotationScaling Rotation/scaling part (upper-left 3x3
@ -528,6 +537,17 @@ template<class T> Matrix4<T> Matrix4<T>::perspectiveProjection(const Vector2<T>&
{ T(0), T(0), T(2)*far*near*zScale, T(0)}};
}
template<class T> Matrix4<T> Matrix4<T>::lookAt(const Vector3<T>& eye, const Vector3<T>& target, const Vector3<T>& up) {
const Vector3<T> backward = (eye - target).normalized();
const Vector3<T> right = Vector3<T>::cross(up, backward).normalized();
const Vector3<T> realUp = Vector3<T>::cross(backward, right);
return {{ right, T(0)},
{ realUp, T(0)},
{backward, T(0)},
{ eye, T(1)}};
}
template<class T> inline Matrix3x3<T> Matrix4<T>::rotation() const {
CORRADE_ASSERT(TypeTraits<T>::equals((*this)[0].xyz().dot(), (*this)[1].xyz().dot()) &&
TypeTraits<T>::equals((*this)[1].xyz().dot(), (*this)[2].xyz().dot()),

42
src/Magnum/Math/Test/Matrix4Test.cpp

@ -85,6 +85,8 @@ struct Matrix4Test: Corrade::TestSuite::Tester {
void orthographicProjection();
void perspectiveProjection();
void perspectiveProjectionFov();
void lookAt();
void fromParts();
void rotationScalingPart();
void rotationNormalizedPart();
@ -131,6 +133,8 @@ Matrix4Test::Matrix4Test() {
&Matrix4Test::orthographicProjection,
&Matrix4Test::perspectiveProjection,
&Matrix4Test::perspectiveProjectionFov,
&Matrix4Test::lookAt,
&Matrix4Test::fromParts,
&Matrix4Test::rotationScalingPart,
&Matrix4Test::rotationNormalizedPart,
@ -507,6 +511,44 @@ void Matrix4Test::transform() {
CORRADE_COMPARE(a.transformPoint(v), Vector3(3.0f, -4.0f, 9.0f));
}
void Matrix4Test::lookAt() {
Matrix4 a = Matrix4::lookAt({0.0f, 0.0f, 0.0f},
{0.0f, 1.0f, 0.0f},
{0.0f, 0.0f, 1.0f});
CORRADE_VERIFY(a.isRigidTransformation());
CORRADE_COMPARE(a, Matrix4({1.0f, 0.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 1.0f, 0.0f},
{0.0f, -1.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 0.0f, 1.0f}));
Matrix4 b = Matrix4::lookAt({100.0f, 200.0f, 300.0f},
{ 0.0f, 0.0f, 0.0f},
{ 0.0f, 1.0f, 0.0f});
CORRADE_VERIFY(b.isRigidTransformation());
CORRADE_COMPARE(b, Matrix4({ 0.948683f, 0.0f, -0.316228f, 0.0f},
{-0.169031f, 0.845154f, -0.507093f, 0.0f},
{ 0.267261f, 0.534522f, 0.801784f, 0.0f},
{ 100.0f, 200.0f, 300.0f, 1.0f}));
Matrix4 c = Matrix4::lookAt({3.0f, 0.0f, 0.0f},
{0.0f, 4.0f, 5.0f},
{0.0f, 0.0f, 1.0f});
CORRADE_VERIFY(c.isRigidTransformation());
CORRADE_COMPARE(c, Matrix4({ 0.8f, 0.6f, 0.0f, 0.0f},
{0.424264f, -0.565685f, 0.707107f, 0.0f},
{0.424264f, -0.565685f, -0.707107f, 0.0f},
{ 3.0f, 0.0f, 0.0f, 1.0f}));
Matrix4 d = Matrix4::lookAt({ 0.0f, 3.0f, 0.0f},
{-5.0f, 0.0f, -4.0f},
{ 0.0f, 1.0f, 0.0f});
CORRADE_VERIFY(d.isRigidTransformation());
CORRADE_COMPARE(d, Matrix4({ 0.624695f, 0.0f, -0.780869f, 0.0f},
{-0.331295f, 0.905539f, -0.265036f, 0.0f},
{ 0.707107f, 0.424264f, 0.565685f, 0.0f},
{ 0.0f, 3.0f, 0.0f, 1.0f}));
}
void Matrix4Test::debug() {
Matrix4 m({3.0f, 5.0f, 8.0f, 4.0f},
{4.0f, 4.0f, 7.0f, 3.0f},

Loading…
Cancel
Save