core_func_common.cpp 36 KB

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