PageRenderTime 31ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llmath/tests/llquaternion_test.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 660 lines | 514 code | 88 blank | 58 comment | 98 complexity | 39847776b6792ec481a8574a776224ed MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llquaternion_test.cpp
  3. * @author Adroit
  4. * @date 2007-03
  5. * @brief Test cases of llquaternion.h
  6. *
  7. * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  8. * Second Life Viewer Source Code
  9. * Copyright (C) 2010, Linden Research, Inc.
  10. *
  11. * This library is free software; you can redistribute it and/or
  12. * modify it under the terms of the GNU Lesser General Public
  13. * License as published by the Free Software Foundation;
  14. * version 2.1 of the License only.
  15. *
  16. * This library is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  19. * Lesser General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU Lesser General Public
  22. * License along with this library; if not, write to the Free Software
  23. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  24. *
  25. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  26. * $/LicenseInfo$
  27. */
  28. #include "linden_common.h"
  29. #include "../test/lltut.h"
  30. #include "../v4math.h"
  31. #include "../v3math.h"
  32. #include "../v3dmath.h"
  33. #include "../m4math.h"
  34. #include "../m3math.h"
  35. #include "../llquaternion.h"
  36. namespace tut
  37. {
  38. struct llquat_test
  39. {
  40. };
  41. typedef test_group<llquat_test> llquat_test_t;
  42. typedef llquat_test_t::object llquat_test_object_t;
  43. tut::llquat_test_t tut_llquat_test("LLQuaternion");
  44. //test case for LLQuaternion::LLQuaternion(void) fn.
  45. template<> template<>
  46. void llquat_test_object_t::test<1>()
  47. {
  48. LLQuaternion llquat;
  49. ensure("LLQuaternion::LLQuaternion() failed", 0.f == llquat.mQ[0] &&
  50. 0.f == llquat.mQ[1] &&
  51. 0.f == llquat.mQ[2] &&
  52. 1.f == llquat.mQ[3]);
  53. }
  54. //test case for explicit LLQuaternion(const LLMatrix4 &mat) fn.
  55. template<> template<>
  56. void llquat_test_object_t::test<2>()
  57. {
  58. LLMatrix4 llmat;
  59. LLVector4 vector1(2.0f, 1.0f, 3.0f, 6.0f);
  60. LLVector4 vector2(5.0f, 6.0f, 0.0f, 1.0f);
  61. LLVector4 vector3(2.0f, 1.0f, 2.0f, 9.0f);
  62. LLVector4 vector4(3.0f, 8.0f, 1.0f, 5.0f);
  63. llmat.initRows(vector1, vector2, vector3, vector4);
  64. ensure("explicit LLQuaternion(const LLMatrix4 &mat) failed", 2.0f == llmat.mMatrix[0][0] &&
  65. 1.0f == llmat.mMatrix[0][1] &&
  66. 3.0f == llmat.mMatrix[0][2] &&
  67. 6.0f == llmat.mMatrix[0][3] &&
  68. 5.0f == llmat.mMatrix[1][0] &&
  69. 6.0f == llmat.mMatrix[1][1] &&
  70. 0.0f == llmat.mMatrix[1][2] &&
  71. 1.0f == llmat.mMatrix[1][3] &&
  72. 2.0f == llmat.mMatrix[2][0] &&
  73. 1.0f == llmat.mMatrix[2][1] &&
  74. 2.0f == llmat.mMatrix[2][2] &&
  75. 9.0f == llmat.mMatrix[2][3] &&
  76. 3.0f == llmat.mMatrix[3][0] &&
  77. 8.0f == llmat.mMatrix[3][1] &&
  78. 1.0f == llmat.mMatrix[3][2] &&
  79. 5.0f == llmat.mMatrix[3][3]);
  80. }
  81. template<> template<>
  82. void llquat_test_object_t::test<3>()
  83. {
  84. LLMatrix3 llmat;
  85. LLVector3 vect1(3.4028234660000000f , 234.56f, 4234.442234f);
  86. LLVector3 vect2(741.434f, 23.00034f, 6567.223423f);
  87. LLVector3 vect3(566.003034f, 12.98705f, 234.764423f);
  88. llmat.setRows(vect1, vect2, vect3);
  89. ensure("LLMatrix3::setRows fn failed.", 3.4028234660000000f == llmat.mMatrix[0][0] &&
  90. 234.56f == llmat.mMatrix[0][1] &&
  91. 4234.442234f == llmat.mMatrix[0][2] &&
  92. 741.434f == llmat.mMatrix[1][0] &&
  93. 23.00034f == llmat.mMatrix[1][1] &&
  94. 6567.223423f == llmat.mMatrix[1][2] &&
  95. 566.003034f == llmat.mMatrix[2][0] &&
  96. 12.98705f == llmat.mMatrix[2][1] &&
  97. 234.764423f == llmat.mMatrix[2][2]);
  98. }
  99. //test case for LLQuaternion(F32 x, F32 y, F32 z, F32 w), setQuatInit() and normQuat() fns.
  100. template<> template<>
  101. void llquat_test_object_t::test<4>()
  102. {
  103. F32 x_val = 3.0f;
  104. F32 y_val = 2.0f;
  105. F32 z_val = 6.0f;
  106. F32 w_val = 1.0f;
  107. LLQuaternion res_quat;
  108. res_quat.setQuatInit(x_val, y_val, z_val, w_val);
  109. res_quat.normQuat();
  110. ensure("LLQuaternion::normQuat() fn failed",
  111. is_approx_equal(0.42426407f, res_quat.mQ[0]) &&
  112. is_approx_equal(0.28284273f, res_quat.mQ[1]) &&
  113. is_approx_equal(0.84852815f, res_quat.mQ[2]) &&
  114. is_approx_equal(0.14142136f, res_quat.mQ[3]));
  115. x_val = 0.0f;
  116. y_val = 0.0f;
  117. z_val = 0.0f;
  118. w_val = 0.0f;
  119. res_quat.setQuatInit(x_val, y_val, z_val, w_val);
  120. res_quat.normQuat();
  121. ensure("LLQuaternion::normQuat() fn. failed.",
  122. is_approx_equal(0.0f, res_quat.mQ[0]) &&
  123. is_approx_equal(0.0f, res_quat.mQ[1]) &&
  124. is_approx_equal(0.0f, res_quat.mQ[2]) &&
  125. is_approx_equal(1.0f, res_quat.mQ[3]));
  126. ensure("LLQuaternion::normQuat() fn. failed.",
  127. is_approx_equal(0.0f, res_quat.mQ[0]) &&
  128. is_approx_equal(0.0f, res_quat.mQ[1]) &&
  129. is_approx_equal(0.0f, res_quat.mQ[2]) &&
  130. is_approx_equal(1.0f, res_quat.mQ[3]));
  131. }
  132. //test case for conjQuat() and transQuat() fns.
  133. template<> template<>
  134. void llquat_test_object_t::test<5>()
  135. {
  136. F32 x_val = 3.0f;
  137. F32 y_val = 2.0f;
  138. F32 z_val = 6.0f;
  139. F32 w_val = 1.0f;
  140. LLQuaternion res_quat;
  141. LLQuaternion result, result1;
  142. result1 = result = res_quat.setQuatInit(x_val, y_val, z_val, w_val);
  143. result.conjQuat();
  144. result1.transQuat();
  145. ensure("LLQuaternion::conjQuat and LLQuaternion::transQuat failed ",
  146. is_approx_equal(result1.mQ[0], result.mQ[0]) &&
  147. is_approx_equal(result1.mQ[1], result.mQ[1]) &&
  148. is_approx_equal(result1.mQ[2], result.mQ[2]));
  149. }
  150. //test case for dot(const LLQuaternion &a, const LLQuaternion &b) fn.
  151. template<> template<>
  152. void llquat_test_object_t::test<6>()
  153. {
  154. LLQuaternion quat1(3.0f, 2.0f, 6.0f, 0.0f), quat2(1.0f, 1.0f, 1.0f, 1.0f);
  155. ensure("1. The two values are different", llround(12.000000f, 2) == llround(dot(quat1, quat2), 2));
  156. LLQuaternion quat0(3.0f, 9.334f, 34.5f, 23.0f), quat(34.5f, 23.23f, 2.0f, 45.5f);
  157. ensure("2. The two values are different", llround(1435.828807f, 2) == llround(dot(quat0, quat), 2));
  158. }
  159. //test case for LLQuaternion &LLQuaternion::constrain(F32 radians) fn.
  160. template<> template<>
  161. void llquat_test_object_t::test<7>()
  162. {
  163. F32 radian = 60.0f;
  164. LLQuaternion quat(3.0f, 2.0f, 6.0f, 0.0f);
  165. LLQuaternion quat1;
  166. quat1 = quat.constrain(radian);
  167. ensure("1. LLQuaternion::constrain(F32 radians) failed",
  168. is_approx_equal_fraction(-0.423442f, quat1.mQ[0], 8) &&
  169. is_approx_equal_fraction(-0.282295f, quat1.mQ[1], 8) &&
  170. is_approx_equal_fraction(-0.846884f, quat1.mQ[2], 8) &&
  171. is_approx_equal_fraction(0.154251f, quat1.mQ[3], 8));
  172. radian = 30.0f;
  173. LLQuaternion quat0(37.50f, 12.0f, 86.023f, 40.32f);
  174. quat1 = quat0.constrain(radian);
  175. ensure("2. LLQuaternion::constrain(F32 radians) failed",
  176. is_approx_equal_fraction(37.500000f, quat1.mQ[0], 8) &&
  177. is_approx_equal_fraction(12.0000f, quat1.mQ[1], 8) &&
  178. is_approx_equal_fraction(86.0230f, quat1.mQ[2], 8) &&
  179. is_approx_equal_fraction(40.320000f, quat1.mQ[3], 8));
  180. }
  181. template<> template<>
  182. void llquat_test_object_t::test<8>()
  183. {
  184. F32 value1 = 15.0f;
  185. LLQuaternion quat1(1.0f, 2.0f, 4.0f, 1.0f);
  186. LLQuaternion quat2(4.0f, 3.0f, 6.5f, 9.7f);
  187. LLQuaternion res_lerp, res_slerp, res_nlerp;
  188. //test case for lerp(F32 t, const LLQuaternion &q) fn.
  189. res_lerp = lerp(value1, quat1);
  190. ensure("1. LLQuaternion lerp(F32 t, const LLQuaternion &q) failed",
  191. is_approx_equal_fraction(0.181355f, res_lerp.mQ[0], 16) &&
  192. is_approx_equal_fraction(0.362711f, res_lerp.mQ[1], 16) &&
  193. is_approx_equal_fraction(0.725423f, res_lerp.mQ[2], 16) &&
  194. is_approx_equal_fraction(0.556158f, res_lerp.mQ[3], 16));
  195. //test case for lerp(F32 t, const LLQuaternion &p, const LLQuaternion &q) fn.
  196. res_lerp = lerp(value1, quat1, quat2);
  197. ensure("2. LLQuaternion lerp(F32 t, const LLQuaternion &p, const LLQuaternion &q) failed",
  198. is_approx_equal_fraction(0.314306f, res_lerp.mQ[0], 16) &&
  199. is_approx_equal_fraction(0.116156f, res_lerp.mQ[1], 16) &&
  200. is_approx_equal_fraction(0.283559f, res_lerp.mQ[2], 16) &&
  201. is_approx_equal_fraction(0.898506f, res_lerp.mQ[3], 16));
  202. //test case for slerp( F32 u, const LLQuaternion &a, const LLQuaternion &b ) fn.
  203. res_slerp = slerp(value1, quat1, quat2);
  204. ensure("3. LLQuaternion slerp( F32 u, const LLQuaternion &a, const LLQuaternion &b) failed",
  205. is_approx_equal_fraction(46.000f, res_slerp.mQ[0], 16) &&
  206. is_approx_equal_fraction(17.00f, res_slerp.mQ[1], 16) &&
  207. is_approx_equal_fraction(41.5f, res_slerp.mQ[2], 16) &&
  208. is_approx_equal_fraction(131.5f, res_slerp.mQ[3], 16));
  209. //test case for nlerp(F32 t, const LLQuaternion &a, const LLQuaternion &b) fn.
  210. res_nlerp = nlerp(value1, quat1, quat2);
  211. ensure("4. LLQuaternion nlerp(F32 t, const LLQuaternion &a, const LLQuaternion &b) failed",
  212. is_approx_equal_fraction(0.314306f, res_nlerp.mQ[0], 16) &&
  213. is_approx_equal_fraction(0.116157f, res_nlerp.mQ[1], 16) &&
  214. is_approx_equal_fraction(0.283559f, res_nlerp.mQ[2], 16) &&
  215. is_approx_equal_fraction(0.898506f, res_nlerp.mQ[3], 16));
  216. //test case for nlerp(F32 t, const LLQuaternion &q) fn.
  217. res_slerp = slerp(value1, quat1);
  218. ensure("5. LLQuaternion slerp(F32 t, const LLQuaternion &q) failed",
  219. is_approx_equal_fraction(1.0f, res_slerp.mQ[0], 16) &&
  220. is_approx_equal_fraction(2.0f, res_slerp.mQ[1], 16) &&
  221. is_approx_equal_fraction(4.0000f, res_slerp.mQ[2], 16) &&
  222. is_approx_equal_fraction(1.000f, res_slerp.mQ[3], 16));
  223. LLQuaternion quat3(2.0f, 1.0f, 5.5f, 10.5f);
  224. LLQuaternion res_nlerp1;
  225. value1 = 100.0f;
  226. res_nlerp1 = nlerp(value1, quat3);
  227. ensure("6. LLQuaternion nlerp(F32 t, const LLQuaternion &q) failed",
  228. is_approx_equal_fraction(0.268245f, res_nlerp1.mQ[0], 16) && is_approx_equal_fraction(0.134122f, res_nlerp1.mQ[1], 2) &&
  229. is_approx_equal_fraction(0.737673f, res_nlerp1.mQ[2], 16) &&
  230. is_approx_equal_fraction(0.604892f, res_nlerp1.mQ[3], 16));
  231. //test case for lerp(F32 t, const LLQuaternion &q) fn.
  232. res_lerp = lerp(value1, quat2);
  233. ensure("7. LLQuaternion lerp(F32 t, const LLQuaternion &q) failed",
  234. is_approx_equal_fraction(0.404867f, res_lerp.mQ[0], 16) &&
  235. is_approx_equal_fraction(0.303650f, res_lerp.mQ[1], 16) &&
  236. is_approx_equal_fraction(0.657909f, res_lerp.mQ[2], 16) &&
  237. is_approx_equal_fraction(0.557704f, res_lerp.mQ[3], 16));
  238. }
  239. template<> template<>
  240. void llquat_test_object_t::test<9>()
  241. {
  242. //test case for LLQuaternion operator*(const LLQuaternion &a, const LLQuaternion &b) fn
  243. LLQuaternion quat1(1.0f, 2.5f, 3.5f, 5.5f);
  244. LLQuaternion quat2(4.0f, 3.0f, 5.0f, 1.0f);
  245. LLQuaternion result = quat1 * quat2;
  246. ensure("1. LLQuaternion Operator* failed", (21.0f == result.mQ[0]) &&
  247. (10.0f == result.mQ[1]) &&
  248. (38.0f == result.mQ[2]) &&
  249. (-23.5f == result.mQ[3]));
  250. LLQuaternion quat3(2341.340f, 2352.345f, 233.25f, 7645.5f);
  251. LLQuaternion quat4(674.067f, 893.0897f, 578.0f, 231.0f);
  252. result = quat3 * quat4;
  253. ensure("2. LLQuaternion Operator* failed", (4543086.5f == result.mQ[0]) &&
  254. (8567578.0f == result.mQ[1]) &&
  255. (3967591.25f == result.mQ[2]) &&
  256. is_approx_equal(-2047783.25f, result.mQ[3]));
  257. //inline LLQuaternion operator+(const LLQuaternion &a, const LLQuaternion &b)fn.
  258. result = quat1 + quat2;
  259. ensure("3. LLQuaternion operator+ failed", (5.0f == result.mQ[0]) &&
  260. (5.5f == result.mQ[1]) &&
  261. (8.5f == result.mQ[2]) &&
  262. (6.5f == result.mQ[3]));
  263. result = quat3 + quat4;
  264. ensure(
  265. "4. LLQuaternion operator+ failed",
  266. is_approx_equal(3015.407227f, result.mQ[0]) &&
  267. is_approx_equal(3245.434570f, result.mQ[1]) &&
  268. (811.25f == result.mQ[2]) &&
  269. (7876.5f == result.mQ[3]));
  270. //inline LLQuaternion operator-(const LLQuaternion &a, const LLQuaternion &b) fn
  271. result = quat1 - quat2;
  272. ensure(
  273. "5. LLQuaternion operator-(const LLQuaternion &a, const LLQuaternion &b) failed",
  274. (-3.0f == result.mQ[0]) &&
  275. (-0.5f == result.mQ[1]) &&
  276. (-1.5f == result.mQ[2]) &&
  277. (4.5f == result.mQ[3]));
  278. result = quat3 - quat4;
  279. ensure(
  280. "6. LLQuaternion operator-(const LLQuaternion &a, const LLQuaternion &b) failed",
  281. is_approx_equal(1667.273071f, result.mQ[0]) &&
  282. is_approx_equal(1459.255249f, result.mQ[1]) &&
  283. (-344.75f == result.mQ[2]) &&
  284. (7414.50f == result.mQ[3]));
  285. }
  286. //test case for LLVector4 operator*(const LLVector4 &a, const LLQuaternion &rot) fn.
  287. template<> template<>
  288. void llquat_test_object_t::test<10>()
  289. {
  290. LLVector4 vect(12.0f, 5.0f, 60.0f, 75.1f);
  291. LLQuaternion quat(2323.034f, 23.5f, 673.23f, 57667.5f);
  292. LLVector4 result = vect * quat;
  293. ensure(
  294. "1. LLVector4 operator*(const LLVector4 &a, const LLQuaternion &rot) failed",
  295. is_approx_equal(39928406016.0f, result.mV[0]) &&
  296. // gcc on x86 actually gives us more precision than we were expecting, verified with -ffloat-store - we forgive this
  297. (1457802240.0f >= result.mV[1]) && // gcc+x86+linux
  298. (1457800960.0f <= result.mV[1]) && // elsewhere
  299. is_approx_equal(200580612096.0f, result.mV[2]) &&
  300. (75.099998f == result.mV[3]));
  301. LLVector4 vect1(22.0f, 45.0f, 40.0f, 78.1f);
  302. LLQuaternion quat1(2.034f, 45.5f, 37.23f, 7.5f);
  303. result = vect1 * quat1;
  304. ensure(
  305. "2. LLVector4 operator*(const LLVector4 &a, const LLQuaternion &rot) failed",
  306. is_approx_equal(-58153.5390f, result.mV[0]) &&
  307. (183787.8125f == result.mV[1]) &&
  308. (116864.164063f == result.mV[2]) &&
  309. (78.099998f == result.mV[3]));
  310. }
  311. //test case for LLVector3 operator*(const LLVector3 &a, const LLQuaternion &rot) fn.
  312. template<> template<>
  313. void llquat_test_object_t::test<11>()
  314. {
  315. LLVector3 vect(12.0f, 5.0f, 60.0f);
  316. LLQuaternion quat(23.5f, 6.5f, 3.23f, 56.5f);
  317. LLVector3 result = vect * quat;
  318. ensure(
  319. "1. LLVector3 operator*(const LLVector3 &a, const LLQuaternion &rot) failed",
  320. is_approx_equal(97182.953125f,result.mV[0]) &&
  321. is_approx_equal(-135405.640625f, result.mV[1]) &&
  322. is_approx_equal(162986.140f, result.mV[2]));
  323. LLVector3 vect1(5.0f, 40.0f, 78.1f);
  324. LLQuaternion quat1(2.034f, 45.5f, 37.23f, 7.5f);
  325. result = vect1 * quat1;
  326. ensure(
  327. "2. LLVector3 operator*(const LLVector3 &a, const LLQuaternion &rot) failed",
  328. is_approx_equal(33217.703f, result.mV[0]) &&
  329. is_approx_equal(295383.8125f, result.mV[1]) &&
  330. is_approx_equal(84718.140f, result.mV[2]));
  331. }
  332. //test case for LLVector3d operator*(const LLVector3d &a, const LLQuaternion &rot) fn.
  333. template<> template<>
  334. void llquat_test_object_t::test<12>()
  335. {
  336. LLVector3d vect(-2.0f, 5.0f, -6.0f);
  337. LLQuaternion quat(-3.5f, 4.5f, 3.5f, 6.5f);
  338. LLVector3d result = vect * quat;
  339. ensure(
  340. "1. LLVector3d operator*(const LLVector3d &a, const LLQuaternion &rot) failed ",
  341. (-633.0f == result.mdV[0]) &&
  342. (-300.0f == result.mdV[1]) &&
  343. (-36.0f == result.mdV[2]));
  344. LLVector3d vect1(5.0f, -4.5f, 8.21f);
  345. LLQuaternion quat1(2.0f, 4.5f, -7.2f, 9.5f);
  346. result = vect1 * quat1;
  347. ensure(
  348. "2. LLVector3d operator*(const LLVector3d &a, const LLQuaternion &rot) failed",
  349. is_approx_equal_fraction(-120.29f, (F32) result.mdV[0], 8) &&
  350. is_approx_equal_fraction(-1683.958f, (F32) result.mdV[1], 8) &&
  351. is_approx_equal_fraction(516.56f, (F32) result.mdV[2], 8));
  352. LLVector3d vect2(2.0f, 3.5f, 1.1f);
  353. LLQuaternion quat2(1.0f, 4.0f, 2.0f, 5.0f);
  354. result = vect2 * quat2;
  355. ensure(
  356. "3. LLVector3d operator*(const LLVector3d &a, const LLQuaternion &rot) failed",
  357. is_approx_equal_fraction(18.400001f, (F32) result.mdV[0], 8) &&
  358. is_approx_equal_fraction(188.6f, (F32) result.mdV[1], 8) &&
  359. is_approx_equal_fraction(32.20f, (F32) result.mdV[2], 8));
  360. }
  361. //test case for inline LLQuaternion operator-(const LLQuaternion &a) fn.
  362. template<> template<>
  363. void llquat_test_object_t::test<13>()
  364. {
  365. LLQuaternion quat(23.5f, 34.5f, 16723.4f, 324.7f);
  366. LLQuaternion result = -quat;
  367. ensure(
  368. "1. LLQuaternion operator-(const LLQuaternion &a) failed",
  369. (-23.5f == result.mQ[0]) &&
  370. (-34.5f == result.mQ[1]) &&
  371. (-16723.4f == result.mQ[2]) &&
  372. (-324.7f == result.mQ[3]));
  373. LLQuaternion quat1(-3.5f, -34.5f, -16.4f, -154.7f);
  374. result = -quat1;
  375. ensure(
  376. "2. LLQuaternion operator-(const LLQuaternion &a) failed.",
  377. (3.5f == result.mQ[0]) &&
  378. (34.5f == result.mQ[1]) &&
  379. (16.4f == result.mQ[2]) &&
  380. (154.7f == result.mQ[3]));
  381. }
  382. //test case for inline LLQuaternion operator*(F32 a, const LLQuaternion &q) and
  383. //inline LLQuaternion operator*(F32 a, const LLQuaternion &q) fns.
  384. template<> template<>
  385. void llquat_test_object_t::test<14>()
  386. {
  387. LLQuaternion quat_value(9.0f, 8.0f, 7.0f, 6.0f);
  388. F32 a =3.5f;
  389. LLQuaternion result = a * quat_value;
  390. LLQuaternion result1 = quat_value * a;
  391. ensure(
  392. "1. LLQuaternion operator* failed",
  393. (result.mQ[0] == result1.mQ[0]) &&
  394. (result.mQ[1] == result1.mQ[1]) &&
  395. (result.mQ[2] == result1.mQ[2]) &&
  396. (result.mQ[3] == result1.mQ[3]));
  397. LLQuaternion quat_val(9454.0f, 43568.3450f, 456343247.0343f, 2346.03434f);
  398. a =-3324.3445f;
  399. result = a * quat_val;
  400. result1 = quat_val * a;
  401. ensure(
  402. "2. LLQuaternion operator* failed",
  403. (result.mQ[0] == result1.mQ[0]) &&
  404. (result.mQ[1] == result1.mQ[1]) &&
  405. (result.mQ[2] == result1.mQ[2]) &&
  406. (result.mQ[3] == result1.mQ[3]));
  407. }
  408. template<> template<>
  409. void llquat_test_object_t::test<15>()
  410. {
  411. // test cases for inline LLQuaternion operator~(const LLQuaternion &a)
  412. LLQuaternion quat_val(2323.634f, -43535.4f, 3455.88f, -32232.45f);
  413. LLQuaternion result = ~quat_val;
  414. ensure(
  415. "1. LLQuaternion operator~(const LLQuaternion &a) failed ",
  416. (-2323.634f == result.mQ[0]) &&
  417. (43535.4f == result.mQ[1]) &&
  418. (-3455.88f == result.mQ[2]) &&
  419. (-32232.45f == result.mQ[3]));
  420. //test case for inline bool LLQuaternion::operator==(const LLQuaternion &b) const
  421. LLQuaternion quat_val1(2323.634f, -43535.4f, 3455.88f, -32232.45f);
  422. LLQuaternion quat_val2(2323.634f, -43535.4f, 3455.88f, -32232.45f);
  423. ensure(
  424. "2. LLQuaternion::operator==(const LLQuaternion &b) failed",
  425. quat_val1 == quat_val2);
  426. }
  427. template<> template<>
  428. void llquat_test_object_t::test<16>()
  429. {
  430. //test case for inline bool LLQuaternion::operator!=(const LLQuaternion &b) const
  431. LLQuaternion quat_val1(2323.634f, -43535.4f, 3455.88f, -32232.45f);
  432. LLQuaternion quat_val2(0, -43535.4f, 3455.88f, -32232.45f);
  433. ensure("LLQuaternion::operator!=(const LLQuaternion &b) failed", quat_val1 != quat_val2);
  434. }
  435. template<> template<>
  436. void llquat_test_object_t::test<17>()
  437. {
  438. //test case for LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order)
  439. F32 x = 2.0f;
  440. F32 y = 1.0f;
  441. F32 z = 3.0f;
  442. LLQuaternion result = mayaQ(x, y, z, LLQuaternion::XYZ);
  443. ensure(
  444. "1. LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for XYZ",
  445. is_approx_equal_fraction(0.0172174f, result.mQ[0], 16) &&
  446. is_approx_equal_fraction(0.009179f, result.mQ[1], 16) &&
  447. is_approx_equal_fraction(0.026020f, result.mQ[2], 16) &&
  448. is_approx_equal_fraction(0.999471f, result.mQ[3], 16));
  449. LLQuaternion result1 = mayaQ(x, y, z, LLQuaternion::YZX);
  450. ensure(
  451. "2. LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for XYZ",
  452. is_approx_equal_fraction(0.017217f, result1.mQ[0], 16) &&
  453. is_approx_equal_fraction(0.008265f, result1.mQ[1], 16) &&
  454. is_approx_equal_fraction(0.026324f, result1.mQ[2], 16) &&
  455. is_approx_equal_fraction(0.999471f, result1.mQ[3], 16));
  456. LLQuaternion result2 = mayaQ(x, y, z, LLQuaternion::ZXY);
  457. ensure(
  458. "3. LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for ZXY",
  459. is_approx_equal_fraction(0.017674f, result2.mQ[0], 16) &&
  460. is_approx_equal_fraction(0.008265f, result2.mQ[1], 16) &&
  461. is_approx_equal_fraction(0.026020f, result2.mQ[2], 16) &&
  462. is_approx_equal_fraction(0.999471f, result2.mQ[3], 16));
  463. LLQuaternion result3 = mayaQ(x, y, z, LLQuaternion::XZY);
  464. ensure(
  465. "4. TLLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for XZY",
  466. is_approx_equal_fraction(0.017674f, result3.mQ[0], 16) &&
  467. is_approx_equal_fraction(0.009179f, result3.mQ[1], 16) &&
  468. is_approx_equal_fraction(0.026020f, result3.mQ[2], 16) &&
  469. is_approx_equal_fraction(0.999463f, result3.mQ[3], 16));
  470. LLQuaternion result4 = mayaQ(x, y, z, LLQuaternion::YXZ);
  471. ensure(
  472. "5. LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for YXZ",
  473. is_approx_equal_fraction(0.017217f, result4.mQ[0], 16) &&
  474. is_approx_equal_fraction(0.009179f, result4.mQ[1], 16) &&
  475. is_approx_equal_fraction(0.026324f, result4.mQ[2], 16) &&
  476. is_approx_equal_fraction(0.999463f, result4.mQ[3], 16));
  477. LLQuaternion result5 = mayaQ(x, y, z, LLQuaternion::ZYX);
  478. ensure(
  479. "6. LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for ZYX",
  480. is_approx_equal_fraction(0.017674f, result5.mQ[0], 16) &&
  481. is_approx_equal_fraction(0.008265f, result5.mQ[1], 16) &&
  482. is_approx_equal_fraction(0.026324f, result5.mQ[2], 16) &&
  483. is_approx_equal_fraction(0.999463f, result5.mQ[3], 16));
  484. }
  485. template<> template<>
  486. void llquat_test_object_t::test<18>()
  487. {
  488. // test case for friend std::ostream& operator<<(std::ostream &s, const LLQuaternion &a) fn
  489. LLQuaternion a(1.0f, 1.0f, 1.0f, 1.0f);
  490. std::ostringstream result_value;
  491. result_value << a;
  492. ensure_equals("1. Operator << failed", result_value.str(), "{ 1, 1, 1, 1 }");
  493. LLQuaternion b(-31.034f, 231.2340f, 3451.344320f, -341.0f);
  494. std::ostringstream result_value1;
  495. result_value1 << b;
  496. ensure_equals("2. Operator << failed", result_value1.str(), "{ -31.034, 231.234, 3451.34, -341 }");
  497. LLQuaternion c(1.0f, 2.2f, 3.3f, 4.4f);
  498. result_value << c;
  499. ensure_equals("3. Operator << failed", result_value.str(), "{ 1, 1, 1, 1 }{ 1, 2.2, 3.3, 4.4 }");
  500. }
  501. template<> template<>
  502. void llquat_test_object_t::test<19>()
  503. {
  504. //test case for const char *OrderToString( const LLQuaternion::Order order ) fn
  505. const char* result = OrderToString(LLQuaternion::XYZ);
  506. ensure("1. OrderToString failed for XYZ", (0 == strcmp("XYZ", result)));
  507. result = OrderToString(LLQuaternion::YZX);
  508. ensure("2. OrderToString failed for YZX", (0 == strcmp("YZX", result)));
  509. result = OrderToString(LLQuaternion::ZXY);
  510. ensure(
  511. "3. OrderToString failed for ZXY",
  512. (0 == strcmp("ZXY", result)) &&
  513. (0 != strcmp("XYZ", result)) &&
  514. (0 != strcmp("YXZ", result)) &&
  515. (0 != strcmp("ZYX", result)) &&
  516. (0 != strcmp("XYZ", result)));
  517. result = OrderToString(LLQuaternion::XZY);
  518. ensure("4. OrderToString failed for XZY", (0 == strcmp("XZY", result)));
  519. result = OrderToString(LLQuaternion::ZYX);
  520. ensure("5. OrderToString failed for ZYX", (0 == strcmp("ZYX", result)));
  521. result = OrderToString(LLQuaternion::YXZ);
  522. ensure("6.OrderToString failed for YXZ", (0 == strcmp("YXZ", result)));
  523. }
  524. template<> template<>
  525. void llquat_test_object_t::test<20>()
  526. {
  527. //test case for LLQuaternion::Order StringToOrder( const char *str ) fn
  528. int result = StringToOrder("XYZ");
  529. ensure("1. LLQuaternion::Order StringToOrder(const char *str ) failed for XYZ", 0 == result);
  530. result = StringToOrder("YZX");
  531. ensure("2. LLQuaternion::Order StringToOrder(const char *str) failed for YZX", 1 == result);
  532. result = StringToOrder("ZXY");
  533. ensure("3. LLQuaternion::Order StringToOrder(const char *str) failed for ZXY", 2 == result);
  534. result = StringToOrder("XZY");
  535. ensure("4. LLQuaternion::Order StringToOrder(const char *str) failed for XZY", 3 == result);
  536. result = StringToOrder("YXZ");
  537. ensure("5. LLQuaternion::Order StringToOrder(const char *str) failed for YXZ", 4 == result);
  538. result = StringToOrder("ZYX");
  539. ensure("6. LLQuaternion::Order StringToOrder(const char *str) failed for ZYX", 5 == result);
  540. }
  541. template<> template<>
  542. void llquat_test_object_t::test<21>()
  543. {
  544. //void LLQuaternion::getAngleAxis(F32* angle, LLVector3 &vec) const fn
  545. F32 angle_value = 90.0f;
  546. LLVector3 vect(12.0f, 4.0f, 1.0f);
  547. LLQuaternion llquat(angle_value, vect);
  548. llquat.getAngleAxis(&angle_value, vect);
  549. ensure(
  550. "LLQuaternion::getAngleAxis(F32* angle, LLVector3 &vec) failed",
  551. is_approx_equal_fraction(2.035406f, angle_value, 16) &&
  552. is_approx_equal_fraction(0.315244f, vect.mV[1], 16) &&
  553. is_approx_equal_fraction(0.078811f, vect.mV[2], 16) &&
  554. is_approx_equal_fraction(0.945733f, vect.mV[0], 16));
  555. }
  556. template<> template<>
  557. void llquat_test_object_t::test<22>()
  558. {
  559. //test case for void LLQuaternion::getEulerAngles(F32 *roll, F32 *pitch, F32 *yaw) const fn
  560. F32 roll = -12.0f;
  561. F32 pitch = -22.43f;
  562. F32 yaw = 11.0f;
  563. LLQuaternion llquat;
  564. llquat.getEulerAngles(&roll, &pitch, &yaw);
  565. ensure(
  566. "LLQuaternion::getEulerAngles(F32 *roll, F32 *pitch, F32 *yaw) failed",
  567. is_approx_equal(0.000f, llquat.mQ[0]) &&
  568. is_approx_equal(0.000f, llquat.mQ[1]) &&
  569. is_approx_equal(0.000f, llquat.mQ[2]) &&
  570. is_approx_equal(1.000f, llquat.mQ[3]));
  571. }
  572. }