Changeset 1320
- Timestamp:
- Apr 30, 2012, 8:40:52 PM (9 years ago)
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/lol/math/vector.h
r1317 r1320 1566 1566 v2(mat[2].xyz) {} 1567 1567 1568 explicit Mat3(Quat<T> const &q); 1569 1568 1570 inline Vec3<T>& operator[](size_t n) { return (&v0)[n]; } 1569 1571 inline Vec3<T> const& operator[](size_t n) const { return (&v0)[n]; } … … 1574 1576 static Mat3<T> rotate(T angle, T x, T y, T z); 1575 1577 static Mat3<T> rotate(T angle, Vec3<T> v); 1576 static Mat3<T> rotate(Quat<T> q);1577 1578 static Mat3<T> fromeuler(T x, T y, T z); 1578 1579 static Mat3<T> fromeuler(Vec3<T> const &v); … … 1676 1677 v3((T)0, (T)0, (T)0, val) {} 1677 1678 1679 explicit Mat4(Quat<T> const &q); 1680 1678 1681 inline Vec4<T>& operator[](size_t n) { return (&v0)[n]; } 1679 1682 inline Vec4<T> const& operator[](size_t n) const { return (&v0)[n]; } … … 1706 1709 { 1707 1710 return Mat4<T>(Mat3<T>::rotate(angle, v), (T)1); 1708 }1709 1710 static inline Mat4<T> rotate(Quat<T> q)1711 {1712 return Mat4<T>(Mat3<T>::rotate(q), (T)1);1713 1711 } 1714 1712 -
trunk/src/math/vector.cpp
r1319 r1320 362 362 float ct = std::cos(angle); 363 363 364 float len = s qrtf(x * x + y * y + z * z);364 float len = std::sqrt(x * x + y * y + z * z); 365 365 float invlen = len ? 1.0f / len : 0.0f; 366 366 x *= invlen; … … 394 394 } 395 395 396 template<> mat3 mat3::rotate(quatq)396 template<> mat3::Mat3(quat const &q) 397 397 { 398 398 float n = norm(q); 399 399 400 400 if (!n) 401 return mat3(1.0f); 402 403 mat3 ret; 401 { 402 for (int j = 0; j < 3; j++) 403 for (int i = 0; i < 3; i++) 404 (*this)[i][j] = (i == j) ? 1.f : 0.f; 405 return; 406 } 407 404 408 float s = 2.0f / n; 405 409 406 ret[0][0] = 1.0f - s * (q.y * q.y + q.z * q.z); 407 ret[0][1] = s * (q.x * q.y - q.z * q.w); 408 ret[0][2] = s * (q.x * q.z + q.y * q.w); 409 410 ret[1][0] = s * (q.x * q.y + q.z * q.w); 411 ret[1][1] = 1.0f - s * (q.z * q.z + q.x * q.x); 412 ret[1][2] = s * (q.y * q.z - q.x * q.w); 413 414 ret[2][0] = s * (q.x * q.z - q.y * q.w); 415 ret[2][1] = s * (q.y * q.z + q.x * q.w); 416 ret[2][2] = 1.0f - s * (q.x * q.x + q.y * q.y); 417 418 return ret; 419 } 420 421 static void MatrixToQuat(quat &that, mat3 const &m) 410 v0[0] = 1.0f - s * (q.y * q.y + q.z * q.z); 411 v0[1] = s * (q.x * q.y + q.z * q.w); 412 v0[2] = s * (q.x * q.z - q.y * q.w); 413 414 v1[0] = s * (q.x * q.y - q.z * q.w); 415 v1[1] = 1.0f - s * (q.z * q.z + q.x * q.x); 416 v1[2] = s * (q.y * q.z + q.x * q.w); 417 418 v2[0] = s * (q.x * q.z + q.y * q.w); 419 v2[1] = s * (q.y * q.z - q.x * q.w); 420 v2[2] = 1.0f - s * (q.x * q.x + q.y * q.y); 421 } 422 423 template<> mat4::Mat4(quat const &q) 424 { 425 *this = mat4(mat3(q), 1.f); 426 } 427 428 static inline void MatrixToQuat(quat &that, mat3 const &m) 422 429 { 423 430 /* See http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/christian.htm for a version with no branches */ … … 425 432 if (t > 0) 426 433 { 427 that.w = 0.5f * s qrtf(1.0f + t);434 that.w = 0.5f * std::sqrt(1.0f + t); 428 435 float s = 0.25f / that.w; 429 436 that.x = s * (m[1][2] - m[2][1]); … … 433 440 else if (m[0][0] > m[1][1] && m[0][0] > m[2][2]) 434 441 { 435 that.x = 0.5f * s qrtf(1.0f + m[0][0] - m[1][1] - m[2][2]);442 that.x = 0.5f * std::sqrt(1.0f + m[0][0] - m[1][1] - m[2][2]); 436 443 float s = 0.25f / that.x; 437 444 that.y = s * (m[0][1] + m[1][0]); … … 441 448 else if (m[1][1] > m[2][2]) 442 449 { 443 that.y = 0.5f * s qrtf(1.0f - m[0][0] + m[1][1] - m[2][2]);450 that.y = 0.5f * std::sqrt(1.0f - m[0][0] + m[1][1] - m[2][2]); 444 451 float s = 0.25f / that.y; 445 452 that.x = s * (m[0][1] + m[1][0]); … … 449 456 else 450 457 { 451 that.z = 0.5f * s qrtf(1.0f - m[0][0] - m[1][1] + m[2][2]);458 that.z = 0.5f * std::sqrt(1.0f - m[0][0] - m[1][1] + m[2][2]); 452 459 float s = 0.25f / that.z; 453 460 that.x = s * (m[2][0] + m[0][2]); -
trunk/test/unit/rotation.cpp
r1318 r1320 27 27 LOLUNIT_TEST(Rotate2D) 28 28 { 29 /* Check that rotation isCCW */29 /* Rotations must be CCW */ 30 30 mat2 m90 = mat2::rotate(90.f); 31 31 … … 39 39 LOLUNIT_TEST(Compose2D) 40 40 { 41 /* Check that rotating 20 degrees twice meansrotating 40 degrees */41 /* Rotating 20 degrees twice must equal rotating 40 degrees */ 42 42 mat2 m20 = mat2::rotate(20.f); 43 43 mat2 m40 = mat2::rotate(40.f); … … 46 46 LOLUNIT_ASSERT_DOUBLES_EQUAL(m20x20[0][0], m40[0][0], 1e-5); 47 47 LOLUNIT_ASSERT_DOUBLES_EQUAL(m20x20[1][0], m40[1][0], 1e-5); 48 48 49 LOLUNIT_ASSERT_DOUBLES_EQUAL(m20x20[0][1], m40[0][1], 1e-5); 49 50 LOLUNIT_ASSERT_DOUBLES_EQUAL(m20x20[1][1], m40[1][1], 1e-5); … … 52 53 LOLUNIT_TEST(Rotate3D) 53 54 { 54 /* Check that rotation is CCW aroundeach axis */55 /* Rotations must be CCW along each axis */ 55 56 mat3 m90x = mat3::rotate(90.f, 1.f, 0.f, 0.f); 56 57 mat3 m90y = mat3::rotate(90.f, 0.f, 1.f, 0.f); … … 77 78 LOLUNIT_TEST(Compose3D) 78 79 { 79 /* Check that rotating 20 degrees twice meansrotating 40 degrees */80 /* Rotating 20 degrees twice must equal rotating 40 degrees */ 80 81 mat3 m20 = mat3::rotate(20.f, 1.f, 2.f, 3.f); 81 82 mat3 m40 = mat3::rotate(40.f, 1.f, 2.f, 3.f); … … 85 86 LOLUNIT_ASSERT_DOUBLES_EQUAL(m20x20[1][0], m40[1][0], 1e-5); 86 87 LOLUNIT_ASSERT_DOUBLES_EQUAL(m20x20[2][0], m40[2][0], 1e-5); 88 87 89 LOLUNIT_ASSERT_DOUBLES_EQUAL(m20x20[0][1], m40[0][1], 1e-5); 88 90 LOLUNIT_ASSERT_DOUBLES_EQUAL(m20x20[1][1], m40[1][1], 1e-5); 89 91 LOLUNIT_ASSERT_DOUBLES_EQUAL(m20x20[2][1], m40[2][1], 1e-5); 92 90 93 LOLUNIT_ASSERT_DOUBLES_EQUAL(m20x20[0][2], m40[0][2], 1e-5); 91 94 LOLUNIT_ASSERT_DOUBLES_EQUAL(m20x20[1][2], m40[1][2], 1e-5); … … 95 98 LOLUNIT_TEST(QuaternionTransform) 96 99 { 97 /* Check that rotating using a quaternion is the same as rotating 98 * using a matrix */ 100 /* Rotating using a quaternion must equal rotating using a matrix */ 99 101 mat3 m20 = mat3::rotate(20.f, 1.f, 2.f, 3.f); 100 102 quat q20 = quat::rotate(20.f, 1.f, 2.f, 3.f); … … 111 113 LOLUNIT_TEST(QuaternionFromMatrix) 112 114 { 115 /* A rotation matrix converted to a quaternion should match the 116 * quaternion built with the same parameters */ 113 117 quat q1 = quat::rotate(20.f, 1.f, 2.f, 3.f); 114 118 quat q2 = quat(mat3::rotate(20.f, 1.f, 2.f, 3.f)); … … 119 123 LOLUNIT_ASSERT_DOUBLES_EQUAL(q2.z, q1.z, 1e-5); 120 124 } 125 126 LOLUNIT_TEST(MatrixFromQuaternion) 127 { 128 /* A quaternion converted to a rotation matrix should match the 129 * rotation matrix built with the same parameters */ 130 mat3 m1 = mat3::rotate(60.f, 1.f, -2.f, 3.f); 131 mat3 m2 = mat3(quat::rotate(60.f, 1.f, -2.f, 3.f)); 132 133 LOLUNIT_ASSERT_DOUBLES_EQUAL(m2[0][0], m1[0][0], 1e-5); 134 LOLUNIT_ASSERT_DOUBLES_EQUAL(m2[1][0], m1[1][0], 1e-5); 135 LOLUNIT_ASSERT_DOUBLES_EQUAL(m2[2][0], m1[2][0], 1e-5); 136 137 LOLUNIT_ASSERT_DOUBLES_EQUAL(m2[0][1], m1[0][1], 1e-5); 138 LOLUNIT_ASSERT_DOUBLES_EQUAL(m2[1][1], m1[1][1], 1e-5); 139 LOLUNIT_ASSERT_DOUBLES_EQUAL(m2[2][1], m1[2][1], 1e-5); 140 141 LOLUNIT_ASSERT_DOUBLES_EQUAL(m2[0][2], m1[0][2], 1e-5); 142 LOLUNIT_ASSERT_DOUBLES_EQUAL(m2[1][2], m1[1][2], 1e-5); 143 LOLUNIT_ASSERT_DOUBLES_EQUAL(m2[2][2], m1[2][2], 1e-5); 144 } 145 146 LOLUNIT_TEST(MatrixCompositionThroughQuaternions) 147 { 148 /* Combining two rotation matrices should match the matrix created 149 * from the combination of the two equivalent quaternions */ 150 mat3 m1 = mat3::rotate(60.f, 1.f, -2.f, 3.f); 151 mat3 m2 = mat3::rotate(20.f, -3.f, 1.f, -3.f); 152 153 mat3 m3 = m2 * m1; 154 mat3 m4(quat(m2) * quat(m1)); 155 156 LOLUNIT_ASSERT_DOUBLES_EQUAL(m4[0][0], m3[0][0], 1e-5); 157 LOLUNIT_ASSERT_DOUBLES_EQUAL(m4[1][0], m3[1][0], 1e-5); 158 LOLUNIT_ASSERT_DOUBLES_EQUAL(m4[2][0], m3[2][0], 1e-5); 159 160 LOLUNIT_ASSERT_DOUBLES_EQUAL(m4[0][1], m3[0][1], 1e-5); 161 LOLUNIT_ASSERT_DOUBLES_EQUAL(m4[1][1], m3[1][1], 1e-5); 162 LOLUNIT_ASSERT_DOUBLES_EQUAL(m4[2][1], m3[2][1], 1e-5); 163 164 LOLUNIT_ASSERT_DOUBLES_EQUAL(m4[0][2], m3[0][2], 1e-5); 165 LOLUNIT_ASSERT_DOUBLES_EQUAL(m4[1][2], m3[1][2], 1e-5); 166 LOLUNIT_ASSERT_DOUBLES_EQUAL(m4[2][2], m3[2][2], 1e-5); 167 } 168 169 LOLUNIT_TEST(QuaternionCompositionThroughMatrices) 170 { 171 /* Combining two quaternions should match the quaternion created 172 * from the combination of the two equivalent rotation matrices */ 173 quat q1 = quat::rotate(60.f, 1.f, -2.f, 3.f); 174 quat q2 = quat::rotate(20.f, -3.f, 1.f, -2.f); 175 176 quat q3 = q2 * q1; 177 quat q4(mat3(q2) * mat3(q1)); 178 179 LOLUNIT_ASSERT_DOUBLES_EQUAL(q4.w, q3.w, 1e-5); 180 LOLUNIT_ASSERT_DOUBLES_EQUAL(q4.x, q3.x, 1e-5); 181 LOLUNIT_ASSERT_DOUBLES_EQUAL(q4.y, q3.y, 1e-5); 182 LOLUNIT_ASSERT_DOUBLES_EQUAL(q4.z, q3.z, 1e-5); 183 } 121 184 }; 122 185
Note: See TracChangeset
for help on using the changeset viewer.