gl_vec.cc 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773
  1. #include "catch.hpp"
  2. #include "gl_vec.hh"
  3. using namespace gl;
  4. // Test approximations.
  5. template<typename T>
  6. bool approxEq(T x, T y)
  7. {
  8. return std::abs(x - y) < T(1.0e-5);
  9. }
  10. template<int N, typename T>
  11. bool approxEq(const vecN<N, T>& x, const vecN<N, T>&y)
  12. {
  13. return length2(x - y) < T(1.0e-4);
  14. }
  15. TEST_CASE("gl_vec: rsqrt")
  16. {
  17. CHECK(rsqrt(16.0f) == 0.25f);
  18. CHECK(rsqrt(16.0 ) == 0.25 );
  19. }
  20. TEST_CASE("gl_vec: radians, degrees")
  21. {
  22. CHECK(approxEq(radians( 0.0), 0.0 ));
  23. CHECK(approxEq(radians( 90.0), M_PI / 2));
  24. CHECK(approxEq(radians(180.0), M_PI ));
  25. CHECK(approxEq(degrees(0.0 ), 0.0));
  26. CHECK(approxEq(degrees(M_PI / 2), 90.0));
  27. CHECK(approxEq(degrees(M_PI ), 180.0));
  28. }
  29. // It's useful to test both integer and float variants because the
  30. // former are implemented in plain C++ and (only) the latter have SSE
  31. // optimizations.
  32. TEST_CASE("gl_vec: constructors")
  33. {
  34. SECTION("default constructor") {
  35. vec2 v2;
  36. CHECK(v2[0] == 0);
  37. CHECK(v2[1] == 0);
  38. ivec2 i2;
  39. CHECK(i2[0] == 0);
  40. CHECK(i2[1] == 0);
  41. vec3 v3;
  42. CHECK(v3[0] == 0);
  43. CHECK(v3[1] == 0);
  44. CHECK(v3[2] == 0);
  45. ivec3 i3;
  46. CHECK(i3[0] == 0);
  47. CHECK(i3[1] == 0);
  48. CHECK(i3[2] == 0);
  49. vec4 v4;
  50. CHECK(v4[0] == 0);
  51. CHECK(v4[1] == 0);
  52. CHECK(v4[2] == 0);
  53. CHECK(v4[3] == 0);
  54. ivec4 i4;
  55. CHECK(i4[0] == 0);
  56. CHECK(i4[1] == 0);
  57. CHECK(i4[2] == 0);
  58. CHECK(i4[3] == 0);
  59. }
  60. SECTION("broadcast constructor") {
  61. vec2 v2(2);
  62. CHECK(v2[0] == 2);
  63. CHECK(v2[1] == 2);
  64. ivec2 i2(2);
  65. CHECK(i2[0] == 2);
  66. CHECK(i2[1] == 2);
  67. vec3 v3(3);
  68. CHECK(v3[0] == 3);
  69. CHECK(v3[1] == 3);
  70. CHECK(v3[2] == 3);
  71. ivec3 i3(3);
  72. CHECK(i3[0] == 3);
  73. CHECK(i3[1] == 3);
  74. CHECK(i3[2] == 3);
  75. vec4 v4(4);
  76. CHECK(v4[0] == 4);
  77. CHECK(v4[1] == 4);
  78. CHECK(v4[2] == 4);
  79. CHECK(v4[3] == 4);
  80. ivec4 i4(4);
  81. CHECK(i4[0] == 4);
  82. CHECK(i4[1] == 4);
  83. CHECK(i4[2] == 4);
  84. CHECK(i4[3] == 4);
  85. }
  86. SECTION("per-element constructor") {
  87. vec2 v2(2, 3);
  88. CHECK(v2[0] == 2);
  89. CHECK(v2[1] == 3);
  90. ivec2 i2(2, 3);
  91. CHECK(i2[0] == 2);
  92. CHECK(i2[1] == 3);
  93. vec3 v3(3, 4, 5);
  94. CHECK(v3[0] == 3);
  95. CHECK(v3[1] == 4);
  96. CHECK(v3[2] == 5);
  97. ivec3 i3(3, 4, 5);
  98. CHECK(i3[0] == 3);
  99. CHECK(i3[1] == 4);
  100. CHECK(i3[2] == 5);
  101. vec4 v4(4, 5, 6, 7);
  102. CHECK(v4[0] == 4);
  103. CHECK(v4[1] == 5);
  104. CHECK(v4[2] == 6);
  105. CHECK(v4[3] == 7);
  106. ivec4 i4(4, 5, 6, 7);
  107. CHECK(i4[0] == 4);
  108. CHECK(i4[1] == 5);
  109. CHECK(i4[2] == 6);
  110. CHECK(i4[3] == 7);
  111. }
  112. SECTION("construct from smaller vectors/scalar") {
  113. vec3 v3(3, vec2(4, 5));
  114. CHECK(v3[0] == 3);
  115. CHECK(v3[1] == 4);
  116. CHECK(v3[2] == 5);
  117. ivec3 i3(ivec2(4, 5), 3);
  118. CHECK(i3[0] == 4);
  119. CHECK(i3[1] == 5);
  120. CHECK(i3[2] == 3);
  121. vec4 v4(4, vec3(5, 6, 7));
  122. CHECK(v4[0] == 4);
  123. CHECK(v4[1] == 5);
  124. CHECK(v4[2] == 6);
  125. CHECK(v4[3] == 7);
  126. ivec4 i4(ivec3(5, 6, 7), 4);
  127. CHECK(i4[0] == 5);
  128. CHECK(i4[1] == 6);
  129. CHECK(i4[2] == 7);
  130. CHECK(i4[3] == 4);
  131. vec4 w4(vec2(5, 6), vec2(7, 8));
  132. CHECK(w4[0] == 5);
  133. CHECK(w4[1] == 6);
  134. CHECK(w4[2] == 7);
  135. CHECK(w4[3] == 8);
  136. ivec4 j4(ivec2(5, 6), ivec2(7, 8));
  137. CHECK(j4[0] == 5);
  138. CHECK(j4[1] == 6);
  139. CHECK(j4[2] == 7);
  140. CHECK(j4[3] == 8);
  141. #if 0
  142. // Not implemeneted yet (also not yet needed).
  143. vec4 x4(1, vec2(3, 5), 7);
  144. CHECK(x4[0] == 1);
  145. CHECK(x4[1] == 3);
  146. CHECK(x4[2] == 5);
  147. CHECK(x4[3] == 7);
  148. ivec4 k4(2, ivec2(4, 6), 8);
  149. CHECK(k4[0] == 2);
  150. CHECK(k4[1] == 4);
  151. CHECK(k4[2] == 6);
  152. CHECK(k4[3] == 8);
  153. #endif
  154. #if 0
  155. // Ok, compile error:
  156. // static assertion failed: wrong vector length in constructor
  157. ivec3 wrong1(3, ivec3(4, 5, 6));
  158. ivec4 wrong2(3, ivec2(4, 5));
  159. ivec4 wrong3(ivec2(4, 5), ivec3(8, 9));
  160. #endif
  161. }
  162. }
  163. TEST_CASE("gl_vec: modify elements")
  164. {
  165. vec2 v2;
  166. v2[0] = 5;
  167. CHECK(v2[0] == 5);
  168. CHECK(v2[1] == 0);
  169. v2[1] = 7;
  170. CHECK(v2[0] == 5);
  171. CHECK(v2[1] == 7);
  172. ivec2 i2;
  173. i2[0] = 5;
  174. CHECK(i2[0] == 5);
  175. CHECK(i2[1] == 0);
  176. i2[1] = 7;
  177. CHECK(i2[0] == 5);
  178. CHECK(i2[1] == 7);
  179. vec3 v3(1);
  180. v3[1] = 2;
  181. CHECK(v3[0] == 1);
  182. CHECK(v3[1] == 2);
  183. CHECK(v3[2] == 1);
  184. ivec3 i3(1);
  185. i3[1] = 2;
  186. CHECK(i3[0] == 1);
  187. CHECK(i3[1] == 2);
  188. CHECK(i3[2] == 1);
  189. vec4 v4(1, 2, 3, 4);
  190. v4[0] = 9; v4[2] = 8;
  191. CHECK(v4[0] == 9);
  192. CHECK(v4[1] == 2);
  193. CHECK(v4[2] == 8);
  194. CHECK(v4[3] == 4);
  195. ivec4 i4(1, 2, 3, 4);
  196. i4[0] = 9; i4[2] = 8;
  197. CHECK(i4[0] == 9);
  198. CHECK(i4[1] == 2);
  199. CHECK(i4[2] == 8);
  200. CHECK(i4[3] == 4);
  201. }
  202. TEST_CASE("gl_vec: (in)equality")
  203. {
  204. CHECK( vec2(1, 2) == vec2(1, 2));
  205. CHECK( vec2(1, 2) != vec2(1, 4));
  206. CHECK( vec2(1, 2) != vec2(3, 2));
  207. CHECK( vec2(1, 2) != vec2(3, 4));
  208. CHECK(ivec2(1, 2) == ivec2(1, 2));
  209. CHECK(ivec2(1, 2) != ivec2(1, 4));
  210. CHECK(ivec2(1, 2) != ivec2(3, 2));
  211. CHECK(ivec2(1, 2) != ivec2(3, 4));
  212. CHECK( vec3(1, 2, 3) == vec3(1, 2, 3));
  213. CHECK( vec3(1, 2, 3) != vec3(1, 2, 4));
  214. CHECK(ivec3(1, 2, 3) == ivec3(1, 2, 3));
  215. CHECK(ivec3(1, 2, 3) != ivec3(1, 2, 4));
  216. CHECK( vec4(1, 2, 3, 4) == vec4(1, 2, 3, 4));
  217. CHECK( vec4(1, 2, 3, 4) != vec4(1, 2, 4, 4));
  218. CHECK(ivec4(1, 2, 3, 4) == ivec4(1, 2, 3, 4));
  219. CHECK(ivec4(1, 2, 3, 4) != ivec4(1, 2, 4, 4));
  220. }
  221. TEST_CASE("gl_vec: copy constructor, assignment")
  222. {
  223. SECTION("vec2") {
  224. vec2 v(2, 3);
  225. vec2 w(v); CHECK(v == w);
  226. v[0] = 9; CHECK(v != w);
  227. w = v; CHECK(v == w);
  228. }
  229. SECTION("ivec2") {
  230. ivec2 v(2, 3);
  231. ivec2 w(v); CHECK(v == w);
  232. v[1] = 9; CHECK(v != w);
  233. w = v; CHECK(v == w);
  234. }
  235. SECTION("vec3") {
  236. vec3 v(3, 4, 5);
  237. vec3 w(v); CHECK(v == w);
  238. v[2] = 8; CHECK(v != w);
  239. w = v; CHECK(v == w);
  240. }
  241. SECTION("ivec3") {
  242. ivec3 v(3, 4, 5);
  243. ivec3 w(v); CHECK(v == w);
  244. v[1] = 8; CHECK(v != w);
  245. w = v; CHECK(v == w);
  246. }
  247. SECTION("vec4") {
  248. vec4 v(4, 5, 6, 7);
  249. vec4 w(v); CHECK(v == w);
  250. v[3] = 0; CHECK(v != w);
  251. w = v; CHECK(v == w);
  252. }
  253. SECTION("ivec4") {
  254. ivec4 v(4, 5, 6, 7);
  255. ivec4 w(v); CHECK(v == w);
  256. v[0] = 1; CHECK(v != w);
  257. w = v; CHECK(v == w);
  258. }
  259. }
  260. TEST_CASE("gl_vec: construct from larger vector")
  261. {
  262. vec4 v4(1, 2, 3, 4);
  263. vec3 v3(7, 8, 9);
  264. CHECK(vec3(v4) == vec3(1, 2, 3));
  265. CHECK(vec2(v4) == vec2(1, 2));
  266. CHECK(vec2(v3) == vec2(7, 8));
  267. ivec4 i4(1, 2, 3, 4);
  268. ivec3 i3(7, 8, 9);
  269. CHECK(ivec3(i4) == ivec3(1, 2, 3));
  270. CHECK(ivec2(i4) == ivec2(1, 2));
  271. CHECK(ivec2(i3) == ivec2(7, 8));
  272. }
  273. // From here on I'll skip tests on vec2 and ivec2.
  274. // Vectors of dimension 2 and 3 are handled by the same C++ code, so
  275. // if there's a bug it should show up in both types.
  276. TEST_CASE("gl_vec: vector add")
  277. {
  278. vec3 v3(1, 2, 3); vec4 v4(1, 2, 3, 4);
  279. ivec3 i3(1, 2, 3); ivec4 i4(1, 2, 3, 4);
  280. CHECK((v3 + vec3(4, 5, 6)) == vec3(5, 7, 9));
  281. CHECK((i3 + ivec3(4, 5, 6)) == ivec3(5, 7, 9));
  282. CHECK((v4 + vec4(4, 5, 6, 7)) == vec4(5, 7, 9, 11));
  283. CHECK((i4 + ivec4(4, 5, 6, 7)) == ivec4(5, 7, 9, 11));
  284. v3 += vec3(2, 3, 4);
  285. i3 += ivec3(2, 3, 4);
  286. v4 += vec4(2, 3, 4, 5);
  287. i4 += ivec4(2, 3, 4, 5);
  288. CHECK(v3 == vec3(3, 5, 7));
  289. CHECK(i3 == ivec3(3, 5, 7));
  290. CHECK(v4 == vec4(3, 5, 7, 9));
  291. CHECK(i4 == ivec4(3, 5, 7, 9));
  292. }
  293. TEST_CASE("gl_vec: vector subtract")
  294. {
  295. vec3 v3(1, 2, 3); vec4 v4(1, 2, 3, 4);
  296. ivec3 i3(1, 2, 3); ivec4 i4(1, 2, 3, 4);
  297. CHECK((v3 - vec3(4, 3, 2)) == vec3(-3, -1, 1));
  298. CHECK((i3 - ivec3(4, 3, 2)) == ivec3(-3, -1, 1));
  299. CHECK((v4 - vec4(4, 3, 2, 1)) == vec4(-3, -1, 1, 3));
  300. CHECK((i4 - ivec4(4, 3, 2, 1)) == ivec4(-3, -1, 1, 3));
  301. v3 -= vec3(2, 4, 6);
  302. i3 -= ivec3(2, 4, 6);
  303. v4 -= vec4(2, 4, 6, 8);
  304. i4 -= ivec4(2, 4, 6, 8);
  305. CHECK(v3 == vec3(-1, -2, -3));
  306. CHECK(i3 == ivec3(-1, -2, -3));
  307. CHECK(v4 == vec4(-1, -2, -3, -4));
  308. CHECK(i4 == ivec4(-1, -2, -3, -4));
  309. }
  310. TEST_CASE("gl_vec: vector negate")
  311. {
  312. CHECK((- vec3(4, -3, 2)) == vec3(-4, 3, -2));
  313. CHECK((-ivec3(4, -3, 2)) == ivec3(-4, 3, -2));
  314. CHECK((- vec4(4, -3, 2, -1)) == vec4(-4, 3, -2, 1));
  315. CHECK((-ivec4(4, -3, 2, -1)) == ivec4(-4, 3, -2, 1));
  316. }
  317. TEST_CASE("gl_vec: component-wise vector multiplication")
  318. {
  319. vec3 v3(0, 2, -3); vec4 v4(0, 2, -3, 4);
  320. ivec3 i3(0, 2, -3); ivec4 i4(0, 2, -3, 4);
  321. // scalar * vector
  322. CHECK((2.0f * v3) == vec3(0, 4, -6));
  323. CHECK((2 * i3) == ivec3(0, 4, -6));
  324. CHECK((2.0f * v4) == vec4(0, 4, -6, 8));
  325. CHECK((2 * i4) == ivec4(0, 4, -6, 8));
  326. // vector * scalar
  327. CHECK((v3 * 2.0f) == vec3(0, 4, -6));
  328. CHECK((i3 * 2 ) == ivec3(0, 4, -6));
  329. CHECK((v4 * 2.0f) == vec4(0, 4, -6, 8));
  330. CHECK((i4 * 2 ) == ivec4(0, 4, -6, 8));
  331. // vector * vector
  332. vec3 w3(-1, 2, -3); vec4 w4(-1, 2, -3, -4);
  333. ivec3 j3(-1, 2, -3); ivec4 j4(-1, 2, -3, -4);
  334. CHECK((v3 * w3) == vec3(0, 4, 9));
  335. CHECK((i3 * j3) == ivec3(0, 4, 9));
  336. CHECK((v4 * w4) == vec4(0, 4, 9, -16));
  337. CHECK((i4 * j4) == ivec4(0, 4, 9, -16));
  338. // *= scalar
  339. v3 *= 2.0f; CHECK(v3 == vec3(0, 4, -6));
  340. i3 *= 2; CHECK(i3 == ivec3(0, 4, -6));
  341. v4 *= 2.0f; CHECK(v4 == vec4(0, 4, -6, 8));
  342. i4 *= 2; CHECK(i4 == ivec4(0, 4, -6, 8));
  343. // *= vector
  344. v3 *= w3; CHECK(v3 == vec3(0, 8, 18));
  345. i3 *= j3; CHECK(i3 == ivec3(0, 8, 18));
  346. v4 *= w4; CHECK(v4 == vec4(0, 8, 18, -32));
  347. i4 *= j4; CHECK(i4 == ivec4(0, 8, 18, -32));
  348. }
  349. TEST_CASE("gl_vec: reciprocal (only floating point)")
  350. {
  351. CHECK(approxEq(recip(vec3(4, 2, 0.5)), vec3(0.25, 0.5, 2)));
  352. CHECK(approxEq(recip(vec4(4, 2, 0.5, 1)), vec4(0.25, 0.5, 2, 1)));
  353. }
  354. TEST_CASE("gl_vec: component-wise division (only floating point)")
  355. {
  356. vec3 v3( 0, 1, -4);
  357. vec3 w3(-1, -2, 2);
  358. CHECK((v3 / 2.0f) == vec3( 0, 0.5f, -2));
  359. CHECK((6.0f / w3) == vec3(-6, -3, 3));
  360. CHECK((v3 / w3) == vec3( 0, -0.5f, -2));
  361. vec4 v4( 2, 1, -4, -3);
  362. vec4 w4(-1, 2, 2, -6);
  363. CHECK(approxEq((v4 / -2.0f), vec4(-1, -0.5f, 2, 1.5f)));
  364. CHECK(approxEq((6.0f / w4), vec4(-6, 3, 3, -1)));
  365. CHECK(approxEq((v4 / w4), vec4(-2, 0.5f, -2, 0.5f)));
  366. }
  367. TEST_CASE("gl_vec: component-wise min/max")
  368. {
  369. CHECK(min( vec3(2, 3, 4), vec3(1, -5, 7)) == vec3(1, -5, 4));
  370. CHECK(min(ivec3(2, 3, 4), ivec3(1, -5, 7)) == ivec3(1, -5, 4));
  371. CHECK(min( vec4(1, -2, 5, -7), vec4(0, 2, -4, -3)) == vec4(0, -2, -4, -7));
  372. CHECK(min(ivec4(1, -2, 5, -7), ivec4(0, 2, -4, -3)) == ivec4(0, -2, -4, -7));
  373. CHECK(max( vec3(2, 3, 4), vec3(1, -5, 7)) == vec3(2, 3, 7));
  374. CHECK(max(ivec3(2, 3, 4), ivec3(1, -5, 7)) == ivec3(2, 3, 7));
  375. CHECK(max( vec4(1, -2, 5, -7), vec4(0, 2, -4, -3)) == vec4(1, 2, 5, -3));
  376. CHECK(max(ivec4(1, -2, 5, -7), ivec4(0, 2, -4, -3)) == ivec4(1, 2, 5, -3));
  377. }
  378. TEST_CASE("gl_vec: minimum component within a vector")
  379. {
  380. CHECK(min_component( vec3(1, 5, -7.2f)) == -7.2f);
  381. CHECK(min_component(ivec3(3, 2, 4)) == 2);
  382. CHECK(min_component( vec4(-1, 2, 5.2f, 0)) == -1);
  383. CHECK(min_component(ivec4(1, -2, 5, -7)) == -7);
  384. }
  385. TEST_CASE("gl_vec: clamp") {
  386. CHECK(clamp( vec3(2, 3, 4), vec3(0, 4, -4), vec3(4, 7, 0)) == vec3(2, 4, 0));
  387. CHECK(clamp(ivec3(2, 3, 4), ivec3(0, 4, -4), ivec3(4, 7, 0)) == ivec3(2, 4, 0));
  388. CHECK(clamp( vec4(4, 2, 7, 1), vec4(0, 3, 2, 1), vec4(4, 6, 8, 3)) == vec4(4, 3, 7, 1));
  389. CHECK(clamp(ivec4(4, 2, 7, 1), ivec4(0, 3, 2, 1), ivec4(4, 6, 8, 3)) == ivec4(4, 3, 7, 1));
  390. CHECK(clamp( vec3(2, 3, 4), 1.0f, 3.0f) == vec3(2, 3, 3));
  391. CHECK(clamp(ivec3(2, 3, 4), 1, 3 ) == ivec3(2, 3, 3));
  392. CHECK(clamp( vec4(4, 2, 7, 1), 2.0f, 6.0f) == vec4(4, 2, 6, 2));
  393. CHECK(clamp(ivec4(4, 2, 7, 1), 2, 6 ) == ivec4(4, 2, 6, 2));
  394. }
  395. TEST_CASE("gl_vec: sum of vector components")
  396. {
  397. CHECK(sum( vec3(4, -3, 2)) == 3.0f);
  398. CHECK(sum(ivec3(4, -3, 2)) == 3 );
  399. CHECK(sum( vec4(4, -3, 2, -1)) == 2.0f);
  400. CHECK(sum(ivec4(4, -3, 2, -1)) == 2 );
  401. CHECK(sum_broadcast(vec3(4, -3, 2)) == vec3(3.0f));
  402. CHECK(sum_broadcast(vec4(4, -3, 2, -1)) == vec4(2.0f));
  403. }
  404. TEST_CASE("gl_vec: dot product")
  405. {
  406. CHECK(dot( vec3(4, -3, 2), vec3(-1, 3, 2) ) == -9.0f);
  407. CHECK(dot(ivec3(4, -3, 2), ivec3(-1, 3, 2) ) == -9 );
  408. CHECK(dot( vec4(4, -3, 2, -1), vec4(-1, 3, 2, -2)) == -7.0f);
  409. CHECK(dot(ivec4(4, -3, 2, -1), ivec4(-1, 3, 2, -2)) == -7 );
  410. CHECK(dot_broadcast(vec3(4, -3, 2), vec3(-1, 3, 2) ) == vec3(-9.0f));
  411. CHECK(dot_broadcast(vec4(4, -3, 2, -1), vec4(-1, 3, 2, -2)) == vec4(-7.0f));
  412. }
  413. TEST_CASE("gl_vec: cross product (only for vectors of length 3)")
  414. {
  415. CHECK(cross( vec3(4, -3, 2), vec3(-1, 3, 2)) == vec3(-12, -10, 9));
  416. CHECK(cross(ivec3(4, -3, 2), ivec3(-1, 3, 2)) == ivec3(-12, -10, 9));
  417. }
  418. TEST_CASE("gl_vec: vector length squared (2-norm squared)")
  419. {
  420. CHECK(length2( vec3(4, -3, 2 )) == 29.0f);
  421. CHECK(length2(ivec3(4, -3, 2 )) == 29 );
  422. CHECK(length2( vec4(4, -3, 2, -1)) == 30.0f);
  423. CHECK(length2(ivec4(4, -3, 2, -1)) == 30 );
  424. }
  425. TEST_CASE("gl_vec: vector length (2-norm), (only floating point)")
  426. {
  427. CHECK(length(vec3(4, -3, 2 )) == sqrtf(29.0f));
  428. CHECK(length(vec4(4, -3, 2, -1)) == sqrtf(30.0f));
  429. }
  430. TEST_CASE("gl_vec: vector normalization, only floating point")
  431. {
  432. CHECK(normalize(vec3( 0, 4, -3 )) == vec3( 0.0f, 0.8f, -0.6f));
  433. CHECK(normalize(vec4(-4, 0, 0, 3)) == vec4(-0.8f, 0.0f, 0.0f, 0.6f));
  434. }
  435. TEST_CASE("gl_vec: round")
  436. {
  437. CHECK(round(vec3( 1.1f, 2.6f, -3.8f)) == ivec3( 1, 3, -4));
  438. CHECK(round(vec4(-1.1f, 2.4f, 3.8f, -4.6f)) == ivec4(-1, 2, 4, -5));
  439. // round integers, nop
  440. CHECK(round(ivec4(1, -2, 3, -4)) == ivec4(1, -2, 3, -4));
  441. }
  442. TEST_CASE("gl_vec: trunc")
  443. {
  444. CHECK(trunc(vec3( 1.1f, 2.5f, -3.8f)) == ivec3( 1, 2, -3));
  445. CHECK(trunc(vec4(-1.1f, 2.5f, 3.8f, -4.5f)) == ivec4(-1, 2, 3, -4));
  446. // trunc integers, nop
  447. CHECK(trunc(ivec4(1, -2, 3, -4)) == ivec4(1, -2, 3, -4));
  448. }
  449. #if 0
  450. // The following functions are not part of the actual test. They get compiled,
  451. // but never executed. I used them to (manually) inspect the quality of the
  452. // generated code. Mostly only for vec4, because the code was only optimized
  453. // for that type.
  454. void test_constr(vec4& z)
  455. {
  456. z = vec4();
  457. }
  458. void test_constr(float x, vec4& z)
  459. {
  460. z = vec4(x);
  461. }
  462. void test_constr(float a, float b, float c, float d, vec4& z)
  463. {
  464. z = vec4(a, b, c, d);
  465. }
  466. void test_change0(float x, vec4& z)
  467. {
  468. z[0] = x;
  469. }
  470. void test_change2(float x, vec4& z)
  471. {
  472. z[2] = x;
  473. }
  474. void test_extract0(const vec4& x, float& z)
  475. {
  476. z = x[0];
  477. }
  478. void test_extract2(const vec4& x, float& z)
  479. {
  480. z = x[2];
  481. }
  482. bool test_equal(const vec4& x, const vec4& y)
  483. {
  484. return x == y;
  485. }
  486. bool test_not_equal(const vec4& x, const vec4& y)
  487. {
  488. return x != y;
  489. }
  490. void test_add(const vec4& x, const vec4& y, vec4& z)
  491. {
  492. z = x + y;
  493. }
  494. void test_add(vec4& x, const vec4& y)
  495. {
  496. x += y;
  497. }
  498. void test_negate(const vec4& x, vec4& y)
  499. {
  500. y = -x;
  501. }
  502. void test_mul(const vec4& x, const vec4& y, vec4& z)
  503. {
  504. z = x * y;
  505. }
  506. void test_mul(float x, const vec4& y, vec4& z)
  507. {
  508. z = x * y;
  509. }
  510. void test_div(const vec4& x, const vec4& y, vec4& z)
  511. {
  512. z = x / y;
  513. }
  514. void test_div(float x, const vec4& y, vec4& z)
  515. {
  516. z = x / y;
  517. }
  518. void test_div(const vec4& x, float y, vec4& z)
  519. {
  520. z = x / y;
  521. }
  522. void test_sum(const vec4& x, float& y)
  523. {
  524. y = sum(x);
  525. }
  526. void test_sum_broadcast(const vec4& x, vec4& y)
  527. {
  528. y = sum_broadcast(x);
  529. }
  530. void test_dot(const vec4& x, const vec4& y, float& z)
  531. {
  532. z = dot(x, y);
  533. }
  534. void test_dot_broadcast(const vec4& x, const vec4& y, vec4& z)
  535. {
  536. z = dot_broadcast(x, y);
  537. }
  538. void test_length2(const vec4& x, float& y)
  539. {
  540. y = length2(x);
  541. }
  542. void test_length(const vec4& x, float& y)
  543. {
  544. y = length(x);
  545. }
  546. void test_normalize(const vec4& x, vec4& y)
  547. {
  548. y = normalize(x);
  549. }
  550. void test_recip(const vec4& x, vec4& y)
  551. {
  552. y = recip(x);
  553. }
  554. void test_constr(vec3& z)
  555. {
  556. z = vec3();
  557. }
  558. void test_constr(float x, vec3& z)
  559. {
  560. z = vec3(x);
  561. }
  562. void test_constr(float a, float b, float c, vec3& z)
  563. {
  564. z = vec3(a, b, c);
  565. }
  566. void test_constr(vec4 x, vec3& y)
  567. {
  568. y = vec3(x);
  569. }
  570. void test_change0(float x, vec3& z)
  571. {
  572. z[0] = x;
  573. }
  574. void test_change2(float x, vec3& z)
  575. {
  576. z[2] = x;
  577. }
  578. void test_extract0(const vec3& x, float& z)
  579. {
  580. z = x[0];
  581. }
  582. void test_extract2(const vec3& x, float& z)
  583. {
  584. z = x[2];
  585. }
  586. bool test_equal(const vec3& x, const vec3& y)
  587. {
  588. return x == y;
  589. }
  590. bool test_not_equal(const vec3& x, const vec3& y)
  591. {
  592. return x != y;
  593. }
  594. void test_add(const vec3& x, const vec3& y, vec3& z)
  595. {
  596. z = x + y;
  597. }
  598. void test_add(vec3& x, const vec3& y)
  599. {
  600. x += y;
  601. }
  602. void test_negate(const vec3& x, vec3& y)
  603. {
  604. y = -x;
  605. }
  606. void test_mul(const vec3& x, const vec3& y, vec3& z)
  607. {
  608. z = x * y;
  609. }
  610. void test_mul(float x, const vec3& y, vec3& z)
  611. {
  612. z = x * y;
  613. }
  614. void test_div(const vec3& x, const vec3& y, vec3& z)
  615. {
  616. z = x / y;
  617. }
  618. void test_div(float x, const vec3& y, vec3& z)
  619. {
  620. z = x / y;
  621. }
  622. void test_div(const vec3& x, float y, vec3& z)
  623. {
  624. z = x / y;
  625. }
  626. void test_min(const vec3& x, const vec3& y, vec3& z)
  627. {
  628. z = min(x, y);
  629. }
  630. void test_min(const vec4& x, const vec4& y, vec4& z)
  631. {
  632. z = min(x, y);
  633. }
  634. void test_clamp(const vec3& x, const vec3& y, const vec3& z, vec3& w)
  635. {
  636. w = clamp(x, y, z);
  637. }
  638. void test_clamp(const vec4& x, const vec4& y, const vec4& z, vec4& w)
  639. {
  640. w = clamp(x, y, z);
  641. }
  642. void test_clamp(const vec3& x, float y, float z, vec3& w)
  643. {
  644. w = clamp(x, y, z);
  645. }
  646. void test_clamp(const vec4& x, float y, float z, vec4& w)
  647. {
  648. w = clamp(x, y, z);
  649. }
  650. void test_clamp(const vec4& x, vec4& y)
  651. {
  652. y = clamp(x, 0.0f, 1.0f);
  653. }
  654. void test_sum(const vec3& x, float& y)
  655. {
  656. y = sum(x);
  657. }
  658. void test_dot(const vec3& x, const vec3& y, float& z)
  659. {
  660. z = dot(x, y);
  661. }
  662. void test_length2(const vec3& x, float& y)
  663. {
  664. y = length2(x);
  665. }
  666. void test_length(const vec3& x, float& y)
  667. {
  668. y = length(x);
  669. }
  670. void test_normalize(const vec3& x, vec3& y)
  671. {
  672. y = normalize(x);
  673. }
  674. void test_round(const vec4& x, ivec4& y)
  675. {
  676. y = round(x);
  677. }
  678. void test_trunc(const vec4& x, ivec4& y)
  679. {
  680. y = trunc(x);
  681. }
  682. #endif