core_func_common.cpp 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412
  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. int main()
  1106. {
  1107. int Error = 0;
  1108. Error += sign::test();
  1109. Error += floor_::test();
  1110. Error += mod_::test();
  1111. Error += modf_::test();
  1112. Error += floatBitsToInt::test();
  1113. Error += floatBitsToUint::test();
  1114. Error += mix_::test();
  1115. Error += step_::test();
  1116. Error += smoothstep_::test();
  1117. Error += max_::test();
  1118. Error += min_::test();
  1119. Error += clamp_::test();
  1120. Error += round_::test();
  1121. Error += roundEven::test();
  1122. Error += isnan_::test();
  1123. Error += isinf_::test();
  1124. Error += frexp_::test();
  1125. Error += ldexp_::test();
  1126. # ifdef NDEBUG
  1127. std::size_t Samples = 1000;
  1128. # else
  1129. std::size_t Samples = 1;
  1130. # endif
  1131. Error += sign::perf(Samples);
  1132. Error += min_::perf(Samples);
  1133. return Error;
  1134. }
  1135. #if(GLM_COMPILER & GLM_COMPILER_VC)
  1136. # pragma warning(pop)
  1137. #endif