core_func_common.cpp 38 KB

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