diff --git a/matrix.hpp b/matrix.hpp index 3fc1143a..731ec9a2 100644 --- a/matrix.hpp +++ b/matrix.hpp @@ -68,7 +68,7 @@ namespace util { static matrix<4,T> ortho (T left, T right, T bottom, T top, T near, T far); static matrix<4,T> ortho2D (T left, T right, T bottom, T top); static matrix<4,T> perspective (T fov, T aspect, range Z); - static matrix<4,T> look_at (point<3,T> eye, point<3,T> centre, vector<3,T> up); + static matrix<4,T> look_at (point<3,T> eye, point<3,T> target, vector<3,T> up); // Affine matrices static matrix<4,T> translation (util::vector<2,T>); diff --git a/test/matrix.cpp b/test/matrix.cpp index 61c920f8..956ceaef 100644 --- a/test/matrix.cpp +++ b/test/matrix.cpp @@ -3,9 +3,13 @@ #include "debug.hpp" #include "tap.hpp" #include "vector.hpp" +#include "coord/iostream.hpp" +#include "quaternion.hpp" #include + +/////////////////////////////////////////////////////////////////////////////// int main (void) { @@ -153,5 +157,43 @@ main (void) tap.expect_eq (m.inverse (), r / 40.f, "4x4 inversion"); } + // sanity check euler rotations + { + static const struct { + util::vector3f euler; + const char *msg; + } TESTS[] = { + { util::vector3f { 0 }, "zeroes" }, + + { { 1, 0, 0 }, "x-axis" }, + { { 0, 1, 0 }, "y-axis" }, + { { 0, 0, 1 }, "z-axis" }, + + { util::vector3f { 1 }, "ones" }, + + { { 3, 5, 7 }, "positive primes" }, + { { -3, -5, -7 }, "negative primes" }, + { { 3, -5, 7 }, "mixed primes" }, + }; + + for (auto t: TESTS) { + constexpr auto PI2 = 2 * util::PI; + + auto matrix = ( + util::quaternionf::rotation (t.euler[2], { 0, 0, 1 }) * + util::quaternionf::rotation (t.euler[1], { 0, 1, 0 }) * + util::quaternionf::rotation (t.euler[0], { 1, 0, 0 }) + ).as_matrix (); + + auto euler = to_euler (matrix); + auto truth = t.euler; + + euler = mod (euler + 4 * PI2, PI2); + truth = mod (truth + 4 * PI2, PI2); + + tap.expect_eq (truth, euler, "matrix-to-euler, %s", t.msg); + } + } + return tap.status (); }