core_func_common.cpp 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267
  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. }//namespace min_
  232. namespace max_
  233. {
  234. static int test()
  235. {
  236. int Error = 0;
  237. glm::vec1 A0 = glm::max(glm::vec1(1), glm::vec1(1));
  238. glm::vec2 B0 = glm::max(glm::vec2(1), glm::vec2(1));
  239. glm::vec2 B1 = glm::max(glm::vec2(1), 1.0f);
  240. bool B2 = glm::all(glm::equal(B0, B1));
  241. Error += B2 ? 0 : 1;
  242. glm::vec3 C0 = glm::max(glm::vec3(1), glm::vec3(1));
  243. glm::vec3 C1 = glm::max(glm::vec3(1), 1.0f);
  244. bool C2 = glm::all(glm::equal(C0, C1));
  245. Error += C2 ? 0 : 1;
  246. glm::vec4 D0 = glm::max(glm::vec4(1), glm::vec4(1));
  247. glm::vec4 D1 = glm::max(glm::vec4(1), 1.0f);
  248. bool D2 = glm::all(glm::equal(D0, D1));
  249. Error += D2 ? 0 : 1;
  250. return Error;
  251. }
  252. }//namespace max_
  253. namespace clamp_
  254. {
  255. static int test()
  256. {
  257. int Error = 0;
  258. return Error;
  259. }
  260. }//namespace clamp_
  261. namespace mix_
  262. {
  263. template<typename T, typename B>
  264. struct entry
  265. {
  266. T x;
  267. T y;
  268. B a;
  269. T Result;
  270. };
  271. entry<float, bool> const TestBool[] =
  272. {
  273. {0.0f, 1.0f, false, 0.0f},
  274. {0.0f, 1.0f, true, 1.0f},
  275. {-1.0f, 1.0f, false, -1.0f},
  276. {-1.0f, 1.0f, true, 1.0f}
  277. };
  278. entry<float, float> const TestFloat[] =
  279. {
  280. {0.0f, 1.0f, 0.0f, 0.0f},
  281. {0.0f, 1.0f, 1.0f, 1.0f},
  282. {-1.0f, 1.0f, 0.0f, -1.0f},
  283. {-1.0f, 1.0f, 1.0f, 1.0f}
  284. };
  285. entry<glm::vec2, bool> const TestVec2Bool[] =
  286. {
  287. {glm::vec2(0.0f), glm::vec2(1.0f), false, glm::vec2(0.0f)},
  288. {glm::vec2(0.0f), glm::vec2(1.0f), true, glm::vec2(1.0f)},
  289. {glm::vec2(-1.0f), glm::vec2(1.0f), false, glm::vec2(-1.0f)},
  290. {glm::vec2(-1.0f), glm::vec2(1.0f), true, glm::vec2(1.0f)}
  291. };
  292. entry<glm::vec2, glm::bvec2> const TestBVec2[] =
  293. {
  294. {glm::vec2(0.0f), glm::vec2(1.0f), glm::bvec2(false), glm::vec2(0.0f)},
  295. {glm::vec2(0.0f), glm::vec2(1.0f), glm::bvec2(true), glm::vec2(1.0f)},
  296. {glm::vec2(-1.0f), glm::vec2(1.0f), glm::bvec2(false), glm::vec2(-1.0f)},
  297. {glm::vec2(-1.0f), glm::vec2(1.0f), glm::bvec2(true), glm::vec2(1.0f)},
  298. {glm::vec2(-1.0f), glm::vec2(1.0f), glm::bvec2(true, false), glm::vec2(1.0f, -1.0f)}
  299. };
  300. entry<glm::vec3, bool> const TestVec3Bool[] =
  301. {
  302. {glm::vec3(0.0f), glm::vec3(1.0f), false, glm::vec3(0.0f)},
  303. {glm::vec3(0.0f), glm::vec3(1.0f), true, glm::vec3(1.0f)},
  304. {glm::vec3(-1.0f), glm::vec3(1.0f), false, glm::vec3(-1.0f)},
  305. {glm::vec3(-1.0f), glm::vec3(1.0f), true, glm::vec3(1.0f)}
  306. };
  307. entry<glm::vec3, glm::bvec3> const TestBVec3[] =
  308. {
  309. {glm::vec3(0.0f), glm::vec3(1.0f), glm::bvec3(false), glm::vec3(0.0f)},
  310. {glm::vec3(0.0f), glm::vec3(1.0f), glm::bvec3(true), glm::vec3(1.0f)},
  311. {glm::vec3(-1.0f), glm::vec3(1.0f), glm::bvec3(false), glm::vec3(-1.0f)},
  312. {glm::vec3(-1.0f), glm::vec3(1.0f), glm::bvec3(true), glm::vec3(1.0f)},
  313. {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)}
  314. };
  315. entry<glm::vec4, bool> const TestVec4Bool[] =
  316. {
  317. {glm::vec4(0.0f), glm::vec4(1.0f), false, glm::vec4(0.0f)},
  318. {glm::vec4(0.0f), glm::vec4(1.0f), true, glm::vec4(1.0f)},
  319. {glm::vec4(-1.0f), glm::vec4(1.0f), false, glm::vec4(-1.0f)},
  320. {glm::vec4(-1.0f), glm::vec4(1.0f), true, glm::vec4(1.0f)}
  321. };
  322. entry<glm::vec4, glm::bvec4> const TestBVec4[] =
  323. {
  324. {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)},
  325. {glm::vec4(0.0f), glm::vec4(1.0f), glm::bvec4(true), glm::vec4(1.0f)},
  326. {glm::vec4(-1.0f), glm::vec4(1.0f), glm::bvec4(false), glm::vec4(-1.0f)},
  327. {glm::vec4(-1.0f), glm::vec4(1.0f), glm::bvec4(true), glm::vec4(1.0f)},
  328. {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)}
  329. };
  330. static int test()
  331. {
  332. int Error = 0;
  333. // Float with bool
  334. {
  335. for(std::size_t i = 0; i < sizeof(TestBool) / sizeof(entry<float, bool>); ++i)
  336. {
  337. float Result = glm::mix(TestBool[i].x, TestBool[i].y, TestBool[i].a);
  338. Error += glm::epsilonEqual(Result, TestBool[i].Result, glm::epsilon<float>()) ? 0 : 1;
  339. }
  340. }
  341. // Float with float
  342. {
  343. for(std::size_t i = 0; i < sizeof(TestFloat) / sizeof(entry<float, float>); ++i)
  344. {
  345. float Result = glm::mix(TestFloat[i].x, TestFloat[i].y, TestFloat[i].a);
  346. Error += glm::epsilonEqual(Result, TestFloat[i].Result, glm::epsilon<float>()) ? 0 : 1;
  347. }
  348. }
  349. // vec2 with bool
  350. {
  351. for(std::size_t i = 0; i < sizeof(TestVec2Bool) / sizeof(entry<glm::vec2, bool>); ++i)
  352. {
  353. glm::vec2 Result = glm::mix(TestVec2Bool[i].x, TestVec2Bool[i].y, TestVec2Bool[i].a);
  354. Error += glm::epsilonEqual(Result.x, TestVec2Bool[i].Result.x, glm::epsilon<float>()) ? 0 : 1;
  355. Error += glm::epsilonEqual(Result.y, TestVec2Bool[i].Result.y, glm::epsilon<float>()) ? 0 : 1;
  356. }
  357. }
  358. // vec2 with bvec2
  359. {
  360. for(std::size_t i = 0; i < sizeof(TestBVec2) / sizeof(entry<glm::vec2, glm::bvec2>); ++i)
  361. {
  362. glm::vec2 Result = glm::mix(TestBVec2[i].x, TestBVec2[i].y, TestBVec2[i].a);
  363. Error += glm::epsilonEqual(Result.x, TestBVec2[i].Result.x, glm::epsilon<float>()) ? 0 : 1;
  364. Error += glm::epsilonEqual(Result.y, TestBVec2[i].Result.y, glm::epsilon<float>()) ? 0 : 1;
  365. }
  366. }
  367. // vec3 with bool
  368. {
  369. for(std::size_t i = 0; i < sizeof(TestVec3Bool) / sizeof(entry<glm::vec3, bool>); ++i)
  370. {
  371. glm::vec3 Result = glm::mix(TestVec3Bool[i].x, TestVec3Bool[i].y, TestVec3Bool[i].a);
  372. Error += glm::epsilonEqual(Result.x, TestVec3Bool[i].Result.x, glm::epsilon<float>()) ? 0 : 1;
  373. Error += glm::epsilonEqual(Result.y, TestVec3Bool[i].Result.y, glm::epsilon<float>()) ? 0 : 1;
  374. Error += glm::epsilonEqual(Result.z, TestVec3Bool[i].Result.z, glm::epsilon<float>()) ? 0 : 1;
  375. }
  376. }
  377. // vec3 with bvec3
  378. {
  379. for(std::size_t i = 0; i < sizeof(TestBVec3) / sizeof(entry<glm::vec3, glm::bvec3>); ++i)
  380. {
  381. glm::vec3 Result = glm::mix(TestBVec3[i].x, TestBVec3[i].y, TestBVec3[i].a);
  382. Error += glm::epsilonEqual(Result.x, TestBVec3[i].Result.x, glm::epsilon<float>()) ? 0 : 1;
  383. Error += glm::epsilonEqual(Result.y, TestBVec3[i].Result.y, glm::epsilon<float>()) ? 0 : 1;
  384. Error += glm::epsilonEqual(Result.z, TestBVec3[i].Result.z, glm::epsilon<float>()) ? 0 : 1;
  385. }
  386. }
  387. // vec4 with bool
  388. {
  389. for(std::size_t i = 0; i < sizeof(TestVec4Bool) / sizeof(entry<glm::vec4, bool>); ++i)
  390. {
  391. glm::vec4 Result = glm::mix(TestVec4Bool[i].x, TestVec4Bool[i].y, TestVec4Bool[i].a);
  392. Error += glm::epsilonEqual(Result.x, TestVec4Bool[i].Result.x, glm::epsilon<float>()) ? 0 : 1;
  393. Error += glm::epsilonEqual(Result.y, TestVec4Bool[i].Result.y, glm::epsilon<float>()) ? 0 : 1;
  394. Error += glm::epsilonEqual(Result.z, TestVec4Bool[i].Result.z, glm::epsilon<float>()) ? 0 : 1;
  395. Error += glm::epsilonEqual(Result.w, TestVec4Bool[i].Result.w, glm::epsilon<float>()) ? 0 : 1;
  396. }
  397. }
  398. // vec4 with bvec4
  399. {
  400. for(std::size_t i = 0; i < sizeof(TestBVec4) / sizeof(entry<glm::vec4, glm::bvec4>); ++i)
  401. {
  402. glm::vec4 Result = glm::mix(TestBVec4[i].x, TestBVec4[i].y, TestBVec4[i].a);
  403. Error += glm::epsilonEqual(Result.x, TestBVec4[i].Result.x, glm::epsilon<float>()) ? 0 : 1;
  404. Error += glm::epsilonEqual(Result.y, TestBVec4[i].Result.y, glm::epsilon<float>()) ? 0 : 1;
  405. Error += glm::epsilonEqual(Result.z, TestBVec4[i].Result.z, glm::epsilon<float>()) ? 0 : 1;
  406. Error += glm::epsilonEqual(Result.w, TestBVec4[i].Result.w, glm::epsilon<float>()) ? 0 : 1;
  407. }
  408. }
  409. return Error;
  410. }
  411. }//namespace mix_
  412. namespace step_
  413. {
  414. template<typename EDGE, typename VEC>
  415. struct entry
  416. {
  417. EDGE edge;
  418. VEC x;
  419. VEC result;
  420. };
  421. entry<float, glm::vec4> TestVec4Scalar [] =
  422. {
  423. { 1.0f, glm::vec4(1.0f, 2.0f, 3.0f, 4.0f), glm::vec4(1.0f) },
  424. { 0.0f, glm::vec4(1.0f, 2.0f, 3.0f, 4.0f), glm::vec4(1.0f) },
  425. { 0.0f, glm::vec4(-1.0f, -2.0f, -3.0f, -4.0f), glm::vec4(0.0f) }
  426. };
  427. entry<glm::vec4, glm::vec4> TestVec4Vector [] =
  428. {
  429. { glm::vec4(-1.0f, -2.0f, -3.0f, -4.0f), glm::vec4(-2.0f, -3.0f, -4.0f, -5.0f), glm::vec4(0.0f) },
  430. { glm::vec4( 0.0f, 1.0f, 2.0f, 3.0f), glm::vec4( 1.0f, 2.0f, 3.0f, 4.0f), glm::vec4(1.0f) },
  431. { glm::vec4( 2.0f, 3.0f, 4.0f, 5.0f), glm::vec4( 1.0f, 2.0f, 3.0f, 4.0f), glm::vec4(0.0f) },
  432. { glm::vec4( 0.0f, 1.0f, 2.0f, 3.0f), glm::vec4(-1.0f,-2.0f,-3.0f,-4.0f), glm::vec4(0.0f) }
  433. };
  434. static int test()
  435. {
  436. int Error = 0;
  437. // scalar
  438. {
  439. float const Edge = 2.0f;
  440. float const A = glm::step(Edge, 1.0f);
  441. Error += glm::epsilonEqual(A, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  442. float const B = glm::step(Edge, 3.0f);
  443. Error += glm::epsilonEqual(B, 1.0f, glm::epsilon<float>()) ? 0 : 1;
  444. float const C = glm::step(Edge, 2.0f);
  445. Error += glm::epsilonEqual(C, 1.0f, glm::epsilon<float>()) ? 0 : 1;
  446. }
  447. // vec4 and float
  448. {
  449. for (std::size_t i = 0; i < sizeof(TestVec4Scalar) / sizeof(entry<float, glm::vec4>); ++i)
  450. {
  451. glm::vec4 Result = glm::step(TestVec4Scalar[i].edge, TestVec4Scalar[i].x);
  452. Error += glm::all(glm::epsilonEqual(Result, TestVec4Scalar[i].result, glm::epsilon<float>())) ? 0 : 1;
  453. }
  454. }
  455. // vec4 and vec4
  456. {
  457. for (std::size_t i = 0; i < sizeof(TestVec4Vector) / sizeof(entry<glm::vec4, glm::vec4>); ++i)
  458. {
  459. glm::vec4 Result = glm::step(TestVec4Vector[i].edge, TestVec4Vector[i].x);
  460. Error += glm::all(glm::epsilonEqual(Result, TestVec4Vector[i].result, glm::epsilon<float>())) ? 0 : 1;
  461. }
  462. }
  463. return Error;
  464. }
  465. }//namespace step_
  466. namespace round_
  467. {
  468. static int test()
  469. {
  470. int Error = 0;
  471. {
  472. float A = glm::round(0.0f);
  473. Error += glm::epsilonEqual(A, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  474. float B = glm::round(0.5f);
  475. Error += glm::epsilonEqual(B, 1.0f, glm::epsilon<float>()) ? 0 : 1;
  476. float C = glm::round(1.0f);
  477. Error += glm::epsilonEqual(C, 1.0f, glm::epsilon<float>()) ? 0 : 1;
  478. float D = glm::round(0.1f);
  479. Error += glm::epsilonEqual(D, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  480. float E = glm::round(0.9f);
  481. Error += glm::epsilonEqual(E, 1.0f, glm::epsilon<float>()) ? 0 : 1;
  482. float F = glm::round(1.5f);
  483. Error += glm::epsilonEqual(F, 2.0f, glm::epsilon<float>()) ? 0 : 1;
  484. float G = glm::round(1.9f);
  485. Error += glm::epsilonEqual(G, 2.0f, glm::epsilon<float>()) ? 0 : 1;
  486. }
  487. {
  488. float A = glm::round(-0.0f);
  489. Error += glm::epsilonEqual(A, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  490. float B = glm::round(-0.5f);
  491. Error += glm::epsilonEqual(B, -1.0f, glm::epsilon<float>()) ? 0 : 1;
  492. float C = glm::round(-1.0f);
  493. Error += glm::epsilonEqual(C, -1.0f, glm::epsilon<float>()) ? 0 : 1;
  494. float D = glm::round(-0.1f);
  495. Error += glm::epsilonEqual(D, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  496. float E = glm::round(-0.9f);
  497. Error += glm::epsilonEqual(E, -1.0f, glm::epsilon<float>()) ? 0 : 1;
  498. float F = glm::round(-1.5f);
  499. Error += glm::epsilonEqual(F, -2.0f, glm::epsilon<float>()) ? 0 : 1;
  500. float G = glm::round(-1.9f);
  501. Error += glm::epsilonEqual(G, -2.0f, glm::epsilon<float>()) ? 0 : 1;
  502. }
  503. return Error;
  504. }
  505. }//namespace round_
  506. namespace roundEven
  507. {
  508. static int test()
  509. {
  510. int Error = 0;
  511. {
  512. float A1 = glm::roundEven(-1.5f);
  513. Error += glm::epsilonEqual(A1, -2.0f, 0.0001f) ? 0 : 1;
  514. float A2 = glm::roundEven(1.5f);
  515. Error += glm::epsilonEqual(A2, 2.0f, 0.0001f) ? 0 : 1;
  516. float A5 = glm::roundEven(-2.5f);
  517. Error += glm::epsilonEqual(A5, -2.0f, 0.0001f) ? 0 : 1;
  518. float A6 = glm::roundEven(2.5f);
  519. Error += glm::epsilonEqual(A6, 2.0f, 0.0001f) ? 0 : 1;
  520. float A3 = glm::roundEven(-3.5f);
  521. Error += glm::epsilonEqual(A3, -4.0f, 0.0001f) ? 0 : 1;
  522. float A4 = glm::roundEven(3.5f);
  523. Error += glm::epsilonEqual(A4, 4.0f, 0.0001f) ? 0 : 1;
  524. float C7 = glm::roundEven(-4.5f);
  525. Error += glm::epsilonEqual(C7, -4.0f, 0.0001f) ? 0 : 1;
  526. float C8 = glm::roundEven(4.5f);
  527. Error += glm::epsilonEqual(C8, 4.0f, 0.0001f) ? 0 : 1;
  528. float C1 = glm::roundEven(-5.5f);
  529. Error += glm::epsilonEqual(C1, -6.0f, 0.0001f) ? 0 : 1;
  530. float C2 = glm::roundEven(5.5f);
  531. Error += glm::epsilonEqual(C2, 6.0f, 0.0001f) ? 0 : 1;
  532. float C3 = glm::roundEven(-6.5f);
  533. Error += glm::epsilonEqual(C3, -6.0f, 0.0001f) ? 0 : 1;
  534. float C4 = glm::roundEven(6.5f);
  535. Error += glm::epsilonEqual(C4, 6.0f, 0.0001f) ? 0 : 1;
  536. float C5 = glm::roundEven(-7.5f);
  537. Error += glm::epsilonEqual(C5, -8.0f, 0.0001f) ? 0 : 1;
  538. float C6 = glm::roundEven(7.5f);
  539. Error += glm::epsilonEqual(C6, 8.0f, 0.0001f) ? 0 : 1;
  540. Error += 0;
  541. }
  542. {
  543. float A7 = glm::roundEven(-2.4f);
  544. Error += glm::epsilonEqual(A7, -2.0f, 0.0001f) ? 0 : 1;
  545. float A8 = glm::roundEven(2.4f);
  546. Error += glm::epsilonEqual(A8, 2.0f, 0.0001f) ? 0 : 1;
  547. float B1 = glm::roundEven(-2.6f);
  548. Error += glm::epsilonEqual(B1, -3.0f, 0.0001f) ? 0 : 1;
  549. float B2 = glm::roundEven(2.6f);
  550. Error += glm::epsilonEqual(B2, 3.0f, 0.0001f) ? 0 : 1;
  551. float B3 = glm::roundEven(-2.0f);
  552. Error += glm::epsilonEqual(B3, -2.0f, 0.0001f) ? 0 : 1;
  553. float B4 = glm::roundEven(2.0f);
  554. Error += glm::epsilonEqual(B4, 2.0f, 0.0001f) ? 0 : 1;
  555. Error += 0;
  556. }
  557. {
  558. float A = glm::roundEven(0.0f);
  559. Error += glm::epsilonEqual(A, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  560. float B = glm::roundEven(0.5f);
  561. Error += glm::epsilonEqual(B, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  562. float C = glm::roundEven(1.0f);
  563. Error += glm::epsilonEqual(C, 1.0f, glm::epsilon<float>()) ? 0 : 1;
  564. float D = glm::roundEven(0.1f);
  565. Error += glm::epsilonEqual(D, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  566. float E = glm::roundEven(0.9f);
  567. Error += glm::epsilonEqual(E, 1.0f, glm::epsilon<float>()) ? 0 : 1;
  568. float F = glm::roundEven(1.5f);
  569. Error += glm::epsilonEqual(F, 2.0f, glm::epsilon<float>()) ? 0 : 1;
  570. float G = glm::roundEven(1.9f);
  571. Error += glm::epsilonEqual(G, 2.0f, glm::epsilon<float>()) ? 0 : 1;
  572. }
  573. {
  574. float A = glm::roundEven(-0.0f);
  575. Error += glm::epsilonEqual(A, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  576. float B = glm::roundEven(-0.5f);
  577. Error += glm::epsilonEqual(B, -0.0f, glm::epsilon<float>()) ? 0 : 1;
  578. float C = glm::roundEven(-1.0f);
  579. Error += glm::epsilonEqual(C, -1.0f, glm::epsilon<float>()) ? 0 : 1;
  580. float D = glm::roundEven(-0.1f);
  581. Error += glm::epsilonEqual(D, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  582. float E = glm::roundEven(-0.9f);
  583. Error += glm::epsilonEqual(E, -1.0f, glm::epsilon<float>()) ? 0 : 1;
  584. float F = glm::roundEven(-1.5f);
  585. Error += glm::epsilonEqual(F, -2.0f, glm::epsilon<float>()) ? 0 : 1;
  586. float G = glm::roundEven(-1.9f);
  587. Error += glm::epsilonEqual(G, -2.0f, glm::epsilon<float>()) ? 0 : 1;
  588. }
  589. {
  590. float A = glm::roundEven(1.5f);
  591. Error += glm::epsilonEqual(A, 2.0f, glm::epsilon<float>()) ? 0 : 1;
  592. float B = glm::roundEven(2.5f);
  593. Error += glm::epsilonEqual(B, 2.0f, glm::epsilon<float>()) ? 0 : 1;
  594. float C = glm::roundEven(3.5f);
  595. Error += glm::epsilonEqual(C, 4.0f, glm::epsilon<float>()) ? 0 : 1;
  596. float D = glm::roundEven(4.5f);
  597. Error += glm::epsilonEqual(D, 4.0f, glm::epsilon<float>()) ? 0 : 1;
  598. float E = glm::roundEven(5.5f);
  599. Error += glm::epsilonEqual(E, 6.0f, glm::epsilon<float>()) ? 0 : 1;
  600. float F = glm::roundEven(6.5f);
  601. Error += glm::epsilonEqual(F, 6.0f, glm::epsilon<float>()) ? 0 : 1;
  602. float G = glm::roundEven(7.5f);
  603. Error += glm::epsilonEqual(G, 8.0f, glm::epsilon<float>()) ? 0 : 1;
  604. }
  605. {
  606. float A = glm::roundEven(-1.5f);
  607. Error += glm::epsilonEqual(A, -2.0f, glm::epsilon<float>()) ? 0 : 1;
  608. float B = glm::roundEven(-2.5f);
  609. Error += glm::epsilonEqual(B, -2.0f, glm::epsilon<float>()) ? 0 : 1;
  610. float C = glm::roundEven(-3.5f);
  611. Error += glm::epsilonEqual(C, -4.0f, glm::epsilon<float>()) ? 0 : 1;
  612. float D = glm::roundEven(-4.5f);
  613. Error += glm::epsilonEqual(D, -4.0f, glm::epsilon<float>()) ? 0 : 1;
  614. float E = glm::roundEven(-5.5f);
  615. Error += glm::epsilonEqual(E, -6.0f, glm::epsilon<float>()) ? 0 : 1;
  616. float F = glm::roundEven(-6.5f);
  617. Error += glm::epsilonEqual(F, -6.0f, glm::epsilon<float>()) ? 0 : 1;
  618. float G = glm::roundEven(-7.5f);
  619. Error += glm::epsilonEqual(G, -8.0f, glm::epsilon<float>()) ? 0 : 1;
  620. }
  621. return Error;
  622. }
  623. }//namespace roundEven
  624. namespace isnan_
  625. {
  626. static int test()
  627. {
  628. int Error = 0;
  629. float Zero_f = 0.0;
  630. double Zero_d = 0.0;
  631. {
  632. Error += true == glm::isnan(0.0/Zero_d) ? 0 : 1;
  633. Error += true == glm::any(glm::isnan(glm::dvec2(0.0 / Zero_d))) ? 0 : 1;
  634. Error += true == glm::any(glm::isnan(glm::dvec3(0.0 / Zero_d))) ? 0 : 1;
  635. Error += true == glm::any(glm::isnan(glm::dvec4(0.0 / Zero_d))) ? 0 : 1;
  636. }
  637. {
  638. Error += true == glm::isnan(0.0f/Zero_f) ? 0 : 1;
  639. Error += true == glm::any(glm::isnan(glm::vec2(0.0f/Zero_f))) ? 0 : 1;
  640. Error += true == glm::any(glm::isnan(glm::vec3(0.0f/Zero_f))) ? 0 : 1;
  641. Error += true == glm::any(glm::isnan(glm::vec4(0.0f/Zero_f))) ? 0 : 1;
  642. }
  643. return Error;
  644. }
  645. }//namespace isnan_
  646. namespace isinf_
  647. {
  648. static int test()
  649. {
  650. int Error = 0;
  651. float Zero_f = 0.0;
  652. double Zero_d = 0.0;
  653. {
  654. Error += true == glm::isinf( 1.0/Zero_d) ? 0 : 1;
  655. Error += true == glm::isinf(-1.0/Zero_d) ? 0 : 1;
  656. Error += true == glm::any(glm::isinf(glm::dvec2( 1.0/Zero_d))) ? 0 : 1;
  657. Error += true == glm::any(glm::isinf(glm::dvec2(-1.0/Zero_d))) ? 0 : 1;
  658. Error += true == glm::any(glm::isinf(glm::dvec3( 1.0/Zero_d))) ? 0 : 1;
  659. Error += true == glm::any(glm::isinf(glm::dvec3(-1.0/Zero_d))) ? 0 : 1;
  660. Error += true == glm::any(glm::isinf(glm::dvec4( 1.0/Zero_d))) ? 0 : 1;
  661. Error += true == glm::any(glm::isinf(glm::dvec4(-1.0/Zero_d))) ? 0 : 1;
  662. }
  663. {
  664. Error += true == glm::isinf( 1.0f/Zero_f) ? 0 : 1;
  665. Error += true == glm::isinf(-1.0f/Zero_f) ? 0 : 1;
  666. Error += true == glm::any(glm::isinf(glm::vec2( 1.0f/Zero_f))) ? 0 : 1;
  667. Error += true == glm::any(glm::isinf(glm::vec2(-1.0f/Zero_f))) ? 0 : 1;
  668. Error += true == glm::any(glm::isinf(glm::vec3( 1.0f/Zero_f))) ? 0 : 1;
  669. Error += true == glm::any(glm::isinf(glm::vec3(-1.0f/Zero_f))) ? 0 : 1;
  670. Error += true == glm::any(glm::isinf(glm::vec4( 1.0f/Zero_f))) ? 0 : 1;
  671. Error += true == glm::any(glm::isinf(glm::vec4(-1.0f/Zero_f))) ? 0 : 1;
  672. }
  673. return Error;
  674. }
  675. }//namespace isinf_
  676. namespace sign
  677. {
  678. template<typename genFIType>
  679. GLM_FUNC_QUALIFIER genFIType sign_if(genFIType x)
  680. {
  681. GLM_STATIC_ASSERT(
  682. std::numeric_limits<genFIType>::is_iec559 ||
  683. (std::numeric_limits<genFIType>::is_signed && std::numeric_limits<genFIType>::is_integer), "'sign' only accept signed inputs");
  684. genFIType result;
  685. if(x > genFIType(0))
  686. result = genFIType(1);
  687. else if(x < genFIType(0))
  688. result = genFIType(-1);
  689. else
  690. result = genFIType(0);
  691. return result;
  692. }
  693. template<typename genFIType>
  694. GLM_FUNC_QUALIFIER genFIType sign_alu1(genFIType x)
  695. {
  696. GLM_STATIC_ASSERT(
  697. std::numeric_limits<genFIType>::is_signed && std::numeric_limits<genFIType>::is_integer,
  698. "'sign' only accept integer inputs");
  699. return (x >> 31) | (static_cast<unsigned>(-x) >> 31);
  700. }
  701. GLM_FUNC_QUALIFIER int sign_alu2(int x)
  702. {
  703. GLM_STATIC_ASSERT(std::numeric_limits<int>::is_signed && std::numeric_limits<int>::is_integer, "'sign' only accept integer inputs");
  704. # if GLM_COMPILER & GLM_COMPILER_VC
  705. # pragma warning(push)
  706. # pragma warning(disable : 4146) //cast truncates constant value
  707. # endif
  708. return -(static_cast<unsigned>(x) >> 31) | (-static_cast<unsigned>(x) >> 31);
  709. # if GLM_COMPILER & GLM_COMPILER_VC
  710. # pragma warning(pop)
  711. # endif
  712. }
  713. template<typename genFIType>
  714. GLM_FUNC_QUALIFIER genFIType sign_sub(genFIType x)
  715. {
  716. GLM_STATIC_ASSERT(
  717. std::numeric_limits<genFIType>::is_signed && std::numeric_limits<genFIType>::is_integer,
  718. "'sign' only accept integer inputs");
  719. return (static_cast<unsigned>(-x) >> 31) - (static_cast<unsigned>(x) >> 31);
  720. }
  721. template<typename genFIType>
  722. GLM_FUNC_QUALIFIER genFIType sign_cmp(genFIType x)
  723. {
  724. GLM_STATIC_ASSERT(
  725. std::numeric_limits<genFIType>::is_signed && std::numeric_limits<genFIType>::is_integer,
  726. "'sign' only accept integer inputs");
  727. return (x > 0) - (x < 0);
  728. }
  729. template<typename genType>
  730. struct type
  731. {
  732. genType Value;
  733. genType Return;
  734. };
  735. int test_int32()
  736. {
  737. type<glm::int32> const Data[] =
  738. {
  739. { std::numeric_limits<glm::int32>::max(), 1},
  740. { std::numeric_limits<glm::int32>::min(), -1},
  741. { 0, 0},
  742. { 1, 1},
  743. { 2, 1},
  744. { 3, 1},
  745. {-1,-1},
  746. {-2,-1},
  747. {-3,-1}
  748. };
  749. int Error = 0;
  750. for(std::size_t i = 0; i < sizeof(Data) / sizeof(type<glm::int32>); ++i)
  751. {
  752. glm::int32 Result = glm::sign(Data[i].Value);
  753. Error += Data[i].Return == Result ? 0 : 1;
  754. }
  755. for(std::size_t i = 0; i < sizeof(Data) / sizeof(type<glm::int32>); ++i)
  756. {
  757. glm::int32 Result = sign_cmp(Data[i].Value);
  758. Error += Data[i].Return == Result ? 0 : 1;
  759. }
  760. for(std::size_t i = 0; i < sizeof(Data) / sizeof(type<glm::int32>); ++i)
  761. {
  762. glm::int32 Result = sign_if(Data[i].Value);
  763. Error += Data[i].Return == Result ? 0 : 1;
  764. }
  765. for(std::size_t i = 0; i < sizeof(Data) / sizeof(type<glm::int32>); ++i)
  766. {
  767. glm::int32 Result = sign_alu1(Data[i].Value);
  768. Error += Data[i].Return == Result ? 0 : 1;
  769. }
  770. for(std::size_t i = 0; i < sizeof(Data) / sizeof(type<glm::int32>); ++i)
  771. {
  772. glm::int32 Result = sign_alu2(Data[i].Value);
  773. Error += Data[i].Return == Result ? 0 : 1;
  774. }
  775. return Error;
  776. }
  777. int test_i32vec4()
  778. {
  779. type<glm::i32vec4> const Data[] =
  780. {
  781. {glm::i32vec4( 1), glm::i32vec4( 1)},
  782. {glm::i32vec4( 0), glm::i32vec4( 0)},
  783. {glm::i32vec4( 2), glm::i32vec4( 1)},
  784. {glm::i32vec4( 3), glm::i32vec4( 1)},
  785. {glm::i32vec4(-1), glm::i32vec4(-1)},
  786. {glm::i32vec4(-2), glm::i32vec4(-1)},
  787. {glm::i32vec4(-3), glm::i32vec4(-1)}
  788. };
  789. int Error = 0;
  790. for(std::size_t i = 0; i < sizeof(Data) / sizeof(type<glm::i32vec4>); ++i)
  791. {
  792. glm::i32vec4 Result = glm::sign(Data[i].Value);
  793. Error += glm::all(glm::equal(Data[i].Return, Result)) ? 0 : 1;
  794. }
  795. return Error;
  796. }
  797. int test_f32vec4()
  798. {
  799. type<glm::vec4> const Data[] =
  800. {
  801. {glm::vec4( 1), glm::vec4( 1)},
  802. {glm::vec4( 0), glm::vec4( 0)},
  803. {glm::vec4( 2), glm::vec4( 1)},
  804. {glm::vec4( 3), glm::vec4( 1)},
  805. {glm::vec4(-1), glm::vec4(-1)},
  806. {glm::vec4(-2), glm::vec4(-1)},
  807. {glm::vec4(-3), glm::vec4(-1)}
  808. };
  809. int Error = 0;
  810. for(std::size_t i = 0; i < sizeof(Data) / sizeof(type<glm::vec4>); ++i)
  811. {
  812. glm::vec4 Result = glm::sign(Data[i].Value);
  813. Error += glm::all(glm::equal(Data[i].Return, Result)) ? 0 : 1;
  814. }
  815. return Error;
  816. }
  817. static int test()
  818. {
  819. int Error = 0;
  820. Error += test_int32();
  821. Error += test_i32vec4();
  822. Error += test_f32vec4();
  823. return Error;
  824. }
  825. int perf_rand(std::size_t Samples)
  826. {
  827. int Error = 0;
  828. std::size_t const Count = Samples;
  829. std::vector<glm::int32> Input, Output;
  830. Input.resize(Count);
  831. Output.resize(Count);
  832. for(std::size_t i = 0; i < Count; ++i)
  833. Input[i] = static_cast<glm::int32>(glm::linearRand(-65536.f, 65536.f));
  834. std::clock_t Timestamp0 = std::clock();
  835. for(std::size_t i = 0; i < Count; ++i)
  836. Output[i] = sign_cmp(Input[i]);
  837. std::clock_t Timestamp1 = std::clock();
  838. for(std::size_t i = 0; i < Count; ++i)
  839. Output[i] = sign_if(Input[i]);
  840. std::clock_t Timestamp2 = std::clock();
  841. for(std::size_t i = 0; i < Count; ++i)
  842. Output[i] = sign_alu1(Input[i]);
  843. std::clock_t Timestamp3 = std::clock();
  844. for(std::size_t i = 0; i < Count; ++i)
  845. Output[i] = sign_alu2(Input[i]);
  846. std::clock_t Timestamp4 = std::clock();
  847. for(std::size_t i = 0; i < Count; ++i)
  848. Output[i] = sign_sub(Input[i]);
  849. std::clock_t Timestamp5 = std::clock();
  850. for(std::size_t i = 0; i < Count; ++i)
  851. Output[i] = glm::sign(Input[i]);
  852. std::clock_t Timestamp6 = std::clock();
  853. std::printf("sign_cmp(rand) Time %d clocks\n", static_cast<unsigned int>(Timestamp1 - Timestamp0));
  854. std::printf("sign_if(rand) Time %d clocks\n", static_cast<unsigned int>(Timestamp2 - Timestamp1));
  855. std::printf("sign_alu1(rand) Time %d clocks\n", static_cast<unsigned int>(Timestamp3 - Timestamp2));
  856. std::printf("sign_alu2(rand) Time %d clocks\n", static_cast<unsigned int>(Timestamp4 - Timestamp3));
  857. std::printf("sign_sub(rand) Time %d clocks\n", static_cast<unsigned int>(Timestamp5 - Timestamp4));
  858. std::printf("glm::sign(rand) Time %d clocks\n", static_cast<unsigned int>(Timestamp6 - Timestamp5));
  859. return Error;
  860. }
  861. int perf_linear(std::size_t Samples)
  862. {
  863. int Error = 0;
  864. std::size_t const Count = Samples;
  865. std::vector<glm::int32> Input, Output;
  866. Input.resize(Count);
  867. Output.resize(Count);
  868. for(std::size_t i = 0; i < Count; ++i)
  869. Input[i] = static_cast<glm::int32>(i);
  870. std::clock_t Timestamp0 = std::clock();
  871. for(std::size_t i = 0; i < Count; ++i)
  872. Output[i] = sign_cmp(Input[i]);
  873. std::clock_t Timestamp1 = std::clock();
  874. for(std::size_t i = 0; i < Count; ++i)
  875. Output[i] = sign_if(Input[i]);
  876. std::clock_t Timestamp2 = std::clock();
  877. for(std::size_t i = 0; i < Count; ++i)
  878. Output[i] = sign_alu1(Input[i]);
  879. std::clock_t Timestamp3 = std::clock();
  880. for(std::size_t i = 0; i < Count; ++i)
  881. Output[i] = sign_alu2(Input[i]);
  882. std::clock_t Timestamp4 = std::clock();
  883. for(std::size_t i = 0; i < Count; ++i)
  884. Output[i] = sign_sub(Input[i]);
  885. std::clock_t Timestamp5 = std::clock();
  886. std::printf("sign_cmp(linear) Time %d clocks\n", static_cast<unsigned int>(Timestamp1 - Timestamp0));
  887. std::printf("sign_if(linear) Time %d clocks\n", static_cast<unsigned int>(Timestamp2 - Timestamp1));
  888. std::printf("sign_alu1(linear) Time %d clocks\n", static_cast<unsigned int>(Timestamp3 - Timestamp2));
  889. std::printf("sign_alu2(linear) Time %d clocks\n", static_cast<unsigned int>(Timestamp4 - Timestamp3));
  890. std::printf("sign_sub(linear) Time %d clocks\n", static_cast<unsigned int>(Timestamp5 - Timestamp4));
  891. return Error;
  892. }
  893. int perf_linear_cal(std::size_t Samples)
  894. {
  895. int Error = 0;
  896. glm::int32 const Count = static_cast<glm::int32>(Samples);
  897. std::clock_t Timestamp0 = std::clock();
  898. glm::int32 Sum = 0;
  899. for(glm::int32 i = 1; i < Count; ++i)
  900. Sum += sign_cmp(i);
  901. std::clock_t Timestamp1 = std::clock();
  902. for(glm::int32 i = 1; i < Count; ++i)
  903. Sum += sign_if(i);
  904. std::clock_t Timestamp2 = std::clock();
  905. for(glm::int32 i = 1; i < Count; ++i)
  906. Sum += sign_alu1(i);
  907. std::clock_t Timestamp3 = std::clock();
  908. for(glm::int32 i = 1; i < Count; ++i)
  909. Sum += sign_alu2(i);
  910. std::clock_t Timestamp4 = std::clock();
  911. for(glm::int32 i = 1; i < Count; ++i)
  912. Sum += sign_sub(i);
  913. std::clock_t Timestamp5 = std::clock();
  914. std::printf("Sum %d\n", static_cast<unsigned int>(Sum));
  915. std::printf("sign_cmp(linear_cal) Time %d clocks\n", static_cast<unsigned int>(Timestamp1 - Timestamp0));
  916. std::printf("sign_if(linear_cal) Time %d clocks\n", static_cast<unsigned int>(Timestamp2 - Timestamp1));
  917. std::printf("sign_alu1(linear_cal) Time %d clocks\n", static_cast<unsigned int>(Timestamp3 - Timestamp2));
  918. std::printf("sign_alu2(linear_cal) Time %d clocks\n", static_cast<unsigned int>(Timestamp4 - Timestamp3));
  919. std::printf("sign_sub(linear_cal) Time %d clocks\n", static_cast<unsigned int>(Timestamp5 - Timestamp4));
  920. return Error;
  921. }
  922. static int perf(std::size_t Samples)
  923. {
  924. int Error(0);
  925. Error += perf_linear_cal(Samples);
  926. Error += perf_linear(Samples);
  927. Error += perf_rand(Samples);
  928. return Error;
  929. }
  930. }//namespace sign
  931. namespace frexp_
  932. {
  933. static int test()
  934. {
  935. int Error(0);
  936. {
  937. glm::vec1 x(1024);
  938. glm::ivec1 exp;
  939. glm::vec1 A = glm::frexp(x, exp);
  940. Error += glm::all(glm::epsilonEqual(A, glm::vec1(0.5), 0.00001f)) ? 0 : 1;
  941. Error += glm::all(glm::equal(exp, glm::ivec1(11))) ? 0 : 1;
  942. }
  943. {
  944. glm::vec2 x(1024, 0.24);
  945. glm::ivec2 exp;
  946. glm::vec2 A = glm::frexp(x, exp);
  947. Error += glm::all(glm::epsilonEqual(A, glm::vec2(0.5, 0.96), 0.00001f)) ? 0 : 1;
  948. Error += glm::all(glm::equal(exp, glm::ivec2(11, -2))) ? 0 : 1;
  949. }
  950. {
  951. glm::vec3 x(1024, 0.24, 0);
  952. glm::ivec3 exp;
  953. glm::vec3 A = glm::frexp(x, exp);
  954. Error += glm::all(glm::epsilonEqual(A, glm::vec3(0.5, 0.96, 0.0), 0.00001f)) ? 0 : 1;
  955. Error += glm::all(glm::equal(exp, glm::ivec3(11, -2, 0))) ? 0 : 1;
  956. }
  957. {
  958. glm::vec4 x(1024, 0.24, 0, -1.33);
  959. glm::ivec4 exp;
  960. glm::vec4 A = glm::frexp(x, exp);
  961. Error += glm::all(glm::epsilonEqual(A, glm::vec4(0.5, 0.96, 0.0, -0.665), 0.00001f)) ? 0 : 1;
  962. Error += glm::all(glm::equal(exp, glm::ivec4(11, -2, 0, 1))) ? 0 : 1;
  963. }
  964. return Error;
  965. }
  966. }//namespace frexp_
  967. namespace ldexp_
  968. {
  969. static int test()
  970. {
  971. int Error(0);
  972. {
  973. glm::vec1 A = glm::vec1(0.5);
  974. glm::ivec1 exp = glm::ivec1(11);
  975. glm::vec1 x = glm::ldexp(A, exp);
  976. Error += glm::all(glm::epsilonEqual(x, glm::vec1(1024),0.00001f)) ? 0 : 1;
  977. }
  978. {
  979. glm::vec2 A = glm::vec2(0.5, 0.96);
  980. glm::ivec2 exp = glm::ivec2(11, -2);
  981. glm::vec2 x = glm::ldexp(A, exp);
  982. Error += glm::all(glm::epsilonEqual(x, glm::vec2(1024, .24),0.00001f)) ? 0 : 1;
  983. }
  984. {
  985. glm::vec3 A = glm::vec3(0.5, 0.96, 0.0);
  986. glm::ivec3 exp = glm::ivec3(11, -2, 0);
  987. glm::vec3 x = glm::ldexp(A, exp);
  988. Error += glm::all(glm::epsilonEqual(x, glm::vec3(1024, .24, 0),0.00001f)) ? 0 : 1;
  989. }
  990. {
  991. glm::vec4 A = glm::vec4(0.5, 0.96, 0.0, -0.665);
  992. glm::ivec4 exp = glm::ivec4(11, -2, 0, 1);
  993. glm::vec4 x = glm::ldexp(A, exp);
  994. Error += glm::all(glm::epsilonEqual(x, glm::vec4(1024, .24, 0, -1.33),0.00001f)) ? 0 : 1;
  995. }
  996. return Error;
  997. }
  998. }//namespace ldexp_
  999. int main()
  1000. {
  1001. int Error = 0;
  1002. Error += sign::test();
  1003. Error += floor_::test();
  1004. Error += mod_::test();
  1005. Error += modf_::test();
  1006. Error += floatBitsToInt::test();
  1007. Error += floatBitsToUint::test();
  1008. Error += mix_::test();
  1009. Error += step_::test();
  1010. Error += max_::test();
  1011. Error += min_::test();
  1012. Error += clamp_::test();
  1013. Error += round_::test();
  1014. Error += roundEven::test();
  1015. Error += isnan_::test();
  1016. Error += isinf_::test();
  1017. Error += frexp_::test();
  1018. Error += ldexp_::test();
  1019. # ifdef NDEBUG
  1020. std::size_t Samples = 1000;
  1021. # else
  1022. std::size_t Samples = 1;
  1023. # endif
  1024. Error += sign::perf(Samples);
  1025. return Error;
  1026. }