core_func_common.cpp 36 KB

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