Math.cpp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <Tests/Framework/Framework.h>
  6. #include <AnKi/Math.h>
  7. using namespace anki;
  8. /// Test the common perators between a vector and another vector
  9. template<typename Vec>
  10. void operatorsSame()
  11. {
  12. const U size = Vec::kComponentCount;
  13. using T = typename Vec::Scalar;
  14. Vec a, b;
  15. Array<T, size> add, sub, mul, div;
  16. for(U i = 0; i < size; i++)
  17. {
  18. T v0 = T(F64(i * 10) / 2.0 + 1.0);
  19. T v1 = T(F64(i * 1000) / 5.123 + 1.0);
  20. a[i] = v0;
  21. b[i] = v1;
  22. add[i] = v0 + v1;
  23. sub[i] = v0 - v1;
  24. mul[i] = v0 * v1;
  25. div[i] = v0 / v1;
  26. }
  27. Vec c = a + b;
  28. Vec d = a - b;
  29. Vec e = a * b;
  30. Vec f = a / b;
  31. for(U i = 0; i < size; i++)
  32. {
  33. ANKI_TEST_EXPECT_EQ(c[i], add[i]);
  34. ANKI_TEST_EXPECT_EQ(d[i], sub[i]);
  35. ANKI_TEST_EXPECT_EQ(e[i], mul[i]);
  36. ANKI_TEST_EXPECT_EQ(f[i], div[i]);
  37. }
  38. c = a;
  39. c += b;
  40. d = a;
  41. d -= b;
  42. e = a;
  43. e *= b;
  44. f = a;
  45. f /= b;
  46. for(U i = 0; i < size; i++)
  47. {
  48. ANKI_TEST_EXPECT_EQ(c[i], add[i]);
  49. ANKI_TEST_EXPECT_EQ(d[i], sub[i]);
  50. ANKI_TEST_EXPECT_EQ(e[i], mul[i]);
  51. ANKI_TEST_EXPECT_EQ(f[i], div[i]);
  52. }
  53. }
  54. /// Test the dot prods
  55. template<typename Vec>
  56. void dot()
  57. {
  58. const U size = Vec::kComponentCount;
  59. using T = typename Vec::Scalar;
  60. T res = 0;
  61. Vec vec;
  62. for(U i = 0; i < size; i++)
  63. {
  64. T x = T(i * 666 + 1);
  65. vec[i] = x;
  66. res += x * x;
  67. }
  68. ANKI_TEST_EXPECT_EQ(vec.dot(vec), res);
  69. }
  70. /// Test length and normalization
  71. template<typename Vec>
  72. void length()
  73. {
  74. using T = typename Vec::Scalar;
  75. U size = Vec::kComponentCount;
  76. Vec vec;
  77. T res = 0;
  78. for(U i = 0; i < size; i++)
  79. {
  80. T x = T(i * 666);
  81. vec[i] = x;
  82. res += x * x;
  83. }
  84. res = T(sqrt(F32(res)));
  85. ANKI_TEST_EXPECT_EQ(vec.length(), res);
  86. if(Vec::kIsInteger)
  87. {
  88. ANKI_TEST_EXPECT_EQ(vec.normalize(), vec / res);
  89. }
  90. else
  91. {
  92. auto a = vec / res;
  93. auto b = vec.normalize();
  94. for(U i = 0; i < size; i++)
  95. {
  96. ANKI_TEST_EXPECT_NEAR(a[i], b[i], 0.0001);
  97. }
  98. }
  99. }
  100. template<typename Vec>
  101. void comparision()
  102. {
  103. U size = Vec::kComponentCount;
  104. using Scalar = typename Vec::Scalar;
  105. Vec a, a1, b;
  106. for(U i = 0; i < size; i++)
  107. {
  108. a[i] = Scalar(i * 666);
  109. a1[i] = a[i];
  110. b[i] = a[i] + 1;
  111. }
  112. ANKI_TEST_EXPECT_EQ(a == a1, true);
  113. ANKI_TEST_EXPECT_EQ(a != a1, false);
  114. ANKI_TEST_EXPECT_EQ(a < a1, false);
  115. ANKI_TEST_EXPECT_EQ(a <= a1, true);
  116. ANKI_TEST_EXPECT_EQ(a > a1, false);
  117. ANKI_TEST_EXPECT_EQ(a >= a1, true);
  118. ANKI_TEST_EXPECT_EQ(a == b, false);
  119. ANKI_TEST_EXPECT_EQ(a != b, true);
  120. ANKI_TEST_EXPECT_EQ(a < b, true);
  121. ANKI_TEST_EXPECT_EQ(a <= b, true);
  122. ANKI_TEST_EXPECT_EQ(a > b, false);
  123. ANKI_TEST_EXPECT_EQ(a >= b, false);
  124. }
  125. /// Common vector tests
  126. template<typename Vec>
  127. void commonVecTests()
  128. {
  129. operatorsSame<Vec>();
  130. dot<Vec>();
  131. length<Vec>();
  132. comparision<Vec>();
  133. }
  134. ANKI_TEST(Math, Vec2)
  135. {
  136. commonVecTests<Vec2>();
  137. commonVecTests<IVec2>();
  138. commonVecTests<UVec2>();
  139. }
  140. ANKI_TEST(Math, Vec3)
  141. {
  142. commonVecTests<Vec3>();
  143. commonVecTests<IVec3>();
  144. commonVecTests<UVec3>();
  145. }
  146. ANKI_TEST(Math, Vec4)
  147. {
  148. commonVecTests<Vec4>();
  149. commonVecTests<IVec4>();
  150. commonVecTests<UVec4>();
  151. }
  152. ANKI_TEST(Math, VecOperators)
  153. {
  154. // Float vec vs scalar
  155. const Vec3 a(1.0f, -2.0f, 3.5f);
  156. const Vec3 add = a + 2.0f;
  157. const Vec3 sub = a - 1.0f;
  158. const Vec3 mul = a * 2.0f;
  159. const Vec3 div = a / 2.0f;
  160. ANKI_TEST_EXPECT_EQ(add, Vec3(3.0f, 0.0f, 5.5f));
  161. ANKI_TEST_EXPECT_EQ(sub, Vec3(0.0f, -3.0f, 2.5f));
  162. ANKI_TEST_EXPECT_EQ(mul, Vec3(2.0f, -4.0f, 7.0f));
  163. ANKI_TEST_EXPECT_NEAR(div.x, 0.5f, 1e-6f);
  164. ANKI_TEST_EXPECT_NEAR(div.y, -1.0f, 1e-6f);
  165. ANKI_TEST_EXPECT_NEAR(div.z, 1.75f, 1e-6f);
  166. // Integer-specific operators
  167. const IVec2 ai(4, 8);
  168. const IVec2 bi(1, 3);
  169. ANKI_TEST_EXPECT_EQ(ai << bi, IVec2(8, 64));
  170. ANKI_TEST_EXPECT_EQ(ai >> bi, IVec2(2, 1));
  171. ANKI_TEST_EXPECT_EQ(ai & bi, IVec2(0, 0));
  172. ANKI_TEST_EXPECT_EQ(ai | bi, IVec2(5, 11));
  173. ANKI_TEST_EXPECT_EQ(ai ^ bi, IVec2(5, 11));
  174. ANKI_TEST_EXPECT_EQ(ai % bi, IVec2(0, 2));
  175. // Mixed vector/scalar integer operators
  176. IVec2 ci(2, 3);
  177. ci <<= 1;
  178. ANKI_TEST_EXPECT_EQ(ci, IVec2(4, 6));
  179. ci &= IVec2(6);
  180. ANKI_TEST_EXPECT_EQ(ci, IVec2(4, 6));
  181. ci |= 1;
  182. ANKI_TEST_EXPECT_EQ(ci, IVec2(5, 7));
  183. }
  184. ANKI_TEST(Math, VecExtras)
  185. {
  186. // Cross product (Vec3)
  187. const Vec3 a(1.0f, 2.0f, 3.0f);
  188. const Vec3 b(4.0f, 5.0f, 6.0f);
  189. const Vec3 cross = a.cross(b);
  190. ANKI_TEST_EXPECT_NEAR(cross.x, -3.0f, 1e-5f);
  191. ANKI_TEST_EXPECT_NEAR(cross.y, 6.0f, 1e-5f);
  192. ANKI_TEST_EXPECT_NEAR(cross.z, -3.0f, 1e-5f);
  193. // Projection on vector
  194. const Vec3 proj = a.projectTo(Vec3::xAxis());
  195. ANKI_TEST_EXPECT_NEAR(proj.x, 1.0f, 1e-5f);
  196. ANKI_TEST_EXPECT_NEAR(proj.y, 0.0f, 1e-5f);
  197. ANKI_TEST_EXPECT_NEAR(proj.z, 0.0f, 1e-5f);
  198. // Projection on ray
  199. const Vec3 projRay = a.projectTo(Vec3(0.0f), Vec3::yAxis());
  200. ANKI_TEST_EXPECT_NEAR(projRay.x, 0.0f, 1e-5f);
  201. ANKI_TEST_EXPECT_NEAR(projRay.y, 2.0f, 1e-5f);
  202. ANKI_TEST_EXPECT_NEAR(projRay.z, 0.0f, 1e-5f);
  203. // Lerp (scalar t)
  204. const Vec3 lerpRes = a.lerp(b, 0.5f);
  205. ANKI_TEST_EXPECT_NEAR(lerpRes.x, 2.5f, 1e-5f);
  206. ANKI_TEST_EXPECT_NEAR(lerpRes.y, 3.5f, 1e-5f);
  207. ANKI_TEST_EXPECT_NEAR(lerpRes.z, 4.5f, 1e-5f);
  208. // Clamp and reciprocal
  209. const Vec3 clamped = Vec3(-1.0f, 2.0f, 10.0f).clamp(0.0f, 5.0f);
  210. ANKI_TEST_EXPECT_NEAR(clamped.x, 0.0f, 1e-5f);
  211. ANKI_TEST_EXPECT_NEAR(clamped.y, 2.0f, 1e-5f);
  212. ANKI_TEST_EXPECT_NEAR(clamped.z, 5.0f, 1e-5f);
  213. const Vec2 recip = Vec2(2.0f, -4.0f).reciprocal();
  214. ANKI_TEST_EXPECT_NEAR(recip.x, 0.5f, 1e-6f);
  215. ANKI_TEST_EXPECT_NEAR(recip.y, -0.25f, 1e-6f);
  216. // Perspective divide (Vec4)
  217. const Vec4 v4(2.0f, 4.0f, 6.0f, 2.0f);
  218. const Vec4 pdiv = v4.perspectiveDivide();
  219. ANKI_TEST_EXPECT_NEAR(pdiv.x, 1.0f, 1e-6f);
  220. ANKI_TEST_EXPECT_NEAR(pdiv.y, 2.0f, 1e-6f);
  221. ANKI_TEST_EXPECT_NEAR(pdiv.z, 3.0f, 1e-6f);
  222. ANKI_TEST_EXPECT_NEAR(pdiv.w, 1.0f, 1e-6f);
  223. }
  224. /// Test the common operators between a matrices
  225. template<typename Mat>
  226. void matOperatorsSame()
  227. {
  228. const U size = Mat::kSize;
  229. using T = typename Mat::Scalar;
  230. Mat a, b;
  231. Array<T, size> add, sub;
  232. for(U i = 0; i < size; i++)
  233. {
  234. T v0 = T(i * 10 / 2);
  235. T v1 = T(F64(i * 1000) / 5.123);
  236. a[i] = v0;
  237. b[i] = v1;
  238. add[i] = v0 + v1;
  239. sub[i] = v0 - v1;
  240. }
  241. Mat c = a + b;
  242. Mat d = a - b;
  243. for(U i = 0; i < size; i++)
  244. {
  245. ANKI_TEST_EXPECT_EQ(c[i], add[i]);
  246. ANKI_TEST_EXPECT_EQ(d[i], sub[i]);
  247. }
  248. c = a;
  249. c += b;
  250. d = a;
  251. d -= b;
  252. for(U i = 0; i < size; i++)
  253. {
  254. ANKI_TEST_EXPECT_EQ(c[i], add[i]);
  255. ANKI_TEST_EXPECT_EQ(d[i], sub[i]);
  256. }
  257. }
  258. /// Get a filled matrix
  259. template<typename Mat>
  260. Mat getNonEmptyMat(typename Mat::Scalar offset = 0)
  261. {
  262. Mat out;
  263. for(U i = 0; i < Mat::kSize; i++)
  264. {
  265. out[i] = typename Mat::Scalar(i) + offset;
  266. }
  267. return out;
  268. }
  269. /// Some getters setters
  270. template<typename Mat, typename RowVec, typename ColVec>
  271. void matSettersGetters()
  272. {
  273. using T = typename Mat::Scalar;
  274. Mat m(T(0));
  275. m.setRow(1, RowVec(1.0));
  276. ANKI_TEST_EXPECT_EQ(m.getRow(1), RowVec(1.0));
  277. m.setColumn(1, ColVec(2.0));
  278. m.setColumn(2, ColVec(3.0));
  279. ANKI_TEST_EXPECT_EQ(m.getColumn(1), ColVec(2.0));
  280. ANKI_TEST_EXPECT_EQ(m.getColumn(2), ColVec(3.0));
  281. ANKI_TEST_EXPECT_EQ(m.getYAxis(), m.getColumn(1));
  282. }
  283. /// Transpose
  284. template<typename Mat>
  285. void transpose()
  286. {
  287. Mat a = getNonEmptyMat<Mat>();
  288. Mat b = a.transpose();
  289. for(U j = 0; j < Mat::kRowCount; j++)
  290. {
  291. for(U i = 0; i < Mat::kColumnCount; i++)
  292. {
  293. ANKI_TEST_EXPECT_EQ(a(j, i), b(i, j));
  294. }
  295. }
  296. b.transposeRotationPart();
  297. for(U j = 0; j < 3; j++)
  298. {
  299. for(U i = 0; i < 3; i++)
  300. {
  301. ANKI_TEST_EXPECT_EQ(a(j, i), b(j, i));
  302. }
  303. }
  304. }
  305. /// Mat vector multiplication
  306. template<typename Mat, typename VecIn, typename VecOut>
  307. void matVecMul()
  308. {
  309. using T = typename Mat::Scalar;
  310. Mat m = getNonEmptyMat<Mat>();
  311. VecIn v;
  312. for(U i = 0; i < VecIn::kSize; i++)
  313. {
  314. v[i] = i;
  315. }
  316. VecOut out = m * v;
  317. VecOut out1;
  318. for(U j = 0; j < Mat::kRowCount; j++)
  319. {
  320. T sum = 0;
  321. for(U i = 0; i < Mat::kColumnCount; i++)
  322. {
  323. sum += m(j, i) * v[j];
  324. }
  325. out1[j] = sum;
  326. }
  327. ANKI_TEST_EXPECT_EQ(out1, out);
  328. }
  329. template<typename Mat, typename RowVec, typename ColVec>
  330. void commonMatTests()
  331. {
  332. matOperatorsSame<Mat>();
  333. matSettersGetters<Mat, RowVec, ColVec>();
  334. }
  335. ANKI_TEST(Math, Mat3)
  336. {
  337. commonMatTests<Mat3, Vec3, Vec3>();
  338. transpose<Mat3>();
  339. // mat*mat
  340. {
  341. Mat3 a = getNonEmptyMat<Mat3>(0);
  342. Mat3 b = getNonEmptyMat<Mat3>(1);
  343. Mat3 c = a * b;
  344. Mat3 d = Mat3(18.000, 21.000, 24.000, 54.000, 66.000, 78.000, 90.000, 111.000, 132.000);
  345. ANKI_TEST_EXPECT_EQ(c, d);
  346. }
  347. // mat*vec
  348. {
  349. Mat3 m = getNonEmptyMat<Mat3>(1.0);
  350. Vec3 v(0.0, 1.0, 2.0);
  351. ANKI_TEST_EXPECT_EQ(m * v, Vec3(8, 17, 26));
  352. }
  353. }
  354. ANKI_TEST(Math, Mat4)
  355. {
  356. commonMatTests<Mat4, Vec4, Vec4>();
  357. transpose<Mat4>();
  358. // mat*mat
  359. {
  360. Mat4 a = getNonEmptyMat<Mat4>(0);
  361. Mat4 b = getNonEmptyMat<Mat4>(1);
  362. Mat4 c = a * b;
  363. Mat4 d =
  364. Mat4(62.0, 68.0, 74.0, 80.0, 174.000, 196.000, 218.000, 240.000, 286.000, 324.000, 362.000, 400.000, 398.000, 452.000, 506.000, 560.000);
  365. ANKI_TEST_EXPECT_EQ(c, d);
  366. }
  367. // mat*vec
  368. {
  369. Mat4 m = getNonEmptyMat<Mat4>(1.0);
  370. Vec4 v(0.0, 1.0, 2.0, 3.0);
  371. ANKI_TEST_EXPECT_EQ(m * v, Vec4(20, 44, 68, 92));
  372. }
  373. }
  374. ANKI_TEST(Math, Mat3x4)
  375. {
  376. commonMatTests<Mat3x4, Vec4, Vec3>();
  377. // combine transforms
  378. {
  379. Mat3x4 a = getNonEmptyMat<Mat3x4>(0);
  380. Mat3x4 b = getNonEmptyMat<Mat3x4>(1);
  381. Mat3x4 c = a.combineTransformations(b);
  382. Mat3x4 d = Mat3x4(23.000, 26.000, 29.000, 35.000, 83.000, 98.000, 113.000, 135.000, 143.000, 170.000, 197.000, 235.000);
  383. ANKI_TEST_EXPECT_EQ(c, d);
  384. }
  385. // mat*vec
  386. {
  387. Mat3x4 m = getNonEmptyMat<Mat3x4>(1.0);
  388. Vec4 v(0.0, 1.0, 2.0, 3.0);
  389. ANKI_TEST_EXPECT_EQ(m * v, Vec3(20, 44, 68));
  390. }
  391. }