diff --git a/src/math/vector.cpp b/src/math/vector.cpp index c2c683a1..ead9e33d 100644 --- a/src/math/vector.cpp +++ b/src/math/vector.cpp @@ -553,6 +553,9 @@ static inline vec3 quat_toeuler_generic(quat const &q, int i, int j, int k) else { /* FIXME: TODO */ + ret[0] = rand(360.f); + ret[1] = rand(360.f); + ret[2] = rand(360.f); } return (180.0f / F_PI / n) * ret; @@ -624,10 +627,10 @@ static inline quat quat_fromeuler_generic(vec3 const &v, int i, int j, int k) { k = 3 - i - j; - ret[0] = c1 * (c0 * c2 - s0 * s2); + ret[0] = c1 * (c0 * c2 - s0 * s2); ret[1 + i] = c1 * (c0 * s2 + s0 * c2); ret[1 + j] = s1 * (c0 * c2 + s0 * s2); - ret[1 + k] = sign * (s0 * c2 - c0 * s2); + ret[1 + k] = sign * (s1 * (s0 * c2 - c0 * s2)); } else { diff --git a/test/unit/quat.cpp b/test/unit/quat.cpp index a89ac70d..9cbe97ee 100644 --- a/test/unit/quat.cpp +++ b/test/unit/quat.cpp @@ -189,11 +189,57 @@ LOLUNIT_FIXTURE(QuaternionTest) LOLUNIT_ASSERT_DOUBLES_EQUAL(d.z, a.z / ratio, 1e-5); } + LOLUNIT_TEST(FromEulerNorm) + { + for (int i = 0; i < 100; ++i) + { + vec3 angles(rand(360.f), rand(360.f), rand(360.f)); + + /* Tait-Bryan */ + quat q1 = quat::fromeuler_xyz(angles); + LOLUNIT_ASSERT_DOUBLES_EQUAL(norm(q1), 1.f, 1e-5); + + quat q2 = quat::fromeuler_yzx(angles); + LOLUNIT_ASSERT_DOUBLES_EQUAL(norm(q2), 1.f, 1e-5); + + quat q3 = quat::fromeuler_zxy(angles); + LOLUNIT_ASSERT_DOUBLES_EQUAL(norm(q3), 1.f, 1e-5); + + quat q4 = quat::fromeuler_xzy(angles); + LOLUNIT_ASSERT_DOUBLES_EQUAL(norm(q4), 1.f, 1e-5); + + quat q5 = quat::fromeuler_zyx(angles); + LOLUNIT_ASSERT_DOUBLES_EQUAL(norm(q5), 1.f, 1e-5); + + quat q6 = quat::fromeuler_yxz(angles); + LOLUNIT_ASSERT_DOUBLES_EQUAL(norm(q6), 1.f, 1e-5); + + /* Euler */ + quat q7 = quat::fromeuler_xyx(angles); + LOLUNIT_ASSERT_DOUBLES_EQUAL(norm(q7), 1.f, 1e-5); + + quat q8 = quat::fromeuler_yzy(angles); + LOLUNIT_ASSERT_DOUBLES_EQUAL(norm(q8), 1.f, 1e-5); + + quat q9 = quat::fromeuler_zxz(angles); + LOLUNIT_ASSERT_DOUBLES_EQUAL(norm(q9), 1.f, 1e-5); + + quat q10 = quat::fromeuler_xzx(angles); + LOLUNIT_ASSERT_DOUBLES_EQUAL(norm(q10), 1.f, 1e-5); + + quat q11 = quat::fromeuler_zyz(angles); + LOLUNIT_ASSERT_DOUBLES_EQUAL(norm(q11), 1.f, 1e-5); + + quat q12 = quat::fromeuler_yxy(angles); + LOLUNIT_ASSERT_DOUBLES_EQUAL(norm(q12), 1.f, 1e-5); + } + } + LOLUNIT_TEST(TaitBryanAngles) { - for (int i = 0; i < 10; ++i) + for (int i = 0; i < 100; ++i) { - /* Pick a random point and a random quaternion. We’re going + /* Pick a random point and a random quaternion. We want * to check whether going to Tait-Bryan angles and back to * quaternion creates the same transform. */ vec3 p(rand(1.f, 2.f), rand(1.f, 2.f), rand(1.f, 2.f)); @@ -253,7 +299,24 @@ LOLUNIT_FIXTURE(QuaternionTest) LOLUNIT_TEST(EulerAngles) { + for (int i = 0; i < 100; ++i) + { + /* Pick a random point and a random quaternion. We want + * to check whether going to Euler angles and back to + * quaternion creates the same transform. */ + vec3 p(rand(1.f, 2.f), rand(1.f, 2.f), rand(1.f, 2.f)); + quat q = normalize(quat(rand(-1.f, 1.f), rand(-1.f, 1.f), + rand(-1.f, 1.f), rand(-1.f, 1.f))); + vec3 p0 = q.transform(p); + + /* x-y-z */ + quat q1 = quat::fromeuler_xyx(vec3::toeuler_xyx(q)); + vec3 p1 = q1.transform(p); +// LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.x, p0.x, 1e-4); +// LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.y, p0.y, 1e-4); +// LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.z, p0.z, 1e-4); + } } };