Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 

541 řádky
18 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright: (c) 2010-2014 Sam Hocevar <sam@hocevar.net>
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the Do What The Fuck You Want To
  7. // Public License, Version 2, as published by Sam Hocevar. See
  8. // http://www.wtfpl.net/ for more details.
  9. //
  10. #include <lol/engine-internal.h>
  11. #include <lolunit.h>
  12. namespace lol
  13. {
  14. lolunit_declare_fixture(QuaternionTest)
  15. {
  16. void SetUp()
  17. {
  18. /* Generate identity quaternions */
  19. m_vectorpairs.Push(vec3::axis_x, vec3::axis_x);
  20. m_vectorpairs.Push(2.f * vec3::axis_x, 3.f * vec3::axis_x);
  21. /* Generate 90-degree rotations */
  22. m_vectorpairs.Push(vec3::axis_x, vec3::axis_y);
  23. m_vectorpairs.Push(2.f * vec3::axis_x, 3.f * vec3::axis_y);
  24. /* Generate 180-degree rotations */
  25. m_vectorpairs.Push(vec3::axis_x, -vec3::axis_x);
  26. m_vectorpairs.Push(2.f * vec3::axis_x, -3.f * vec3::axis_x);
  27. /* Fill array with random test values */
  28. for (int i = 0; i < 10000; ++i)
  29. {
  30. vec3 v1 = lol::pow(10.f, rand(-5.f, 5.f))
  31. * vec3(rand(-1.f, 1.f), rand(-1.f, 1.f), rand(-1.f, 1.f));
  32. vec3 v2 = lol::pow(10.f, rand(-5.f, 5.f))
  33. * vec3(rand(-1.f, 1.f), rand(-1.f, 1.f), rand(-1.f, 1.f));
  34. m_vectorpairs.Push(v1, v2);
  35. }
  36. }
  37. void TearDown() {}
  38. lolunit_declare_test(Equality)
  39. {
  40. quat a4(1.f, 2.f, 3.f, 4.f);
  41. quat b4(0.f, 2.f, 3.f, 4.f);
  42. quat c4(1.f, 0.f, 3.f, 4.f);
  43. quat d4(1.f, 2.f, 0.f, 4.f);
  44. quat e4(1.f, 2.f, 3.f, 0.f);
  45. lolunit_assert_equal(a4, a4);
  46. lolunit_assert_not_different(a4, a4);
  47. lolunit_assert_different(a4, b4);
  48. lolunit_assert_not_equal(a4, b4);
  49. lolunit_assert_different(a4, c4);
  50. lolunit_assert_not_equal(a4, c4);
  51. lolunit_assert_different(a4, d4);
  52. lolunit_assert_not_equal(a4, d4);
  53. lolunit_assert_different(a4, e4);
  54. lolunit_assert_not_equal(a4, e4);
  55. }
  56. lolunit_declare_test(UnaryMinus)
  57. {
  58. quat a(1.f, 3.f, 2.f, 4.f);
  59. quat b(-1.f, -3.f, -2.f, -4.f);
  60. lolunit_assert_equal(a, -b);
  61. lolunit_assert_equal(-a, b);
  62. }
  63. lolunit_declare_test(Conjugate)
  64. {
  65. quat a(1.f, 3.f, 2.f, 4.f);
  66. quat b(1.f, -3.f, -2.f, -4.f);
  67. lolunit_assert_equal(a, ~b);
  68. lolunit_assert_equal(~a, b);
  69. }
  70. lolunit_declare_test(Norm)
  71. {
  72. quat a(2.f, -2.f, -8.f, 3.f);
  73. lolunit_assert_equal(norm(a), 9.f);
  74. quat b = a * ~a;
  75. quat c(norm(a) * norm(a), 0.f, 0.f, 0.f);
  76. lolunit_assert_equal(b, c);
  77. quat d(2.f, 5.f, -4.f, -2.f);
  78. lolunit_assert_equal(norm(a * d), norm(a) * norm(d));
  79. }
  80. lolunit_declare_test(Dot)
  81. {
  82. quat a(-1.f, 2.f, -3.f, 4.f);
  83. quat b(8.f, 7.f, 6.f, 5.f);
  84. lolunit_assert_equal(dot(a, b), 8.f);
  85. }
  86. lolunit_declare_test(Base)
  87. {
  88. quat one(1.f, 0.f, 0.f, 0.f);
  89. quat i(0.f, 1.f, 0.f, 0.f);
  90. quat j(0.f, 0.f, 1.f, 0.f);
  91. quat k(0.f, 0.f, 0.f, 1.f);
  92. lolunit_assert_equal(norm(one), 1.f);
  93. lolunit_assert_equal(norm(i), 1.f);
  94. lolunit_assert_equal(norm(j), 1.f);
  95. lolunit_assert_equal(norm(k), 1.f);
  96. lolunit_assert_equal(i * i, -one);
  97. lolunit_assert_equal(j * j, -one);
  98. lolunit_assert_equal(k * k, -one);
  99. lolunit_assert_equal(i * j * k, -one);
  100. lolunit_assert_equal(i * j, k);
  101. lolunit_assert_equal(j * i, -k);
  102. lolunit_assert_equal(j * k, i);
  103. lolunit_assert_equal(k * j, -i);
  104. lolunit_assert_equal(k * i, j);
  105. lolunit_assert_equal(i * k, -j);
  106. }
  107. lolunit_declare_test(Normalize)
  108. {
  109. quat a(2.f, -2.f, -8.f, 3.f);
  110. quat b = normalize(a);
  111. lolunit_assert_doubles_equal(norm(b), 1.0, 1e-5);
  112. }
  113. lolunit_declare_test(Reciprocal)
  114. {
  115. quat a(2.f, -2.f, -8.f, 3.f);
  116. quat b = re(a);
  117. quat c = 1.f / a;
  118. lolunit_assert_doubles_equal(b.w, c.w, 1e-5);
  119. lolunit_assert_doubles_equal(b.x, c.x, 1e-5);
  120. lolunit_assert_doubles_equal(b.y, c.y, 1e-5);
  121. lolunit_assert_doubles_equal(b.z, c.z, 1e-5);
  122. quat m1 = a * b;
  123. quat m2 = b * a;
  124. lolunit_assert_doubles_equal(m1.w, m2.w, 1e-5);
  125. lolunit_assert_doubles_equal(m1.x, m2.x, 1e-5);
  126. lolunit_assert_doubles_equal(m1.y, m2.y, 1e-5);
  127. lolunit_assert_doubles_equal(m1.z, m2.z, 1e-5);
  128. lolunit_assert_doubles_equal(m1.w, 1.0, 1e-5);
  129. lolunit_assert_doubles_equal(m1.x, 0.0, 1e-5);
  130. lolunit_assert_doubles_equal(m1.y, 0.0, 1e-5);
  131. lolunit_assert_doubles_equal(m1.z, 0.0, 1e-5);
  132. }
  133. lolunit_declare_test(Rotation)
  134. {
  135. /* Check that rotating 10 degrees twice means rotating 20 degrees */
  136. quat a = quat::rotate(10.f, vec3::axis_x);
  137. quat b = quat::rotate(20.f, vec3::axis_x);
  138. quat c = a * a;
  139. lolunit_assert_doubles_equal(c.w, b.w, 1e-5);
  140. lolunit_assert_doubles_equal(c.x, b.x, 1e-5);
  141. lolunit_assert_doubles_equal(c.y, b.y, 1e-5);
  142. lolunit_assert_doubles_equal(c.z, b.z, 1e-5);
  143. /* Check that rotating 10 degrees then 20 is the same as 20 then 10 */
  144. quat d = a * b;
  145. quat e = b * a;
  146. lolunit_assert_doubles_equal(e.w, d.w, 1e-5);
  147. lolunit_assert_doubles_equal(e.x, d.x, 1e-5);
  148. lolunit_assert_doubles_equal(e.y, d.y, 1e-5);
  149. lolunit_assert_doubles_equal(e.z, d.z, 1e-5);
  150. }
  151. lolunit_declare_test(ToAxisAngle)
  152. {
  153. quat q = quat::rotate(10.f, vec3::axis_x);
  154. vec3 axis = q.axis();
  155. float angle = q.angle();
  156. lolunit_assert_doubles_equal(1.0, axis.x, 1e-6);
  157. lolunit_assert_doubles_equal(0.0, axis.y, 1e-6);
  158. lolunit_assert_doubles_equal(0.0, axis.z, 1e-6);
  159. lolunit_assert_doubles_equal(10.0, (double)degrees(angle), 1e-6);
  160. }
  161. lolunit_declare_test(FromTwoVectors)
  162. {
  163. for (auto pair : m_vectorpairs)
  164. {
  165. vec3 a = pair.m1;
  166. vec3 b = pair.m2;
  167. vec3 da = normalize(a);
  168. vec3 db = normalize(b);
  169. quat q = quat::rotate(a, b);
  170. /* Check that q is a unit quaternion */
  171. lolunit_assert_doubles_equal(1.0, (double)norm(q), 1e-5);
  172. /* Check that q transforms da into db */
  173. vec3 c = q.transform(da);
  174. lolunit_assert_doubles_equal(c.x, db.x, 1e-5);
  175. lolunit_assert_doubles_equal(c.y, db.y, 1e-5);
  176. lolunit_assert_doubles_equal(c.z, db.z, 1e-5);
  177. /* Check that ~q transforms db into da */
  178. vec3 d = (~q).transform(db);
  179. lolunit_assert_doubles_equal(d.x, da.x, 1e-5);
  180. lolunit_assert_doubles_equal(d.y, da.y, 1e-5);
  181. lolunit_assert_doubles_equal(d.z, da.z, 1e-5);
  182. if (distance(da, db) > 1e-6f)
  183. {
  184. /* If da and db differ, check that the rotation axis is normal to both
  185. * vectors, which is only true if the rotation uses the shortest path. */
  186. vec3 axis = q.axis();
  187. lolunit_assert_doubles_equal(0.0, (double)dot(axis, da), 1e-5);
  188. lolunit_assert_doubles_equal(0.0, (double)dot(axis, db), 1e-5);
  189. }
  190. else
  191. {
  192. /* If da and db are roughly the same, check that the rotation angle
  193. * is zero. */
  194. lolunit_assert_doubles_equal(0.0, (double)q.angle(), 1e-5);
  195. }
  196. }
  197. }
  198. lolunit_declare_test(FromEulerNorm)
  199. {
  200. for (int i = 0; i < 100; ++i)
  201. {
  202. vec3 angles(rand(360.f), rand(360.f), rand(360.f));
  203. /* Tait-Bryan */
  204. quat q1 = quat::fromeuler_xyz(angles);
  205. lolunit_assert_doubles_equal(norm(q1), 1.f, 1e-5);
  206. quat q2 = quat::fromeuler_yzx(angles);
  207. lolunit_assert_doubles_equal(norm(q2), 1.f, 1e-5);
  208. quat q3 = quat::fromeuler_zxy(angles);
  209. lolunit_assert_doubles_equal(norm(q3), 1.f, 1e-5);
  210. quat q4 = quat::fromeuler_xzy(angles);
  211. lolunit_assert_doubles_equal(norm(q4), 1.f, 1e-5);
  212. quat q5 = quat::fromeuler_zyx(angles);
  213. lolunit_assert_doubles_equal(norm(q5), 1.f, 1e-5);
  214. quat q6 = quat::fromeuler_yxz(angles);
  215. lolunit_assert_doubles_equal(norm(q6), 1.f, 1e-5);
  216. /* Euler */
  217. quat q7 = quat::fromeuler_xyx(angles);
  218. lolunit_assert_doubles_equal(norm(q7), 1.f, 1e-5);
  219. quat q8 = quat::fromeuler_yzy(angles);
  220. lolunit_assert_doubles_equal(norm(q8), 1.f, 1e-5);
  221. quat q9 = quat::fromeuler_zxz(angles);
  222. lolunit_assert_doubles_equal(norm(q9), 1.f, 1e-5);
  223. quat q10 = quat::fromeuler_xzx(angles);
  224. lolunit_assert_doubles_equal(norm(q10), 1.f, 1e-5);
  225. quat q11 = quat::fromeuler_zyz(angles);
  226. lolunit_assert_doubles_equal(norm(q11), 1.f, 1e-5);
  227. quat q12 = quat::fromeuler_yxy(angles);
  228. lolunit_assert_doubles_equal(norm(q12), 1.f, 1e-5);
  229. }
  230. }
  231. lolunit_declare_test(FirstTwoEulerAngles)
  232. {
  233. for (int i = 0; i < 100; ++i)
  234. {
  235. /* We check that fromeuler_xyx and fromeuler_xyz give the
  236. * same result if the 3rd angle is zero. */
  237. vec3 angles(rand(360.f), rand(360.f), 0.f);
  238. quat q1, q2;
  239. q1 = quat::fromeuler_xyz(angles);
  240. q2 = quat::fromeuler_xyx(angles);
  241. lolunit_assert_doubles_equal(q1.w, q2.w, 1e-5);
  242. lolunit_assert_doubles_equal(q1.x, q2.x, 1e-5);
  243. lolunit_assert_doubles_equal(q1.y, q2.y, 1e-5);
  244. lolunit_assert_doubles_equal(q1.z, q2.z, 1e-5);
  245. q1 = quat::fromeuler_yzx(angles);
  246. q2 = quat::fromeuler_yzy(angles);
  247. lolunit_assert_doubles_equal(q1.w, q2.w, 1e-5);
  248. lolunit_assert_doubles_equal(q1.x, q2.x, 1e-5);
  249. lolunit_assert_doubles_equal(q1.y, q2.y, 1e-5);
  250. lolunit_assert_doubles_equal(q1.z, q2.z, 1e-5);
  251. q1 = quat::fromeuler_zxy(angles);
  252. q2 = quat::fromeuler_zxz(angles);
  253. lolunit_assert_doubles_equal(q1.w, q2.w, 1e-5);
  254. lolunit_assert_doubles_equal(q1.x, q2.x, 1e-5);
  255. lolunit_assert_doubles_equal(q1.y, q2.y, 1e-5);
  256. lolunit_assert_doubles_equal(q1.z, q2.z, 1e-5);
  257. q1 = quat::fromeuler_xzy(angles);
  258. q2 = quat::fromeuler_xzx(angles);
  259. lolunit_assert_doubles_equal(q1.w, q2.w, 1e-5);
  260. lolunit_assert_doubles_equal(q1.x, q2.x, 1e-5);
  261. lolunit_assert_doubles_equal(q1.y, q2.y, 1e-5);
  262. lolunit_assert_doubles_equal(q1.z, q2.z, 1e-5);
  263. q1 = quat::fromeuler_zyx(angles);
  264. q2 = quat::fromeuler_zyz(angles);
  265. lolunit_assert_doubles_equal(q1.w, q2.w, 1e-5);
  266. lolunit_assert_doubles_equal(q1.x, q2.x, 1e-5);
  267. lolunit_assert_doubles_equal(q1.y, q2.y, 1e-5);
  268. lolunit_assert_doubles_equal(q1.z, q2.z, 1e-5);
  269. q1 = quat::fromeuler_yxz(angles);
  270. q2 = quat::fromeuler_yxy(angles);
  271. lolunit_assert_doubles_equal(q1.w, q2.w, 1e-5);
  272. lolunit_assert_doubles_equal(q1.x, q2.x, 1e-5);
  273. lolunit_assert_doubles_equal(q1.y, q2.y, 1e-5);
  274. lolunit_assert_doubles_equal(q1.z, q2.z, 1e-5);
  275. }
  276. }
  277. lolunit_declare_test(LastTwoEulerAngles)
  278. {
  279. for (int i = 0; i < 100; ++i)
  280. {
  281. /* We check that fromeuler_zyz and fromeuler_xyz give the
  282. * same result if the 1st angle is zero. */
  283. vec3 angles(0.f, rand(360.f), rand(360.f));
  284. quat q1, q2;
  285. q1 = quat::fromeuler_xyz(angles);
  286. q2 = quat::fromeuler_zyz(angles);
  287. lolunit_assert_doubles_equal(q1.w, q2.w, 1e-5);
  288. lolunit_assert_doubles_equal(q1.x, q2.x, 1e-5);
  289. lolunit_assert_doubles_equal(q1.y, q2.y, 1e-5);
  290. lolunit_assert_doubles_equal(q1.z, q2.z, 1e-5);
  291. q1 = quat::fromeuler_yzx(angles);
  292. q2 = quat::fromeuler_xzx(angles);
  293. lolunit_assert_doubles_equal(q1.w, q2.w, 1e-5);
  294. lolunit_assert_doubles_equal(q1.x, q2.x, 1e-5);
  295. lolunit_assert_doubles_equal(q1.y, q2.y, 1e-5);
  296. lolunit_assert_doubles_equal(q1.z, q2.z, 1e-5);
  297. q1 = quat::fromeuler_zxy(angles);
  298. q2 = quat::fromeuler_yxy(angles);
  299. lolunit_assert_doubles_equal(q1.w, q2.w, 1e-5);
  300. lolunit_assert_doubles_equal(q1.x, q2.x, 1e-5);
  301. lolunit_assert_doubles_equal(q1.y, q2.y, 1e-5);
  302. lolunit_assert_doubles_equal(q1.z, q2.z, 1e-5);
  303. q1 = quat::fromeuler_xzy(angles);
  304. q2 = quat::fromeuler_yzy(angles);
  305. lolunit_assert_doubles_equal(q1.w, q2.w, 1e-5);
  306. lolunit_assert_doubles_equal(q1.x, q2.x, 1e-5);
  307. lolunit_assert_doubles_equal(q1.y, q2.y, 1e-5);
  308. lolunit_assert_doubles_equal(q1.z, q2.z, 1e-5);
  309. q1 = quat::fromeuler_zyx(angles);
  310. q2 = quat::fromeuler_xyx(angles);
  311. lolunit_assert_doubles_equal(q1.w, q2.w, 1e-5);
  312. lolunit_assert_doubles_equal(q1.x, q2.x, 1e-5);
  313. lolunit_assert_doubles_equal(q1.y, q2.y, 1e-5);
  314. lolunit_assert_doubles_equal(q1.z, q2.z, 1e-5);
  315. q1 = quat::fromeuler_yxz(angles);
  316. q2 = quat::fromeuler_zxz(angles);
  317. lolunit_assert_doubles_equal(q1.w, q2.w, 1e-5);
  318. lolunit_assert_doubles_equal(q1.x, q2.x, 1e-5);
  319. lolunit_assert_doubles_equal(q1.y, q2.y, 1e-5);
  320. lolunit_assert_doubles_equal(q1.z, q2.z, 1e-5);
  321. }
  322. }
  323. lolunit_declare_test(TaitBryanAngles)
  324. {
  325. for (int i = 0; i < 100; ++i)
  326. {
  327. /* Pick a random point and a random quaternion. We want
  328. * to check whether going to Tait-Bryan angles and back to
  329. * quaternion creates the same transform. */
  330. vec3 p(rand(1.f, 2.f), rand(1.f, 2.f), rand(1.f, 2.f));
  331. quat q0 = normalize(quat(rand(-1.f, 1.f), rand(-1.f, 1.f),
  332. rand(-1.f, 1.f), rand(-1.f, 1.f)));
  333. vec3 p0 = q0.transform(p);
  334. /* x-y-z */
  335. quat q1 = quat::fromeuler_xyz(vec3::toeuler_xyz(q0));
  336. vec3 p1 = q1.transform(p);
  337. lolunit_assert_doubles_equal(p1.x, p0.x, 1e-4);
  338. lolunit_assert_doubles_equal(p1.y, p0.y, 1e-4);
  339. lolunit_assert_doubles_equal(p1.z, p0.z, 1e-4);
  340. /* y-z-x */
  341. q1 = quat::fromeuler_yzx(vec3::toeuler_yzx(q0));
  342. p1 = q1.transform(p);
  343. lolunit_assert_doubles_equal(p1.x, p0.x, 1e-4);
  344. lolunit_assert_doubles_equal(p1.y, p0.y, 1e-4);
  345. lolunit_assert_doubles_equal(p1.z, p0.z, 1e-4);
  346. /* z-x-y */
  347. q1 = quat::fromeuler_zxy(vec3::toeuler_zxy(q0));
  348. p1 = q1.transform(p);
  349. lolunit_assert_doubles_equal(p1.x, p0.x, 1e-4);
  350. lolunit_assert_doubles_equal(p1.y, p0.y, 1e-4);
  351. lolunit_assert_doubles_equal(p1.z, p0.z, 1e-4);
  352. /* x-z-y */
  353. q1 = quat::fromeuler_xzy(vec3::toeuler_xzy(q0));
  354. p1 = q1.transform(p);
  355. lolunit_assert_doubles_equal(p1.x, p0.x, 1e-4);
  356. lolunit_assert_doubles_equal(p1.y, p0.y, 1e-4);
  357. lolunit_assert_doubles_equal(p1.z, p0.z, 1e-4);
  358. /* z-y-x */
  359. q1 = quat::fromeuler_zyx(vec3::toeuler_zyx(q0));
  360. p1 = q1.transform(p);
  361. lolunit_assert_doubles_equal(p1.x, p0.x, 1e-4);
  362. lolunit_assert_doubles_equal(p1.y, p0.y, 1e-4);
  363. lolunit_assert_doubles_equal(p1.z, p0.z, 1e-4);
  364. /* y-x-z */
  365. q1 = quat::fromeuler_yxz(vec3::toeuler_yxz(q0));
  366. p1 = q1.transform(p);
  367. lolunit_assert_doubles_equal(p1.x, p0.x, 1e-4);
  368. lolunit_assert_doubles_equal(p1.y, p0.y, 1e-4);
  369. lolunit_assert_doubles_equal(p1.z, p0.z, 1e-4);
  370. }
  371. }
  372. lolunit_declare_test(EulerAngles)
  373. {
  374. for (int i = 0; i < 100; ++i)
  375. {
  376. /* Pick a random point and a random quaternion. We want
  377. * to check whether going to Euler angles and back to
  378. * quaternion creates the same transform. */
  379. vec3 p(rand(1.f, 2.f), rand(1.f, 2.f), rand(1.f, 2.f));
  380. quat q0 = normalize(quat(rand(-1.f, 1.f), rand(-1.f, 1.f),
  381. rand(-1.f, 1.f), rand(-1.f, 1.f)));
  382. vec3 p0 = q0.transform(p);
  383. /* x-y-x */
  384. quat q1 = quat::fromeuler_xyx(vec3::toeuler_xyx(q0));
  385. vec3 p1 = q1.transform(p);
  386. lolunit_assert_doubles_equal(p1.x, p0.x, 1e-4);
  387. lolunit_assert_doubles_equal(p1.y, p0.y, 1e-4);
  388. lolunit_assert_doubles_equal(p1.z, p0.z, 1e-4);
  389. /* y-z-y */
  390. q1 = quat::fromeuler_yzy(vec3::toeuler_yzy(q0));
  391. p1 = q1.transform(p);
  392. lolunit_assert_doubles_equal(p1.x, p0.x, 1e-4);
  393. lolunit_assert_doubles_equal(p1.y, p0.y, 1e-4);
  394. lolunit_assert_doubles_equal(p1.z, p0.z, 1e-4);
  395. /* z-x-z */
  396. q1 = quat::fromeuler_zxz(vec3::toeuler_zxz(q0));
  397. p1 = q1.transform(p);
  398. lolunit_assert_doubles_equal(p1.x, p0.x, 1e-4);
  399. lolunit_assert_doubles_equal(p1.y, p0.y, 1e-4);
  400. lolunit_assert_doubles_equal(p1.z, p0.z, 1e-4);
  401. /* x-z-x */
  402. q1 = quat::fromeuler_xzx(vec3::toeuler_xzx(q0));
  403. p1 = q1.transform(p);
  404. lolunit_assert_doubles_equal(p1.x, p0.x, 1e-4);
  405. lolunit_assert_doubles_equal(p1.y, p0.y, 1e-4);
  406. lolunit_assert_doubles_equal(p1.z, p0.z, 1e-4);
  407. /* z-y-z */
  408. q1 = quat::fromeuler_zyz(vec3::toeuler_zyz(q0));
  409. p1 = q1.transform(p);
  410. lolunit_assert_doubles_equal(p1.x, p0.x, 1e-4);
  411. lolunit_assert_doubles_equal(p1.y, p0.y, 1e-4);
  412. lolunit_assert_doubles_equal(p1.z, p0.z, 1e-4);
  413. /* y-x-y */
  414. q1 = quat::fromeuler_yxy(vec3::toeuler_yxy(q0));
  415. p1 = q1.transform(p);
  416. lolunit_assert_doubles_equal(p1.x, p0.x, 1e-4);
  417. lolunit_assert_doubles_equal(p1.y, p0.y, 1e-4);
  418. lolunit_assert_doubles_equal(p1.z, p0.z, 1e-4);
  419. }
  420. }
  421. private:
  422. array<vec3, vec3> m_vectorpairs;
  423. };
  424. } /* namespace lol */