core_func_common.cpp 36 KB

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