core_func_common.cpp 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339
  1. #define GLM_FORCE_EXPLICIT_CTOR
  2. #include <glm/common.hpp>
  3. #include <glm/gtc/constants.hpp>
  4. #include <glm/gtc/epsilon.hpp>
  5. #include <glm/gtc/vec1.hpp>
  6. #include <glm/gtc/random.hpp>
  7. #include <vector>
  8. #include <cstdio>
  9. #include <cmath>
  10. #include <ctime>
  11. // This file has divisions by zero to test isnan
  12. #if GLM_COMPILER & GLM_COMPILER_VC
  13. # pragma warning(disable : 4723)
  14. #endif
  15. namespace floor_
  16. {
  17. static int test()
  18. {
  19. int Error(0);
  20. {
  21. float A = 1.1f;
  22. float B = glm::floor(A);
  23. Error += glm::epsilonEqual(B, 1.f, 0.0001f) ? 0 : 1;
  24. }
  25. {
  26. double A = 1.1;
  27. double B = glm::floor(A);
  28. Error += glm::epsilonEqual(B, 1.0, 0.0001) ? 0 : 1;
  29. }
  30. {
  31. glm::vec1 A(1.1f);
  32. glm::vec1 B = glm::floor(A);
  33. Error += glm::all(glm::epsilonEqual(B, glm::vec1(1.0), 0.0001f)) ? 0 : 1;
  34. }
  35. {
  36. glm::dvec1 A(1.1);
  37. glm::dvec1 B = glm::floor(A);
  38. Error += glm::all(glm::epsilonEqual(B, glm::dvec1(1.0), 0.0001)) ? 0 : 1;
  39. }
  40. {
  41. glm::vec2 A(1.1f);
  42. glm::vec2 B = glm::floor(A);
  43. Error += glm::all(glm::epsilonEqual(B, glm::vec2(1.0), 0.0001f)) ? 0 : 1;
  44. }
  45. {
  46. glm::dvec2 A(1.1);
  47. glm::dvec2 B = glm::floor(A);
  48. Error += glm::all(glm::epsilonEqual(B, glm::dvec2(1.0), 0.0001)) ? 0 : 1;
  49. }
  50. {
  51. glm::vec3 A(1.1f);
  52. glm::vec3 B = glm::floor(A);
  53. Error += glm::all(glm::epsilonEqual(B, glm::vec3(1.0), 0.0001f)) ? 0 : 1;
  54. }
  55. {
  56. glm::dvec3 A(1.1);
  57. glm::dvec3 B = glm::floor(A);
  58. Error += glm::all(glm::epsilonEqual(B, glm::dvec3(1.0), 0.0001)) ? 0 : 1;
  59. }
  60. {
  61. glm::vec4 A(1.1f);
  62. glm::vec4 B = glm::floor(A);
  63. Error += glm::all(glm::epsilonEqual(B, glm::vec4(1.0), 0.0001f)) ? 0 : 1;
  64. }
  65. {
  66. glm::dvec4 A(1.1);
  67. glm::dvec4 B = glm::floor(A);
  68. Error += glm::all(glm::epsilonEqual(B, glm::dvec4(1.0), 0.0001)) ? 0 : 1;
  69. }
  70. return Error;
  71. }
  72. }//namespace floor
  73. namespace modf_
  74. {
  75. static int test()
  76. {
  77. int Error(0);
  78. {
  79. float X(1.5f);
  80. float I(0.0f);
  81. float A = glm::modf(X, I);
  82. Error += I == 1.0f ? 0 : 1;
  83. Error += A == 0.5f ? 0 : 1;
  84. }
  85. {
  86. glm::vec4 X(1.1f, 1.2f, 1.5f, 1.7f);
  87. glm::vec4 I(0.0f);
  88. glm::vec4 A = glm::modf(X, I);
  89. Error += I == glm::vec4(1.0f) ? 0 : 1;
  90. Error += glm::all(glm::epsilonEqual(A, glm::vec4(0.1f, 0.2f, 0.5f, 0.7f), 0.00001f)) ? 0 : 1;
  91. }
  92. {
  93. glm::dvec4 X(1.1, 1.2, 1.5, 1.7);
  94. glm::dvec4 I(0.0);
  95. glm::dvec4 A = glm::modf(X, I);
  96. Error += I == glm::dvec4(1.0) ? 0 : 1;
  97. Error += glm::all(glm::epsilonEqual(A, glm::dvec4(0.1, 0.2, 0.5, 0.7), 0.000000001)) ? 0 : 1;
  98. }
  99. {
  100. double X(1.5);
  101. double I(0.0);
  102. double A = glm::modf(X, I);
  103. Error += I == 1.0 ? 0 : 1;
  104. Error += A == 0.5 ? 0 : 1;
  105. }
  106. return Error;
  107. }
  108. }//namespace modf
  109. namespace mod_
  110. {
  111. static int test()
  112. {
  113. int Error(0);
  114. {
  115. float A(1.5f);
  116. float B(1.0f);
  117. float C = glm::mod(A, B);
  118. Error += glm::abs(C - 0.5f) < 0.00001f ? 0 : 1;
  119. }
  120. {
  121. float A(-0.2f);
  122. float B(1.0f);
  123. float C = glm::mod(A, B);
  124. Error += glm::abs(C - 0.8f) < 0.00001f ? 0 : 1;
  125. }
  126. {
  127. float A(3.0);
  128. float B(2.0f);
  129. float C = glm::mod(A, B);
  130. Error += glm::abs(C - 1.0f) < 0.00001f ? 0 : 1;
  131. }
  132. {
  133. glm::vec4 A(3.0);
  134. float B(2.0f);
  135. glm::vec4 C = glm::mod(A, B);
  136. Error += glm::all(glm::epsilonEqual(C, glm::vec4(1.0f), 0.00001f)) ? 0 : 1;
  137. }
  138. {
  139. glm::vec4 A(3.0);
  140. glm::vec4 B(2.0f);
  141. glm::vec4 C = glm::mod(A, B);
  142. Error += glm::all(glm::epsilonEqual(C, glm::vec4(1.0f), 0.00001f)) ? 0 : 1;
  143. }
  144. return Error;
  145. }
  146. }//namespace mod_
  147. namespace floatBitsToInt
  148. {
  149. static int test()
  150. {
  151. int Error = 0;
  152. {
  153. float A = 1.0f;
  154. int B = glm::floatBitsToInt(A);
  155. float C = glm::intBitsToFloat(B);
  156. Error += glm::epsilonEqual(A, C, 0.0001f) ? 0 : 1;
  157. }
  158. {
  159. glm::vec2 A(1.0f, 2.0f);
  160. glm::ivec2 B = glm::floatBitsToInt(A);
  161. glm::vec2 C = glm::intBitsToFloat(B);
  162. Error += glm::all(glm::epsilonEqual(A, C, 0.0001f)) ? 0 : 1;
  163. }
  164. {
  165. glm::vec3 A(1.0f, 2.0f, 3.0f);
  166. glm::ivec3 B = glm::floatBitsToInt(A);
  167. glm::vec3 C = glm::intBitsToFloat(B);
  168. Error += glm::all(glm::epsilonEqual(A, C, 0.0001f)) ? 0 : 1;
  169. }
  170. {
  171. glm::vec4 A(1.0f, 2.0f, 3.0f, 4.0f);
  172. glm::ivec4 B = glm::floatBitsToInt(A);
  173. glm::vec4 C = glm::intBitsToFloat(B);
  174. Error += glm::all(glm::epsilonEqual(A, C, 0.0001f)) ? 0 : 1;
  175. }
  176. return Error;
  177. }
  178. }//namespace floatBitsToInt
  179. namespace floatBitsToUint
  180. {
  181. static int test()
  182. {
  183. int Error = 0;
  184. {
  185. float A = 1.0f;
  186. glm::uint B = glm::floatBitsToUint(A);
  187. float C = glm::uintBitsToFloat(B);
  188. Error += glm::epsilonEqual(A, C, 0.0001f) ? 0 : 1;
  189. }
  190. {
  191. glm::vec2 A(1.0f, 2.0f);
  192. glm::uvec2 B = glm::floatBitsToUint(A);
  193. glm::vec2 C = glm::uintBitsToFloat(B);
  194. Error += glm::all(glm::epsilonEqual(A, C, 0.0001f)) ? 0 : 1;
  195. }
  196. {
  197. glm::vec3 A(1.0f, 2.0f, 3.0f);
  198. glm::uvec3 B = glm::floatBitsToUint(A);
  199. glm::vec3 C = glm::uintBitsToFloat(B);
  200. Error += glm::all(glm::epsilonEqual(A, C, 0.0001f)) ? 0 : 1;
  201. }
  202. {
  203. glm::vec4 A(1.0f, 2.0f, 3.0f, 4.0f);
  204. glm::uvec4 B = glm::floatBitsToUint(A);
  205. glm::vec4 C = glm::uintBitsToFloat(B);
  206. Error += glm::all(glm::epsilonEqual(A, C, 0.0001f)) ? 0 : 1;
  207. }
  208. return Error;
  209. }
  210. }//namespace floatBitsToUint
  211. namespace min_
  212. {
  213. static int test()
  214. {
  215. int Error = 0;
  216. glm::vec1 A0 = glm::min(glm::vec1(1), glm::vec1(1));
  217. glm::vec2 B0 = glm::min(glm::vec2(1), glm::vec2(1));
  218. glm::vec2 B1 = glm::min(glm::vec2(1), 1.0f);
  219. bool B2 = glm::all(glm::equal(B0, B1));
  220. Error += B2 ? 0 : 1;
  221. glm::vec3 C0 = glm::min(glm::vec3(1), glm::vec3(1));
  222. glm::vec3 C1 = glm::min(glm::vec3(1), 1.0f);
  223. bool C2 = glm::all(glm::equal(C0, C1));
  224. Error += C2 ? 0 : 1;
  225. glm::vec4 D0 = glm::min(glm::vec4(1), glm::vec4(1));
  226. glm::vec4 D1 = glm::min(glm::vec4(1), 1.0f);
  227. bool D2 = glm::all(glm::equal(D0, D1));
  228. Error += D2 ? 0 : 1;
  229. return Error;
  230. }
  231. int min_tern(int a, int b)
  232. {
  233. return a < b ? a : b;
  234. }
  235. int min_int(int x, int y)
  236. {
  237. return y ^ ((x ^ y) & -(x < y));
  238. }
  239. static int perf(std::size_t Count)
  240. {
  241. std::vector<int> A(Count);
  242. std::vector<int> B(Count);
  243. std::size_t const InternalCount = 200000;
  244. for(std::size_t i = 0; i < Count; ++i)
  245. {
  246. A[i] = glm::linearRand(-1000, 1000);
  247. B[i] = glm::linearRand(-1000, 1000);
  248. }
  249. int Error = 0;
  250. glm::int32 SumA = 0;
  251. {
  252. std::clock_t Timestamp0 = std::clock();
  253. for (std::size_t j = 0; j < InternalCount; ++j)
  254. for (std::size_t i = 0; i < Count; ++i)
  255. SumA += min_tern(A[i], B[i]);
  256. std::clock_t Timestamp1 = std::clock();
  257. std::printf("min_tern Time %d clocks\n", static_cast<int>(Timestamp1 - Timestamp0));
  258. }
  259. glm::int32 SumB = 0;
  260. {
  261. std::clock_t Timestamp0 = std::clock();
  262. for (std::size_t j = 0; j < InternalCount; ++j)
  263. for (std::size_t i = 0; i < Count; ++i)
  264. SumB += min_int(A[i], B[i]);
  265. std::clock_t Timestamp1 = std::clock();
  266. std::printf("min_int Time %d clocks\n", static_cast<int>(Timestamp1 - Timestamp0));
  267. }
  268. Error += SumA == SumB ? 0 : 1;
  269. return Error;
  270. }
  271. }//namespace min_
  272. namespace max_
  273. {
  274. static int test()
  275. {
  276. int Error = 0;
  277. glm::vec1 A0 = glm::max(glm::vec1(1), glm::vec1(1));
  278. glm::vec2 B0 = glm::max(glm::vec2(1), glm::vec2(1));
  279. glm::vec2 B1 = glm::max(glm::vec2(1), 1.0f);
  280. bool B2 = glm::all(glm::equal(B0, B1));
  281. Error += B2 ? 0 : 1;
  282. glm::vec3 C0 = glm::max(glm::vec3(1), glm::vec3(1));
  283. glm::vec3 C1 = glm::max(glm::vec3(1), 1.0f);
  284. bool C2 = glm::all(glm::equal(C0, C1));
  285. Error += C2 ? 0 : 1;
  286. glm::vec4 D0 = glm::max(glm::vec4(1), glm::vec4(1));
  287. glm::vec4 D1 = glm::max(glm::vec4(1), 1.0f);
  288. bool D2 = glm::all(glm::equal(D0, D1));
  289. Error += D2 ? 0 : 1;
  290. return Error;
  291. }
  292. }//namespace max_
  293. namespace clamp_
  294. {
  295. static int test()
  296. {
  297. int Error = 0;
  298. return Error;
  299. }
  300. }//namespace clamp_
  301. namespace mix_
  302. {
  303. template<typename T, typename B>
  304. struct entry
  305. {
  306. T x;
  307. T y;
  308. B a;
  309. T Result;
  310. };
  311. entry<float, bool> const TestBool[] =
  312. {
  313. {0.0f, 1.0f, false, 0.0f},
  314. {0.0f, 1.0f, true, 1.0f},
  315. {-1.0f, 1.0f, false, -1.0f},
  316. {-1.0f, 1.0f, true, 1.0f}
  317. };
  318. entry<float, float> const TestFloat[] =
  319. {
  320. {0.0f, 1.0f, 0.0f, 0.0f},
  321. {0.0f, 1.0f, 1.0f, 1.0f},
  322. {-1.0f, 1.0f, 0.0f, -1.0f},
  323. {-1.0f, 1.0f, 1.0f, 1.0f}
  324. };
  325. entry<glm::vec2, bool> const TestVec2Bool[] =
  326. {
  327. {glm::vec2(0.0f), glm::vec2(1.0f), false, glm::vec2(0.0f)},
  328. {glm::vec2(0.0f), glm::vec2(1.0f), true, glm::vec2(1.0f)},
  329. {glm::vec2(-1.0f), glm::vec2(1.0f), false, glm::vec2(-1.0f)},
  330. {glm::vec2(-1.0f), glm::vec2(1.0f), true, glm::vec2(1.0f)}
  331. };
  332. entry<glm::vec2, glm::bvec2> const TestBVec2[] =
  333. {
  334. {glm::vec2(0.0f), glm::vec2(1.0f), glm::bvec2(false), glm::vec2(0.0f)},
  335. {glm::vec2(0.0f), glm::vec2(1.0f), glm::bvec2(true), glm::vec2(1.0f)},
  336. {glm::vec2(-1.0f), glm::vec2(1.0f), glm::bvec2(false), glm::vec2(-1.0f)},
  337. {glm::vec2(-1.0f), glm::vec2(1.0f), glm::bvec2(true), glm::vec2(1.0f)},
  338. {glm::vec2(-1.0f), glm::vec2(1.0f), glm::bvec2(true, false), glm::vec2(1.0f, -1.0f)}
  339. };
  340. entry<glm::vec3, bool> const TestVec3Bool[] =
  341. {
  342. {glm::vec3(0.0f), glm::vec3(1.0f), false, glm::vec3(0.0f)},
  343. {glm::vec3(0.0f), glm::vec3(1.0f), true, glm::vec3(1.0f)},
  344. {glm::vec3(-1.0f), glm::vec3(1.0f), false, glm::vec3(-1.0f)},
  345. {glm::vec3(-1.0f), glm::vec3(1.0f), true, glm::vec3(1.0f)}
  346. };
  347. entry<glm::vec3, glm::bvec3> const TestBVec3[] =
  348. {
  349. {glm::vec3(0.0f), glm::vec3(1.0f), glm::bvec3(false), glm::vec3(0.0f)},
  350. {glm::vec3(0.0f), glm::vec3(1.0f), glm::bvec3(true), glm::vec3(1.0f)},
  351. {glm::vec3(-1.0f), glm::vec3(1.0f), glm::bvec3(false), glm::vec3(-1.0f)},
  352. {glm::vec3(-1.0f), glm::vec3(1.0f), glm::bvec3(true), glm::vec3(1.0f)},
  353. {glm::vec3(1.0f, 2.0f, 3.0f), glm::vec3(4.0f, 5.0f, 6.0f), glm::bvec3(true, false, true), glm::vec3(4.0f, 2.0f, 6.0f)}
  354. };
  355. entry<glm::vec4, bool> const TestVec4Bool[] =
  356. {
  357. {glm::vec4(0.0f), glm::vec4(1.0f), false, glm::vec4(0.0f)},
  358. {glm::vec4(0.0f), glm::vec4(1.0f), true, glm::vec4(1.0f)},
  359. {glm::vec4(-1.0f), glm::vec4(1.0f), false, glm::vec4(-1.0f)},
  360. {glm::vec4(-1.0f), glm::vec4(1.0f), true, glm::vec4(1.0f)}
  361. };
  362. entry<glm::vec4, glm::bvec4> const TestBVec4[] =
  363. {
  364. {glm::vec4(0.0f, 0.0f, 1.0f, 1.0f), glm::vec4(2.0f, 2.0f, 3.0f, 3.0f), glm::bvec4(false, true, false, true), glm::vec4(0.0f, 2.0f, 1.0f, 3.0f)},
  365. {glm::vec4(0.0f), glm::vec4(1.0f), glm::bvec4(true), glm::vec4(1.0f)},
  366. {glm::vec4(-1.0f), glm::vec4(1.0f), glm::bvec4(false), glm::vec4(-1.0f)},
  367. {glm::vec4(-1.0f), glm::vec4(1.0f), glm::bvec4(true), glm::vec4(1.0f)},
  368. {glm::vec4(1.0f, 2.0f, 3.0f, 4.0f), glm::vec4(5.0f, 6.0f, 7.0f, 8.0f), glm::bvec4(true, false, true, false), glm::vec4(5.0f, 2.0f, 7.0f, 4.0f)}
  369. };
  370. static int test()
  371. {
  372. int Error = 0;
  373. // Float with bool
  374. {
  375. for(std::size_t i = 0; i < sizeof(TestBool) / sizeof(entry<float, bool>); ++i)
  376. {
  377. float Result = glm::mix(TestBool[i].x, TestBool[i].y, TestBool[i].a);
  378. Error += glm::epsilonEqual(Result, TestBool[i].Result, glm::epsilon<float>()) ? 0 : 1;
  379. }
  380. }
  381. // Float with float
  382. {
  383. for(std::size_t i = 0; i < sizeof(TestFloat) / sizeof(entry<float, float>); ++i)
  384. {
  385. float Result = glm::mix(TestFloat[i].x, TestFloat[i].y, TestFloat[i].a);
  386. Error += glm::epsilonEqual(Result, TestFloat[i].Result, glm::epsilon<float>()) ? 0 : 1;
  387. }
  388. }
  389. // vec2 with bool
  390. {
  391. for(std::size_t i = 0; i < sizeof(TestVec2Bool) / sizeof(entry<glm::vec2, bool>); ++i)
  392. {
  393. glm::vec2 Result = glm::mix(TestVec2Bool[i].x, TestVec2Bool[i].y, TestVec2Bool[i].a);
  394. Error += glm::epsilonEqual(Result.x, TestVec2Bool[i].Result.x, glm::epsilon<float>()) ? 0 : 1;
  395. Error += glm::epsilonEqual(Result.y, TestVec2Bool[i].Result.y, glm::epsilon<float>()) ? 0 : 1;
  396. }
  397. }
  398. // vec2 with bvec2
  399. {
  400. for(std::size_t i = 0; i < sizeof(TestBVec2) / sizeof(entry<glm::vec2, glm::bvec2>); ++i)
  401. {
  402. glm::vec2 Result = glm::mix(TestBVec2[i].x, TestBVec2[i].y, TestBVec2[i].a);
  403. Error += glm::epsilonEqual(Result.x, TestBVec2[i].Result.x, glm::epsilon<float>()) ? 0 : 1;
  404. Error += glm::epsilonEqual(Result.y, TestBVec2[i].Result.y, glm::epsilon<float>()) ? 0 : 1;
  405. }
  406. }
  407. // vec3 with bool
  408. {
  409. for(std::size_t i = 0; i < sizeof(TestVec3Bool) / sizeof(entry<glm::vec3, bool>); ++i)
  410. {
  411. glm::vec3 Result = glm::mix(TestVec3Bool[i].x, TestVec3Bool[i].y, TestVec3Bool[i].a);
  412. Error += glm::epsilonEqual(Result.x, TestVec3Bool[i].Result.x, glm::epsilon<float>()) ? 0 : 1;
  413. Error += glm::epsilonEqual(Result.y, TestVec3Bool[i].Result.y, glm::epsilon<float>()) ? 0 : 1;
  414. Error += glm::epsilonEqual(Result.z, TestVec3Bool[i].Result.z, glm::epsilon<float>()) ? 0 : 1;
  415. }
  416. }
  417. // vec3 with bvec3
  418. {
  419. for(std::size_t i = 0; i < sizeof(TestBVec3) / sizeof(entry<glm::vec3, glm::bvec3>); ++i)
  420. {
  421. glm::vec3 Result = glm::mix(TestBVec3[i].x, TestBVec3[i].y, TestBVec3[i].a);
  422. Error += glm::epsilonEqual(Result.x, TestBVec3[i].Result.x, glm::epsilon<float>()) ? 0 : 1;
  423. Error += glm::epsilonEqual(Result.y, TestBVec3[i].Result.y, glm::epsilon<float>()) ? 0 : 1;
  424. Error += glm::epsilonEqual(Result.z, TestBVec3[i].Result.z, glm::epsilon<float>()) ? 0 : 1;
  425. }
  426. }
  427. // vec4 with bool
  428. {
  429. for(std::size_t i = 0; i < sizeof(TestVec4Bool) / sizeof(entry<glm::vec4, bool>); ++i)
  430. {
  431. glm::vec4 Result = glm::mix(TestVec4Bool[i].x, TestVec4Bool[i].y, TestVec4Bool[i].a);
  432. Error += glm::epsilonEqual(Result.x, TestVec4Bool[i].Result.x, glm::epsilon<float>()) ? 0 : 1;
  433. Error += glm::epsilonEqual(Result.y, TestVec4Bool[i].Result.y, glm::epsilon<float>()) ? 0 : 1;
  434. Error += glm::epsilonEqual(Result.z, TestVec4Bool[i].Result.z, glm::epsilon<float>()) ? 0 : 1;
  435. Error += glm::epsilonEqual(Result.w, TestVec4Bool[i].Result.w, glm::epsilon<float>()) ? 0 : 1;
  436. }
  437. }
  438. // vec4 with bvec4
  439. {
  440. for(std::size_t i = 0; i < sizeof(TestBVec4) / sizeof(entry<glm::vec4, glm::bvec4>); ++i)
  441. {
  442. glm::vec4 Result = glm::mix(TestBVec4[i].x, TestBVec4[i].y, TestBVec4[i].a);
  443. Error += glm::epsilonEqual(Result.x, TestBVec4[i].Result.x, glm::epsilon<float>()) ? 0 : 1;
  444. Error += glm::epsilonEqual(Result.y, TestBVec4[i].Result.y, glm::epsilon<float>()) ? 0 : 1;
  445. Error += glm::epsilonEqual(Result.z, TestBVec4[i].Result.z, glm::epsilon<float>()) ? 0 : 1;
  446. Error += glm::epsilonEqual(Result.w, TestBVec4[i].Result.w, glm::epsilon<float>()) ? 0 : 1;
  447. }
  448. }
  449. return Error;
  450. }
  451. }//namespace mix_
  452. namespace step_
  453. {
  454. template<typename EDGE, typename VEC>
  455. struct entry
  456. {
  457. EDGE edge;
  458. VEC x;
  459. VEC result;
  460. };
  461. entry<float, glm::vec4> TestVec4Scalar [] =
  462. {
  463. { 1.0f, glm::vec4(1.0f, 2.0f, 3.0f, 4.0f), glm::vec4(1.0f) },
  464. { 0.0f, glm::vec4(1.0f, 2.0f, 3.0f, 4.0f), glm::vec4(1.0f) },
  465. { 0.0f, glm::vec4(-1.0f, -2.0f, -3.0f, -4.0f), glm::vec4(0.0f) }
  466. };
  467. entry<glm::vec4, glm::vec4> TestVec4Vector [] =
  468. {
  469. { glm::vec4(-1.0f, -2.0f, -3.0f, -4.0f), glm::vec4(-2.0f, -3.0f, -4.0f, -5.0f), glm::vec4(0.0f) },
  470. { glm::vec4( 0.0f, 1.0f, 2.0f, 3.0f), glm::vec4( 1.0f, 2.0f, 3.0f, 4.0f), glm::vec4(1.0f) },
  471. { glm::vec4( 2.0f, 3.0f, 4.0f, 5.0f), glm::vec4( 1.0f, 2.0f, 3.0f, 4.0f), glm::vec4(0.0f) },
  472. { glm::vec4( 0.0f, 1.0f, 2.0f, 3.0f), glm::vec4(-1.0f,-2.0f,-3.0f,-4.0f), glm::vec4(0.0f) }
  473. };
  474. static int test()
  475. {
  476. int Error = 0;
  477. // scalar
  478. {
  479. float const Edge = 2.0f;
  480. float const A = glm::step(Edge, 1.0f);
  481. Error += glm::epsilonEqual(A, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  482. float const B = glm::step(Edge, 3.0f);
  483. Error += glm::epsilonEqual(B, 1.0f, glm::epsilon<float>()) ? 0 : 1;
  484. float const C = glm::step(Edge, 2.0f);
  485. Error += glm::epsilonEqual(C, 1.0f, glm::epsilon<float>()) ? 0 : 1;
  486. }
  487. // vec4 and float
  488. {
  489. for (std::size_t i = 0; i < sizeof(TestVec4Scalar) / sizeof(entry<float, glm::vec4>); ++i)
  490. {
  491. glm::vec4 Result = glm::step(TestVec4Scalar[i].edge, TestVec4Scalar[i].x);
  492. Error += glm::all(glm::epsilonEqual(Result, TestVec4Scalar[i].result, glm::epsilon<float>())) ? 0 : 1;
  493. }
  494. }
  495. // vec4 and vec4
  496. {
  497. for (std::size_t i = 0; i < sizeof(TestVec4Vector) / sizeof(entry<glm::vec4, glm::vec4>); ++i)
  498. {
  499. glm::vec4 Result = glm::step(TestVec4Vector[i].edge, TestVec4Vector[i].x);
  500. Error += glm::all(glm::epsilonEqual(Result, TestVec4Vector[i].result, glm::epsilon<float>())) ? 0 : 1;
  501. }
  502. }
  503. return Error;
  504. }
  505. }//namespace step_
  506. namespace round_
  507. {
  508. static int test()
  509. {
  510. int Error = 0;
  511. {
  512. float A = glm::round(0.0f);
  513. Error += glm::epsilonEqual(A, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  514. float B = glm::round(0.5f);
  515. Error += glm::epsilonEqual(B, 1.0f, glm::epsilon<float>()) ? 0 : 1;
  516. float C = glm::round(1.0f);
  517. Error += glm::epsilonEqual(C, 1.0f, glm::epsilon<float>()) ? 0 : 1;
  518. float D = glm::round(0.1f);
  519. Error += glm::epsilonEqual(D, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  520. float E = glm::round(0.9f);
  521. Error += glm::epsilonEqual(E, 1.0f, glm::epsilon<float>()) ? 0 : 1;
  522. float F = glm::round(1.5f);
  523. Error += glm::epsilonEqual(F, 2.0f, glm::epsilon<float>()) ? 0 : 1;
  524. float G = glm::round(1.9f);
  525. Error += glm::epsilonEqual(G, 2.0f, glm::epsilon<float>()) ? 0 : 1;
  526. }
  527. {
  528. float A = glm::round(-0.0f);
  529. Error += glm::epsilonEqual(A, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  530. float B = glm::round(-0.5f);
  531. Error += glm::epsilonEqual(B, -1.0f, glm::epsilon<float>()) ? 0 : 1;
  532. float C = glm::round(-1.0f);
  533. Error += glm::epsilonEqual(C, -1.0f, glm::epsilon<float>()) ? 0 : 1;
  534. float D = glm::round(-0.1f);
  535. Error += glm::epsilonEqual(D, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  536. float E = glm::round(-0.9f);
  537. Error += glm::epsilonEqual(E, -1.0f, glm::epsilon<float>()) ? 0 : 1;
  538. float F = glm::round(-1.5f);
  539. Error += glm::epsilonEqual(F, -2.0f, glm::epsilon<float>()) ? 0 : 1;
  540. float G = glm::round(-1.9f);
  541. Error += glm::epsilonEqual(G, -2.0f, glm::epsilon<float>()) ? 0 : 1;
  542. }
  543. return Error;
  544. }
  545. }//namespace round_
  546. namespace roundEven
  547. {
  548. static int test()
  549. {
  550. int Error = 0;
  551. {
  552. float A1 = glm::roundEven(-1.5f);
  553. Error += glm::epsilonEqual(A1, -2.0f, 0.0001f) ? 0 : 1;
  554. float A2 = glm::roundEven(1.5f);
  555. Error += glm::epsilonEqual(A2, 2.0f, 0.0001f) ? 0 : 1;
  556. float A5 = glm::roundEven(-2.5f);
  557. Error += glm::epsilonEqual(A5, -2.0f, 0.0001f) ? 0 : 1;
  558. float A6 = glm::roundEven(2.5f);
  559. Error += glm::epsilonEqual(A6, 2.0f, 0.0001f) ? 0 : 1;
  560. float A3 = glm::roundEven(-3.5f);
  561. Error += glm::epsilonEqual(A3, -4.0f, 0.0001f) ? 0 : 1;
  562. float A4 = glm::roundEven(3.5f);
  563. Error += glm::epsilonEqual(A4, 4.0f, 0.0001f) ? 0 : 1;
  564. float C7 = glm::roundEven(-4.5f);
  565. Error += glm::epsilonEqual(C7, -4.0f, 0.0001f) ? 0 : 1;
  566. float C8 = glm::roundEven(4.5f);
  567. Error += glm::epsilonEqual(C8, 4.0f, 0.0001f) ? 0 : 1;
  568. float C1 = glm::roundEven(-5.5f);
  569. Error += glm::epsilonEqual(C1, -6.0f, 0.0001f) ? 0 : 1;
  570. float C2 = glm::roundEven(5.5f);
  571. Error += glm::epsilonEqual(C2, 6.0f, 0.0001f) ? 0 : 1;
  572. float C3 = glm::roundEven(-6.5f);
  573. Error += glm::epsilonEqual(C3, -6.0f, 0.0001f) ? 0 : 1;
  574. float C4 = glm::roundEven(6.5f);
  575. Error += glm::epsilonEqual(C4, 6.0f, 0.0001f) ? 0 : 1;
  576. float C5 = glm::roundEven(-7.5f);
  577. Error += glm::epsilonEqual(C5, -8.0f, 0.0001f) ? 0 : 1;
  578. float C6 = glm::roundEven(7.5f);
  579. Error += glm::epsilonEqual(C6, 8.0f, 0.0001f) ? 0 : 1;
  580. Error += 0;
  581. }
  582. {
  583. float A7 = glm::roundEven(-2.4f);
  584. Error += glm::epsilonEqual(A7, -2.0f, 0.0001f) ? 0 : 1;
  585. float A8 = glm::roundEven(2.4f);
  586. Error += glm::epsilonEqual(A8, 2.0f, 0.0001f) ? 0 : 1;
  587. float B1 = glm::roundEven(-2.6f);
  588. Error += glm::epsilonEqual(B1, -3.0f, 0.0001f) ? 0 : 1;
  589. float B2 = glm::roundEven(2.6f);
  590. Error += glm::epsilonEqual(B2, 3.0f, 0.0001f) ? 0 : 1;
  591. float B3 = glm::roundEven(-2.0f);
  592. Error += glm::epsilonEqual(B3, -2.0f, 0.0001f) ? 0 : 1;
  593. float B4 = glm::roundEven(2.0f);
  594. Error += glm::epsilonEqual(B4, 2.0f, 0.0001f) ? 0 : 1;
  595. Error += 0;
  596. }
  597. {
  598. float A = glm::roundEven(0.0f);
  599. Error += glm::epsilonEqual(A, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  600. float B = glm::roundEven(0.5f);
  601. Error += glm::epsilonEqual(B, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  602. float C = glm::roundEven(1.0f);
  603. Error += glm::epsilonEqual(C, 1.0f, glm::epsilon<float>()) ? 0 : 1;
  604. float D = glm::roundEven(0.1f);
  605. Error += glm::epsilonEqual(D, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  606. float E = glm::roundEven(0.9f);
  607. Error += glm::epsilonEqual(E, 1.0f, glm::epsilon<float>()) ? 0 : 1;
  608. float F = glm::roundEven(1.5f);
  609. Error += glm::epsilonEqual(F, 2.0f, glm::epsilon<float>()) ? 0 : 1;
  610. float G = glm::roundEven(1.9f);
  611. Error += glm::epsilonEqual(G, 2.0f, glm::epsilon<float>()) ? 0 : 1;
  612. }
  613. {
  614. float A = glm::roundEven(-0.0f);
  615. Error += glm::epsilonEqual(A, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  616. float B = glm::roundEven(-0.5f);
  617. Error += glm::epsilonEqual(B, -0.0f, glm::epsilon<float>()) ? 0 : 1;
  618. float C = glm::roundEven(-1.0f);
  619. Error += glm::epsilonEqual(C, -1.0f, glm::epsilon<float>()) ? 0 : 1;
  620. float D = glm::roundEven(-0.1f);
  621. Error += glm::epsilonEqual(D, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  622. float E = glm::roundEven(-0.9f);
  623. Error += glm::epsilonEqual(E, -1.0f, glm::epsilon<float>()) ? 0 : 1;
  624. float F = glm::roundEven(-1.5f);
  625. Error += glm::epsilonEqual(F, -2.0f, glm::epsilon<float>()) ? 0 : 1;
  626. float G = glm::roundEven(-1.9f);
  627. Error += glm::epsilonEqual(G, -2.0f, glm::epsilon<float>()) ? 0 : 1;
  628. }
  629. {
  630. float A = glm::roundEven(1.5f);
  631. Error += glm::epsilonEqual(A, 2.0f, glm::epsilon<float>()) ? 0 : 1;
  632. float B = glm::roundEven(2.5f);
  633. Error += glm::epsilonEqual(B, 2.0f, glm::epsilon<float>()) ? 0 : 1;
  634. float C = glm::roundEven(3.5f);
  635. Error += glm::epsilonEqual(C, 4.0f, glm::epsilon<float>()) ? 0 : 1;
  636. float D = glm::roundEven(4.5f);
  637. Error += glm::epsilonEqual(D, 4.0f, glm::epsilon<float>()) ? 0 : 1;
  638. float E = glm::roundEven(5.5f);
  639. Error += glm::epsilonEqual(E, 6.0f, glm::epsilon<float>()) ? 0 : 1;
  640. float F = glm::roundEven(6.5f);
  641. Error += glm::epsilonEqual(F, 6.0f, glm::epsilon<float>()) ? 0 : 1;
  642. float G = glm::roundEven(7.5f);
  643. Error += glm::epsilonEqual(G, 8.0f, glm::epsilon<float>()) ? 0 : 1;
  644. }
  645. {
  646. float A = glm::roundEven(-1.5f);
  647. Error += glm::epsilonEqual(A, -2.0f, glm::epsilon<float>()) ? 0 : 1;
  648. float B = glm::roundEven(-2.5f);
  649. Error += glm::epsilonEqual(B, -2.0f, glm::epsilon<float>()) ? 0 : 1;
  650. float C = glm::roundEven(-3.5f);
  651. Error += glm::epsilonEqual(C, -4.0f, glm::epsilon<float>()) ? 0 : 1;
  652. float D = glm::roundEven(-4.5f);
  653. Error += glm::epsilonEqual(D, -4.0f, glm::epsilon<float>()) ? 0 : 1;
  654. float E = glm::roundEven(-5.5f);
  655. Error += glm::epsilonEqual(E, -6.0f, glm::epsilon<float>()) ? 0 : 1;
  656. float F = glm::roundEven(-6.5f);
  657. Error += glm::epsilonEqual(F, -6.0f, glm::epsilon<float>()) ? 0 : 1;
  658. float G = glm::roundEven(-7.5f);
  659. Error += glm::epsilonEqual(G, -8.0f, glm::epsilon<float>()) ? 0 : 1;
  660. }
  661. return Error;
  662. }
  663. }//namespace roundEven
  664. namespace isnan_
  665. {
  666. static int test()
  667. {
  668. int Error = 0;
  669. float Zero_f = 0.0;
  670. double Zero_d = 0.0;
  671. {
  672. Error += true == glm::isnan(0.0/Zero_d) ? 0 : 1;
  673. Error += true == glm::any(glm::isnan(glm::dvec2(0.0 / Zero_d))) ? 0 : 1;
  674. Error += true == glm::any(glm::isnan(glm::dvec3(0.0 / Zero_d))) ? 0 : 1;
  675. Error += true == glm::any(glm::isnan(glm::dvec4(0.0 / Zero_d))) ? 0 : 1;
  676. }
  677. {
  678. Error += true == glm::isnan(0.0f/Zero_f) ? 0 : 1;
  679. Error += true == glm::any(glm::isnan(glm::vec2(0.0f/Zero_f))) ? 0 : 1;
  680. Error += true == glm::any(glm::isnan(glm::vec3(0.0f/Zero_f))) ? 0 : 1;
  681. Error += true == glm::any(glm::isnan(glm::vec4(0.0f/Zero_f))) ? 0 : 1;
  682. }
  683. return Error;
  684. }
  685. }//namespace isnan_
  686. namespace isinf_
  687. {
  688. static int test()
  689. {
  690. int Error = 0;
  691. float Zero_f = 0.0;
  692. double Zero_d = 0.0;
  693. {
  694. Error += true == glm::isinf( 1.0/Zero_d) ? 0 : 1;
  695. Error += true == glm::isinf(-1.0/Zero_d) ? 0 : 1;
  696. Error += true == glm::any(glm::isinf(glm::dvec2( 1.0/Zero_d))) ? 0 : 1;
  697. Error += true == glm::any(glm::isinf(glm::dvec2(-1.0/Zero_d))) ? 0 : 1;
  698. Error += true == glm::any(glm::isinf(glm::dvec3( 1.0/Zero_d))) ? 0 : 1;
  699. Error += true == glm::any(glm::isinf(glm::dvec3(-1.0/Zero_d))) ? 0 : 1;
  700. Error += true == glm::any(glm::isinf(glm::dvec4( 1.0/Zero_d))) ? 0 : 1;
  701. Error += true == glm::any(glm::isinf(glm::dvec4(-1.0/Zero_d))) ? 0 : 1;
  702. }
  703. {
  704. Error += true == glm::isinf( 1.0f/Zero_f) ? 0 : 1;
  705. Error += true == glm::isinf(-1.0f/Zero_f) ? 0 : 1;
  706. Error += true == glm::any(glm::isinf(glm::vec2( 1.0f/Zero_f))) ? 0 : 1;
  707. Error += true == glm::any(glm::isinf(glm::vec2(-1.0f/Zero_f))) ? 0 : 1;
  708. Error += true == glm::any(glm::isinf(glm::vec3( 1.0f/Zero_f))) ? 0 : 1;
  709. Error += true == glm::any(glm::isinf(glm::vec3(-1.0f/Zero_f))) ? 0 : 1;
  710. Error += true == glm::any(glm::isinf(glm::vec4( 1.0f/Zero_f))) ? 0 : 1;
  711. Error += true == glm::any(glm::isinf(glm::vec4(-1.0f/Zero_f))) ? 0 : 1;
  712. }
  713. return Error;
  714. }
  715. }//namespace isinf_
  716. namespace sign
  717. {
  718. template<typename genFIType>
  719. GLM_FUNC_QUALIFIER genFIType sign_if(genFIType x)
  720. {
  721. GLM_STATIC_ASSERT(
  722. std::numeric_limits<genFIType>::is_iec559 ||
  723. (std::numeric_limits<genFIType>::is_signed && std::numeric_limits<genFIType>::is_integer), "'sign' only accept signed inputs");
  724. genFIType result;
  725. if(x > genFIType(0))
  726. result = genFIType(1);
  727. else if(x < genFIType(0))
  728. result = genFIType(-1);
  729. else
  730. result = genFIType(0);
  731. return result;
  732. }
  733. template<typename genFIType>
  734. GLM_FUNC_QUALIFIER genFIType sign_alu1(genFIType x)
  735. {
  736. GLM_STATIC_ASSERT(
  737. std::numeric_limits<genFIType>::is_signed && std::numeric_limits<genFIType>::is_integer,
  738. "'sign' only accept integer inputs");
  739. return (x >> 31) | (static_cast<unsigned>(-x) >> 31);
  740. }
  741. GLM_FUNC_QUALIFIER int sign_alu2(int x)
  742. {
  743. GLM_STATIC_ASSERT(std::numeric_limits<int>::is_signed && std::numeric_limits<int>::is_integer, "'sign' only accept integer inputs");
  744. # if GLM_COMPILER & GLM_COMPILER_VC
  745. # pragma warning(push)
  746. # pragma warning(disable : 4146) //cast truncates constant value
  747. # endif
  748. return -(static_cast<unsigned>(x) >> 31) | (-static_cast<unsigned>(x) >> 31);
  749. # if GLM_COMPILER & GLM_COMPILER_VC
  750. # pragma warning(pop)
  751. # endif
  752. }
  753. template<typename genFIType>
  754. GLM_FUNC_QUALIFIER genFIType sign_sub(genFIType x)
  755. {
  756. GLM_STATIC_ASSERT(
  757. std::numeric_limits<genFIType>::is_signed && std::numeric_limits<genFIType>::is_integer,
  758. "'sign' only accept integer inputs");
  759. return (static_cast<unsigned>(-x) >> 31) - (static_cast<unsigned>(x) >> 31);
  760. }
  761. template<typename genFIType>
  762. GLM_FUNC_QUALIFIER genFIType sign_cmp(genFIType x)
  763. {
  764. GLM_STATIC_ASSERT(
  765. std::numeric_limits<genFIType>::is_signed && std::numeric_limits<genFIType>::is_integer,
  766. "'sign' only accept integer inputs");
  767. return (x > 0) - (x < 0);
  768. }
  769. template<typename genType>
  770. struct type
  771. {
  772. genType Value;
  773. genType Return;
  774. };
  775. int test_int32()
  776. {
  777. type<glm::int32> const Data[] =
  778. {
  779. { std::numeric_limits<glm::int32>::max(), 1},
  780. { std::numeric_limits<glm::int32>::min(), -1},
  781. { 0, 0},
  782. { 1, 1},
  783. { 2, 1},
  784. { 3, 1},
  785. {-1,-1},
  786. {-2,-1},
  787. {-3,-1}
  788. };
  789. int Error = 0;
  790. for(std::size_t i = 0; i < sizeof(Data) / sizeof(type<glm::int32>); ++i)
  791. {
  792. glm::int32 Result = glm::sign(Data[i].Value);
  793. Error += Data[i].Return == Result ? 0 : 1;
  794. }
  795. for(std::size_t i = 0; i < sizeof(Data) / sizeof(type<glm::int32>); ++i)
  796. {
  797. glm::int32 Result = sign_cmp(Data[i].Value);
  798. Error += Data[i].Return == Result ? 0 : 1;
  799. }
  800. for(std::size_t i = 0; i < sizeof(Data) / sizeof(type<glm::int32>); ++i)
  801. {
  802. glm::int32 Result = sign_if(Data[i].Value);
  803. Error += Data[i].Return == Result ? 0 : 1;
  804. }
  805. for(std::size_t i = 0; i < sizeof(Data) / sizeof(type<glm::int32>); ++i)
  806. {
  807. glm::int32 Result = sign_alu1(Data[i].Value);
  808. Error += Data[i].Return == Result ? 0 : 1;
  809. }
  810. for(std::size_t i = 0; i < sizeof(Data) / sizeof(type<glm::int32>); ++i)
  811. {
  812. glm::int32 Result = sign_alu2(Data[i].Value);
  813. Error += Data[i].Return == Result ? 0 : 1;
  814. }
  815. return Error;
  816. }
  817. int test_i32vec4()
  818. {
  819. type<glm::i32vec4> const Data[] =
  820. {
  821. {glm::i32vec4( 1), glm::i32vec4( 1)},
  822. {glm::i32vec4( 0), glm::i32vec4( 0)},
  823. {glm::i32vec4( 2), glm::i32vec4( 1)},
  824. {glm::i32vec4( 3), glm::i32vec4( 1)},
  825. {glm::i32vec4(-1), glm::i32vec4(-1)},
  826. {glm::i32vec4(-2), glm::i32vec4(-1)},
  827. {glm::i32vec4(-3), glm::i32vec4(-1)}
  828. };
  829. int Error = 0;
  830. for(std::size_t i = 0; i < sizeof(Data) / sizeof(type<glm::i32vec4>); ++i)
  831. {
  832. glm::i32vec4 Result = glm::sign(Data[i].Value);
  833. Error += glm::all(glm::equal(Data[i].Return, Result)) ? 0 : 1;
  834. }
  835. return Error;
  836. }
  837. int test_f32vec4()
  838. {
  839. type<glm::vec4> const Data[] =
  840. {
  841. {glm::vec4( 1), glm::vec4( 1)},
  842. {glm::vec4( 0), glm::vec4( 0)},
  843. {glm::vec4( 2), glm::vec4( 1)},
  844. {glm::vec4( 3), glm::vec4( 1)},
  845. {glm::vec4(-1), glm::vec4(-1)},
  846. {glm::vec4(-2), glm::vec4(-1)},
  847. {glm::vec4(-3), glm::vec4(-1)}
  848. };
  849. int Error = 0;
  850. for(std::size_t i = 0; i < sizeof(Data) / sizeof(type<glm::vec4>); ++i)
  851. {
  852. glm::vec4 Result = glm::sign(Data[i].Value);
  853. Error += glm::all(glm::equal(Data[i].Return, Result)) ? 0 : 1;
  854. }
  855. return Error;
  856. }
  857. static int test()
  858. {
  859. int Error = 0;
  860. Error += test_int32();
  861. Error += test_i32vec4();
  862. Error += test_f32vec4();
  863. return Error;
  864. }
  865. int perf_rand(std::size_t Samples)
  866. {
  867. int Error = 0;
  868. std::size_t const Count = Samples;
  869. std::vector<glm::int32> Input, Output;
  870. Input.resize(Count);
  871. Output.resize(Count);
  872. for(std::size_t i = 0; i < Count; ++i)
  873. Input[i] = static_cast<glm::int32>(glm::linearRand(-65536.f, 65536.f));
  874. std::clock_t Timestamp0 = std::clock();
  875. for(std::size_t i = 0; i < Count; ++i)
  876. Output[i] = sign_cmp(Input[i]);
  877. std::clock_t Timestamp1 = std::clock();
  878. for(std::size_t i = 0; i < Count; ++i)
  879. Output[i] = sign_if(Input[i]);
  880. std::clock_t Timestamp2 = std::clock();
  881. for(std::size_t i = 0; i < Count; ++i)
  882. Output[i] = sign_alu1(Input[i]);
  883. std::clock_t Timestamp3 = std::clock();
  884. for(std::size_t i = 0; i < Count; ++i)
  885. Output[i] = sign_alu2(Input[i]);
  886. std::clock_t Timestamp4 = std::clock();
  887. for(std::size_t i = 0; i < Count; ++i)
  888. Output[i] = sign_sub(Input[i]);
  889. std::clock_t Timestamp5 = std::clock();
  890. for(std::size_t i = 0; i < Count; ++i)
  891. Output[i] = glm::sign(Input[i]);
  892. std::clock_t Timestamp6 = std::clock();
  893. std::printf("sign_cmp(rand) Time %d clocks\n", static_cast<int>(Timestamp1 - Timestamp0));
  894. std::printf("sign_if(rand) Time %d clocks\n", static_cast<int>(Timestamp2 - Timestamp1));
  895. std::printf("sign_alu1(rand) Time %d clocks\n", static_cast<int>(Timestamp3 - Timestamp2));
  896. std::printf("sign_alu2(rand) Time %d clocks\n", static_cast<int>(Timestamp4 - Timestamp3));
  897. std::printf("sign_sub(rand) Time %d clocks\n", static_cast<int>(Timestamp5 - Timestamp4));
  898. std::printf("glm::sign(rand) Time %d clocks\n", static_cast<int>(Timestamp6 - Timestamp5));
  899. return Error;
  900. }
  901. int perf_linear(std::size_t Samples)
  902. {
  903. int Error = 0;
  904. std::size_t const Count = Samples;
  905. std::vector<glm::int32> Input, Output;
  906. Input.resize(Count);
  907. Output.resize(Count);
  908. for(std::size_t i = 0; i < Count; ++i)
  909. Input[i] = static_cast<glm::int32>(i);
  910. std::clock_t Timestamp0 = std::clock();
  911. for(std::size_t i = 0; i < Count; ++i)
  912. Output[i] = sign_cmp(Input[i]);
  913. std::clock_t Timestamp1 = std::clock();
  914. for(std::size_t i = 0; i < Count; ++i)
  915. Output[i] = sign_if(Input[i]);
  916. std::clock_t Timestamp2 = std::clock();
  917. for(std::size_t i = 0; i < Count; ++i)
  918. Output[i] = sign_alu1(Input[i]);
  919. std::clock_t Timestamp3 = std::clock();
  920. for(std::size_t i = 0; i < Count; ++i)
  921. Output[i] = sign_alu2(Input[i]);
  922. std::clock_t Timestamp4 = std::clock();
  923. for(std::size_t i = 0; i < Count; ++i)
  924. Output[i] = sign_sub(Input[i]);
  925. std::clock_t Timestamp5 = std::clock();
  926. std::printf("sign_cmp(linear) Time %d clocks\n", static_cast<int>(Timestamp1 - Timestamp0));
  927. std::printf("sign_if(linear) Time %d clocks\n", static_cast<int>(Timestamp2 - Timestamp1));
  928. std::printf("sign_alu1(linear) Time %d clocks\n", static_cast<int>(Timestamp3 - Timestamp2));
  929. std::printf("sign_alu2(linear) Time %d clocks\n", static_cast<int>(Timestamp4 - Timestamp3));
  930. std::printf("sign_sub(linear) Time %d clocks\n", static_cast<int>(Timestamp5 - Timestamp4));
  931. return Error;
  932. }
  933. int perf_linear_cal(std::size_t Samples)
  934. {
  935. int Error = 0;
  936. glm::int32 const Count = static_cast<glm::int32>(Samples);
  937. std::clock_t Timestamp0 = std::clock();
  938. glm::int32 Sum = 0;
  939. for(glm::int32 i = 1; i < Count; ++i)
  940. Sum += sign_cmp(i);
  941. std::clock_t Timestamp1 = std::clock();
  942. for(glm::int32 i = 1; i < Count; ++i)
  943. Sum += sign_if(i);
  944. std::clock_t Timestamp2 = std::clock();
  945. for(glm::int32 i = 1; i < Count; ++i)
  946. Sum += sign_alu1(i);
  947. std::clock_t Timestamp3 = std::clock();
  948. for(glm::int32 i = 1; i < Count; ++i)
  949. Sum += sign_alu2(i);
  950. std::clock_t Timestamp4 = std::clock();
  951. for(glm::int32 i = 1; i < Count; ++i)
  952. Sum += sign_sub(i);
  953. std::clock_t Timestamp5 = std::clock();
  954. std::printf("Sum %d\n", static_cast<int>(Sum));
  955. std::printf("sign_cmp(linear_cal) Time %d clocks\n", static_cast<int>(Timestamp1 - Timestamp0));
  956. std::printf("sign_if(linear_cal) Time %d clocks\n", static_cast<int>(Timestamp2 - Timestamp1));
  957. std::printf("sign_alu1(linear_cal) Time %d clocks\n", static_cast<int>(Timestamp3 - Timestamp2));
  958. std::printf("sign_alu2(linear_cal) Time %d clocks\n", static_cast<int>(Timestamp4 - Timestamp3));
  959. std::printf("sign_sub(linear_cal) Time %d clocks\n", static_cast<int>(Timestamp5 - Timestamp4));
  960. return Error;
  961. }
  962. static int perf(std::size_t Samples)
  963. {
  964. int Error(0);
  965. Error += perf_linear_cal(Samples);
  966. Error += perf_linear(Samples);
  967. Error += perf_rand(Samples);
  968. return Error;
  969. }
  970. }//namespace sign
  971. namespace frexp_
  972. {
  973. static int test()
  974. {
  975. int Error(0);
  976. {
  977. glm::vec1 x(1024);
  978. glm::ivec1 exp;
  979. glm::vec1 A = glm::frexp(x, exp);
  980. Error += glm::all(glm::epsilonEqual(A, glm::vec1(0.5), 0.00001f)) ? 0 : 1;
  981. Error += glm::all(glm::equal(exp, glm::ivec1(11))) ? 0 : 1;
  982. }
  983. {
  984. glm::vec2 x(1024, 0.24);
  985. glm::ivec2 exp;
  986. glm::vec2 A = glm::frexp(x, exp);
  987. Error += glm::all(glm::epsilonEqual(A, glm::vec2(0.5, 0.96), 0.00001f)) ? 0 : 1;
  988. Error += glm::all(glm::equal(exp, glm::ivec2(11, -2))) ? 0 : 1;
  989. }
  990. {
  991. glm::vec3 x(1024, 0.24, 0);
  992. glm::ivec3 exp;
  993. glm::vec3 A = glm::frexp(x, exp);
  994. Error += glm::all(glm::epsilonEqual(A, glm::vec3(0.5, 0.96, 0.0), 0.00001f)) ? 0 : 1;
  995. Error += glm::all(glm::equal(exp, glm::ivec3(11, -2, 0))) ? 0 : 1;
  996. }
  997. {
  998. glm::vec4 x(1024, 0.24, 0, -1.33);
  999. glm::ivec4 exp;
  1000. glm::vec4 A = glm::frexp(x, exp);
  1001. Error += glm::all(glm::epsilonEqual(A, glm::vec4(0.5, 0.96, 0.0, -0.665), 0.00001f)) ? 0 : 1;
  1002. Error += glm::all(glm::equal(exp, glm::ivec4(11, -2, 0, 1))) ? 0 : 1;
  1003. }
  1004. return Error;
  1005. }
  1006. }//namespace frexp_
  1007. namespace ldexp_
  1008. {
  1009. static int test()
  1010. {
  1011. int Error(0);
  1012. {
  1013. glm::vec1 A = glm::vec1(0.5);
  1014. glm::ivec1 exp = glm::ivec1(11);
  1015. glm::vec1 x = glm::ldexp(A, exp);
  1016. Error += glm::all(glm::epsilonEqual(x, glm::vec1(1024),0.00001f)) ? 0 : 1;
  1017. }
  1018. {
  1019. glm::vec2 A = glm::vec2(0.5, 0.96);
  1020. glm::ivec2 exp = glm::ivec2(11, -2);
  1021. glm::vec2 x = glm::ldexp(A, exp);
  1022. Error += glm::all(glm::epsilonEqual(x, glm::vec2(1024, .24),0.00001f)) ? 0 : 1;
  1023. }
  1024. {
  1025. glm::vec3 A = glm::vec3(0.5, 0.96, 0.0);
  1026. glm::ivec3 exp = glm::ivec3(11, -2, 0);
  1027. glm::vec3 x = glm::ldexp(A, exp);
  1028. Error += glm::all(glm::epsilonEqual(x, glm::vec3(1024, .24, 0),0.00001f)) ? 0 : 1;
  1029. }
  1030. {
  1031. glm::vec4 A = glm::vec4(0.5, 0.96, 0.0, -0.665);
  1032. glm::ivec4 exp = glm::ivec4(11, -2, 0, 1);
  1033. glm::vec4 x = glm::ldexp(A, exp);
  1034. Error += glm::all(glm::epsilonEqual(x, glm::vec4(1024, .24, 0, -1.33),0.00001f)) ? 0 : 1;
  1035. }
  1036. return Error;
  1037. }
  1038. }//namespace ldexp_
  1039. static int test_constexpr()
  1040. {
  1041. #if GLM_HAS_CONSTEXPR
  1042. static_assert(glm::abs(1.0f) > 0.0f, "GLM: Failed constexpr");
  1043. static_assert(glm::abs(glm::vec1(1.0f)) != glm::vec1(0.0f), "GLM: Failed constexpr");
  1044. static_assert(glm::abs(glm::vec2(1.0f)) != glm::vec2(0.0f), "GLM: Failed constexpr");
  1045. static_assert(glm::abs(glm::vec3(1.0f)) != glm::vec3(0.0f), "GLM: Failed constexpr");
  1046. static_assert(glm::abs(glm::vec4(1.0f)) != glm::vec4(0.0f), "GLM: Failed constexpr");
  1047. #endif // GLM_HAS_CONSTEXPR
  1048. return 0;
  1049. }
  1050. int main()
  1051. {
  1052. int Error = 0;
  1053. Error += test_constexpr();
  1054. Error += sign::test();
  1055. Error += floor_::test();
  1056. Error += mod_::test();
  1057. Error += modf_::test();
  1058. Error += floatBitsToInt::test();
  1059. Error += floatBitsToUint::test();
  1060. Error += mix_::test();
  1061. Error += step_::test();
  1062. Error += max_::test();
  1063. Error += min_::test();
  1064. Error += clamp_::test();
  1065. Error += round_::test();
  1066. Error += roundEven::test();
  1067. Error += isnan_::test();
  1068. Error += isinf_::test();
  1069. Error += frexp_::test();
  1070. Error += ldexp_::test();
  1071. # ifdef NDEBUG
  1072. std::size_t Samples = 1000;
  1073. # else
  1074. std::size_t Samples = 1;
  1075. # endif
  1076. Error += sign::perf(Samples);
  1077. Error += min_::perf(Samples);
  1078. return Error;
  1079. }