core_func_common.cpp 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394
  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 round_
  538. {
  539. static int test()
  540. {
  541. int Error = 0;
  542. {
  543. float A = glm::round(0.0f);
  544. Error += glm::equal(A, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  545. float B = glm::round(0.5f);
  546. Error += (glm::equal(B, 1.0f, glm::epsilon<float>()) || glm::equal(B, 0.0f, glm::epsilon<float>())) ? 0 : 1;
  547. float C = glm::round(1.0f);
  548. Error += glm::equal(C, 1.0f, glm::epsilon<float>()) ? 0 : 1;
  549. float D = glm::round(0.1f);
  550. Error += glm::equal(D, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  551. float E = glm::round(0.9f);
  552. Error += glm::equal(E, 1.0f, glm::epsilon<float>()) ? 0 : 1;
  553. float F = glm::round(1.5f);
  554. Error += glm::equal(F, 2.0f, glm::epsilon<float>()) ? 0 : 1;
  555. float G = glm::round(1.9f);
  556. Error += glm::equal(G, 2.0f, glm::epsilon<float>()) ? 0 : 1;
  557. }
  558. {
  559. float A = glm::round(-0.0f);
  560. Error += glm::equal(A, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  561. float B = glm::round(-0.5f);
  562. Error += (glm::equal(B, -1.0f, glm::epsilon<float>()) || glm::equal(B, 0.0f, glm::epsilon<float>())) ? 0 : 1;
  563. float C = glm::round(-1.0f);
  564. Error += glm::equal(C, -1.0f, glm::epsilon<float>()) ? 0 : 1;
  565. float D = glm::round(-0.1f);
  566. Error += glm::equal(D, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  567. float E = glm::round(-0.9f);
  568. Error += glm::equal(E, -1.0f, glm::epsilon<float>()) ? 0 : 1;
  569. float F = glm::round(-1.5f);
  570. Error += glm::equal(F, -2.0f, glm::epsilon<float>()) ? 0 : 1;
  571. float G = glm::round(-1.9f);
  572. Error += glm::equal(G, -2.0f, glm::epsilon<float>()) ? 0 : 1;
  573. }
  574. return Error;
  575. }
  576. }//namespace round_
  577. namespace roundEven
  578. {
  579. static int test()
  580. {
  581. int Error = 0;
  582. {
  583. float A1 = glm::roundEven(-1.5f);
  584. Error += glm::equal(A1, -2.0f, 0.0001f) ? 0 : 1;
  585. float A2 = glm::roundEven(1.5f);
  586. Error += glm::equal(A2, 2.0f, 0.0001f) ? 0 : 1;
  587. float A5 = glm::roundEven(-2.5f);
  588. Error += glm::equal(A5, -2.0f, 0.0001f) ? 0 : 1;
  589. float A6 = glm::roundEven(2.5f);
  590. Error += glm::equal(A6, 2.0f, 0.0001f) ? 0 : 1;
  591. float A3 = glm::roundEven(-3.5f);
  592. Error += glm::equal(A3, -4.0f, 0.0001f) ? 0 : 1;
  593. float A4 = glm::roundEven(3.5f);
  594. Error += glm::equal(A4, 4.0f, 0.0001f) ? 0 : 1;
  595. float C7 = glm::roundEven(-4.5f);
  596. Error += glm::equal(C7, -4.0f, 0.0001f) ? 0 : 1;
  597. float C8 = glm::roundEven(4.5f);
  598. Error += glm::equal(C8, 4.0f, 0.0001f) ? 0 : 1;
  599. float C1 = glm::roundEven(-5.5f);
  600. Error += glm::equal(C1, -6.0f, 0.0001f) ? 0 : 1;
  601. float C2 = glm::roundEven(5.5f);
  602. Error += glm::equal(C2, 6.0f, 0.0001f) ? 0 : 1;
  603. float C3 = glm::roundEven(-6.5f);
  604. Error += glm::equal(C3, -6.0f, 0.0001f) ? 0 : 1;
  605. float C4 = glm::roundEven(6.5f);
  606. Error += glm::equal(C4, 6.0f, 0.0001f) ? 0 : 1;
  607. float C5 = glm::roundEven(-7.5f);
  608. Error += glm::equal(C5, -8.0f, 0.0001f) ? 0 : 1;
  609. float C6 = glm::roundEven(7.5f);
  610. Error += glm::equal(C6, 8.0f, 0.0001f) ? 0 : 1;
  611. Error += 0;
  612. }
  613. {
  614. float A7 = glm::roundEven(-2.4f);
  615. Error += glm::equal(A7, -2.0f, 0.0001f) ? 0 : 1;
  616. float A8 = glm::roundEven(2.4f);
  617. Error += glm::equal(A8, 2.0f, 0.0001f) ? 0 : 1;
  618. float B1 = glm::roundEven(-2.6f);
  619. Error += glm::equal(B1, -3.0f, 0.0001f) ? 0 : 1;
  620. float B2 = glm::roundEven(2.6f);
  621. Error += glm::equal(B2, 3.0f, 0.0001f) ? 0 : 1;
  622. float B3 = glm::roundEven(-2.0f);
  623. Error += glm::equal(B3, -2.0f, 0.0001f) ? 0 : 1;
  624. float B4 = glm::roundEven(2.0f);
  625. Error += glm::equal(B4, 2.0f, 0.0001f) ? 0 : 1;
  626. Error += 0;
  627. }
  628. {
  629. float A = glm::roundEven(0.0f);
  630. Error += glm::equal(A, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  631. float B = glm::roundEven(0.5f);
  632. Error += glm::equal(B, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  633. float C = glm::roundEven(1.0f);
  634. Error += glm::equal(C, 1.0f, glm::epsilon<float>()) ? 0 : 1;
  635. float D = glm::roundEven(0.1f);
  636. Error += glm::equal(D, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  637. float E = glm::roundEven(0.9f);
  638. Error += glm::equal(E, 1.0f, glm::epsilon<float>()) ? 0 : 1;
  639. float F = glm::roundEven(1.5f);
  640. Error += glm::equal(F, 2.0f, glm::epsilon<float>()) ? 0 : 1;
  641. float G = glm::roundEven(1.9f);
  642. Error += glm::equal(G, 2.0f, glm::epsilon<float>()) ? 0 : 1;
  643. }
  644. {
  645. float A = glm::roundEven(-0.0f);
  646. Error += glm::equal(A, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  647. float B = glm::roundEven(-0.5f);
  648. Error += glm::equal(B, -0.0f, glm::epsilon<float>()) ? 0 : 1;
  649. float C = glm::roundEven(-1.0f);
  650. Error += glm::equal(C, -1.0f, glm::epsilon<float>()) ? 0 : 1;
  651. float D = glm::roundEven(-0.1f);
  652. Error += glm::equal(D, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  653. float E = glm::roundEven(-0.9f);
  654. Error += glm::equal(E, -1.0f, glm::epsilon<float>()) ? 0 : 1;
  655. float F = glm::roundEven(-1.5f);
  656. Error += glm::equal(F, -2.0f, glm::epsilon<float>()) ? 0 : 1;
  657. float G = glm::roundEven(-1.9f);
  658. Error += glm::equal(G, -2.0f, glm::epsilon<float>()) ? 0 : 1;
  659. }
  660. {
  661. float A = glm::roundEven(1.5f);
  662. Error += glm::equal(A, 2.0f, glm::epsilon<float>()) ? 0 : 1;
  663. float B = glm::roundEven(2.5f);
  664. Error += glm::equal(B, 2.0f, glm::epsilon<float>()) ? 0 : 1;
  665. float C = glm::roundEven(3.5f);
  666. Error += glm::equal(C, 4.0f, glm::epsilon<float>()) ? 0 : 1;
  667. float D = glm::roundEven(4.5f);
  668. Error += glm::equal(D, 4.0f, glm::epsilon<float>()) ? 0 : 1;
  669. float E = glm::roundEven(5.5f);
  670. Error += glm::equal(E, 6.0f, glm::epsilon<float>()) ? 0 : 1;
  671. float F = glm::roundEven(6.5f);
  672. Error += glm::equal(F, 6.0f, glm::epsilon<float>()) ? 0 : 1;
  673. float G = glm::roundEven(7.5f);
  674. Error += glm::equal(G, 8.0f, glm::epsilon<float>()) ? 0 : 1;
  675. }
  676. {
  677. float A = glm::roundEven(-1.5f);
  678. Error += glm::equal(A, -2.0f, glm::epsilon<float>()) ? 0 : 1;
  679. float B = glm::roundEven(-2.5f);
  680. Error += glm::equal(B, -2.0f, glm::epsilon<float>()) ? 0 : 1;
  681. float C = glm::roundEven(-3.5f);
  682. Error += glm::equal(C, -4.0f, glm::epsilon<float>()) ? 0 : 1;
  683. float D = glm::roundEven(-4.5f);
  684. Error += glm::equal(D, -4.0f, glm::epsilon<float>()) ? 0 : 1;
  685. float E = glm::roundEven(-5.5f);
  686. Error += glm::equal(E, -6.0f, glm::epsilon<float>()) ? 0 : 1;
  687. float F = glm::roundEven(-6.5f);
  688. Error += glm::equal(F, -6.0f, glm::epsilon<float>()) ? 0 : 1;
  689. float G = glm::roundEven(-7.5f);
  690. Error += glm::equal(G, -8.0f, glm::epsilon<float>()) ? 0 : 1;
  691. }
  692. return Error;
  693. }
  694. }//namespace roundEven
  695. namespace isnan_
  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::isnan(0.0/Zero_d) ? 0 : 1;
  704. Error += true == glm::any(glm::isnan(glm::dvec2(0.0 / Zero_d))) ? 0 : 1;
  705. Error += true == glm::any(glm::isnan(glm::dvec3(0.0 / Zero_d))) ? 0 : 1;
  706. Error += true == glm::any(glm::isnan(glm::dvec4(0.0 / Zero_d))) ? 0 : 1;
  707. }
  708. {
  709. Error += true == glm::isnan(0.0f/Zero_f) ? 0 : 1;
  710. Error += true == glm::any(glm::isnan(glm::vec2(0.0f/Zero_f))) ? 0 : 1;
  711. Error += true == glm::any(glm::isnan(glm::vec3(0.0f/Zero_f))) ? 0 : 1;
  712. Error += true == glm::any(glm::isnan(glm::vec4(0.0f/Zero_f))) ? 0 : 1;
  713. }
  714. return Error;
  715. }
  716. }//namespace isnan_
  717. namespace isinf_
  718. {
  719. static int test()
  720. {
  721. int Error = 0;
  722. float Zero_f = 0.0;
  723. double Zero_d = 0.0;
  724. {
  725. Error += true == glm::isinf( 1.0/Zero_d) ? 0 : 1;
  726. Error += true == glm::isinf(-1.0/Zero_d) ? 0 : 1;
  727. Error += true == glm::any(glm::isinf(glm::dvec2( 1.0/Zero_d))) ? 0 : 1;
  728. Error += true == glm::any(glm::isinf(glm::dvec2(-1.0/Zero_d))) ? 0 : 1;
  729. Error += true == glm::any(glm::isinf(glm::dvec3( 1.0/Zero_d))) ? 0 : 1;
  730. Error += true == glm::any(glm::isinf(glm::dvec3(-1.0/Zero_d))) ? 0 : 1;
  731. Error += true == glm::any(glm::isinf(glm::dvec4( 1.0/Zero_d))) ? 0 : 1;
  732. Error += true == glm::any(glm::isinf(glm::dvec4(-1.0/Zero_d))) ? 0 : 1;
  733. }
  734. {
  735. Error += true == glm::isinf( 1.0f/Zero_f) ? 0 : 1;
  736. Error += true == glm::isinf(-1.0f/Zero_f) ? 0 : 1;
  737. Error += true == glm::any(glm::isinf(glm::vec2( 1.0f/Zero_f))) ? 0 : 1;
  738. Error += true == glm::any(glm::isinf(glm::vec2(-1.0f/Zero_f))) ? 0 : 1;
  739. Error += true == glm::any(glm::isinf(glm::vec3( 1.0f/Zero_f))) ? 0 : 1;
  740. Error += true == glm::any(glm::isinf(glm::vec3(-1.0f/Zero_f))) ? 0 : 1;
  741. Error += true == glm::any(glm::isinf(glm::vec4( 1.0f/Zero_f))) ? 0 : 1;
  742. Error += true == glm::any(glm::isinf(glm::vec4(-1.0f/Zero_f))) ? 0 : 1;
  743. }
  744. return Error;
  745. }
  746. }//namespace isinf_
  747. namespace sign
  748. {
  749. template<typename genFIType>
  750. GLM_FUNC_QUALIFIER genFIType sign_if(genFIType x)
  751. {
  752. GLM_STATIC_ASSERT(
  753. std::numeric_limits<genFIType>::is_iec559 ||
  754. (std::numeric_limits<genFIType>::is_signed && std::numeric_limits<genFIType>::is_integer), "'sign' only accept signed inputs");
  755. genFIType result;
  756. if(x > genFIType(0))
  757. result = genFIType(1);
  758. else if(x < genFIType(0))
  759. result = genFIType(-1);
  760. else
  761. result = genFIType(0);
  762. return result;
  763. }
  764. #if GLM_COMPILER & GLM_COMPILER_CLANG
  765. # pragma clang diagnostic push
  766. # pragma clang diagnostic ignored "-Wsign-conversion"
  767. #endif
  768. template<typename genFIType>
  769. GLM_FUNC_QUALIFIER genFIType sign_alu1(genFIType x)
  770. {
  771. GLM_STATIC_ASSERT(
  772. std::numeric_limits<genFIType>::is_signed && std::numeric_limits<genFIType>::is_integer,
  773. "'sign' only accept integer inputs");
  774. return (x >> 31) | (static_cast<unsigned>(-x) >> 31);
  775. }
  776. #if GLM_COMPILER & GLM_COMPILER_CLANG
  777. # pragma clang diagnostic pop
  778. #endif
  779. GLM_FUNC_QUALIFIER int sign_alu2(int x)
  780. {
  781. GLM_STATIC_ASSERT(std::numeric_limits<int>::is_signed && std::numeric_limits<int>::is_integer, "'sign' only accept integer inputs");
  782. # if GLM_COMPILER & GLM_COMPILER_VC
  783. # pragma warning(push)
  784. # pragma warning(disable : 4146) //cast truncates constant value
  785. # endif
  786. return -(static_cast<unsigned>(x) >> 31) | (-static_cast<unsigned>(x) >> 31);
  787. # if GLM_COMPILER & GLM_COMPILER_VC
  788. # pragma warning(pop)
  789. # endif
  790. }
  791. template<typename genFIType>
  792. GLM_FUNC_QUALIFIER genFIType sign_sub(genFIType x)
  793. {
  794. GLM_STATIC_ASSERT(
  795. std::numeric_limits<genFIType>::is_signed && std::numeric_limits<genFIType>::is_integer,
  796. "'sign' only accept integer inputs");
  797. return (static_cast<unsigned>(-x) >> 31) - (static_cast<unsigned>(x) >> 31);
  798. }
  799. template<typename genFIType>
  800. GLM_FUNC_QUALIFIER genFIType sign_cmp(genFIType x)
  801. {
  802. GLM_STATIC_ASSERT(
  803. std::numeric_limits<genFIType>::is_signed && std::numeric_limits<genFIType>::is_integer,
  804. "'sign' only accept integer inputs");
  805. return (x > 0) - (x < 0);
  806. }
  807. template<typename genType>
  808. struct type
  809. {
  810. genType Value;
  811. genType Return;
  812. };
  813. static int test_int32()
  814. {
  815. type<glm::int32> const Data[] =
  816. {
  817. { std::numeric_limits<glm::int32>::max(), 1},
  818. { std::numeric_limits<glm::int32>::min(), -1},
  819. { 0, 0},
  820. { 1, 1},
  821. { 2, 1},
  822. { 3, 1},
  823. {-1,-1},
  824. {-2,-1},
  825. {-3,-1}
  826. };
  827. int Error = 0;
  828. for(std::size_t i = 0; i < sizeof(Data) / sizeof(type<glm::int32>); ++i)
  829. {
  830. glm::int32 Result = glm::sign(Data[i].Value);
  831. Error += Data[i].Return == Result ? 0 : 1;
  832. }
  833. for(std::size_t i = 0; i < sizeof(Data) / sizeof(type<glm::int32>); ++i)
  834. {
  835. glm::int32 Result = sign_cmp(Data[i].Value);
  836. Error += Data[i].Return == Result ? 0 : 1;
  837. }
  838. for(std::size_t i = 0; i < sizeof(Data) / sizeof(type<glm::int32>); ++i)
  839. {
  840. glm::int32 Result = sign_if(Data[i].Value);
  841. Error += Data[i].Return == Result ? 0 : 1;
  842. }
  843. for(std::size_t i = 0; i < sizeof(Data) / sizeof(type<glm::int32>); ++i)
  844. {
  845. glm::int32 Result = sign_alu1(Data[i].Value);
  846. Error += Data[i].Return == Result ? 0 : 1;
  847. }
  848. for(std::size_t i = 0; i < sizeof(Data) / sizeof(type<glm::int32>); ++i)
  849. {
  850. glm::int32 Result = sign_alu2(Data[i].Value);
  851. Error += Data[i].Return == Result ? 0 : 1;
  852. }
  853. return Error;
  854. }
  855. static int test_i32vec4()
  856. {
  857. type<glm::ivec4> const Data[] =
  858. {
  859. {glm::ivec4( 1), glm::ivec4( 1)},
  860. {glm::ivec4( 0), glm::ivec4( 0)},
  861. {glm::ivec4( 2), glm::ivec4( 1)},
  862. {glm::ivec4( 3), glm::ivec4( 1)},
  863. {glm::ivec4(-1), glm::ivec4(-1)},
  864. {glm::ivec4(-2), glm::ivec4(-1)},
  865. {glm::ivec4(-3), glm::ivec4(-1)}
  866. };
  867. int Error = 0;
  868. for(std::size_t i = 0; i < sizeof(Data) / sizeof(type<glm::ivec4>); ++i)
  869. {
  870. glm::ivec4 Result = glm::sign(Data[i].Value);
  871. Error += glm::all(glm::equal(Data[i].Return, Result)) ? 0 : 1;
  872. }
  873. return Error;
  874. }
  875. static int test_f32vec4()
  876. {
  877. type<glm::vec4> const Data[] =
  878. {
  879. {glm::vec4( 1), glm::vec4( 1)},
  880. {glm::vec4( 0), glm::vec4( 0)},
  881. {glm::vec4( 2), glm::vec4( 1)},
  882. {glm::vec4( 3), glm::vec4( 1)},
  883. {glm::vec4(-1), glm::vec4(-1)},
  884. {glm::vec4(-2), glm::vec4(-1)},
  885. {glm::vec4(-3), glm::vec4(-1)}
  886. };
  887. int Error = 0;
  888. for(std::size_t i = 0; i < sizeof(Data) / sizeof(type<glm::vec4>); ++i)
  889. {
  890. glm::vec4 Result = glm::sign(Data[i].Value);
  891. Error += glm::all(glm::equal(Data[i].Return, Result, glm::epsilon<float>())) ? 0 : 1;
  892. }
  893. return Error;
  894. }
  895. static int test()
  896. {
  897. int Error = 0;
  898. Error += test_int32();
  899. Error += test_i32vec4();
  900. Error += test_f32vec4();
  901. return Error;
  902. }
  903. static int perf_rand(std::size_t Samples)
  904. {
  905. int Error = 0;
  906. std::size_t const Count = Samples;
  907. std::vector<glm::int32> Input, Output;
  908. Input.resize(Count);
  909. Output.resize(Count);
  910. for(std::size_t i = 0; i < Count; ++i)
  911. Input[i] = static_cast<glm::int32>(glm::linearRand(-65536.f, 65536.f));
  912. std::clock_t Timestamp0 = std::clock();
  913. for(std::size_t i = 0; i < Count; ++i)
  914. Output[i] = sign_cmp(Input[i]);
  915. std::clock_t Timestamp1 = std::clock();
  916. for(std::size_t i = 0; i < Count; ++i)
  917. Output[i] = sign_if(Input[i]);
  918. std::clock_t Timestamp2 = std::clock();
  919. for(std::size_t i = 0; i < Count; ++i)
  920. Output[i] = sign_alu1(Input[i]);
  921. std::clock_t Timestamp3 = std::clock();
  922. for(std::size_t i = 0; i < Count; ++i)
  923. Output[i] = sign_alu2(Input[i]);
  924. std::clock_t Timestamp4 = std::clock();
  925. for(std::size_t i = 0; i < Count; ++i)
  926. Output[i] = sign_sub(Input[i]);
  927. std::clock_t Timestamp5 = std::clock();
  928. for(std::size_t i = 0; i < Count; ++i)
  929. Output[i] = glm::sign(Input[i]);
  930. std::clock_t Timestamp6 = std::clock();
  931. std::printf("sign_cmp(rand) Time %d clocks\n", static_cast<int>(Timestamp1 - Timestamp0));
  932. std::printf("sign_if(rand) Time %d clocks\n", static_cast<int>(Timestamp2 - Timestamp1));
  933. std::printf("sign_alu1(rand) Time %d clocks\n", static_cast<int>(Timestamp3 - Timestamp2));
  934. std::printf("sign_alu2(rand) Time %d clocks\n", static_cast<int>(Timestamp4 - Timestamp3));
  935. std::printf("sign_sub(rand) Time %d clocks\n", static_cast<int>(Timestamp5 - Timestamp4));
  936. std::printf("glm::sign(rand) Time %d clocks\n", static_cast<int>(Timestamp6 - Timestamp5));
  937. return Error;
  938. }
  939. static int perf_linear(std::size_t Samples)
  940. {
  941. int Error = 0;
  942. std::size_t const Count = Samples;
  943. std::vector<glm::int32> Input, Output;
  944. Input.resize(Count);
  945. Output.resize(Count);
  946. for(std::size_t i = 0; i < Count; ++i)
  947. Input[i] = static_cast<glm::int32>(i);
  948. std::clock_t Timestamp0 = std::clock();
  949. for(std::size_t i = 0; i < Count; ++i)
  950. Output[i] = sign_cmp(Input[i]);
  951. std::clock_t Timestamp1 = std::clock();
  952. for(std::size_t i = 0; i < Count; ++i)
  953. Output[i] = sign_if(Input[i]);
  954. std::clock_t Timestamp2 = std::clock();
  955. for(std::size_t i = 0; i < Count; ++i)
  956. Output[i] = sign_alu1(Input[i]);
  957. std::clock_t Timestamp3 = std::clock();
  958. for(std::size_t i = 0; i < Count; ++i)
  959. Output[i] = sign_alu2(Input[i]);
  960. std::clock_t Timestamp4 = std::clock();
  961. for(std::size_t i = 0; i < Count; ++i)
  962. Output[i] = sign_sub(Input[i]);
  963. std::clock_t Timestamp5 = std::clock();
  964. std::printf("sign_cmp(linear) Time %d clocks\n", static_cast<int>(Timestamp1 - Timestamp0));
  965. std::printf("sign_if(linear) Time %d clocks\n", static_cast<int>(Timestamp2 - Timestamp1));
  966. std::printf("sign_alu1(linear) Time %d clocks\n", static_cast<int>(Timestamp3 - Timestamp2));
  967. std::printf("sign_alu2(linear) Time %d clocks\n", static_cast<int>(Timestamp4 - Timestamp3));
  968. std::printf("sign_sub(linear) Time %d clocks\n", static_cast<int>(Timestamp5 - Timestamp4));
  969. return Error;
  970. }
  971. static int perf_linear_cal(std::size_t Samples)
  972. {
  973. int Error = 0;
  974. glm::int32 const Count = static_cast<glm::int32>(Samples);
  975. std::clock_t Timestamp0 = std::clock();
  976. glm::int32 Sum = 0;
  977. for(glm::int32 i = 1; i < Count; ++i)
  978. Sum += sign_cmp(i);
  979. std::clock_t Timestamp1 = std::clock();
  980. for(glm::int32 i = 1; i < Count; ++i)
  981. Sum += sign_if(i);
  982. std::clock_t Timestamp2 = std::clock();
  983. for(glm::int32 i = 1; i < Count; ++i)
  984. Sum += sign_alu1(i);
  985. std::clock_t Timestamp3 = std::clock();
  986. for(glm::int32 i = 1; i < Count; ++i)
  987. Sum += sign_alu2(i);
  988. std::clock_t Timestamp4 = std::clock();
  989. for(glm::int32 i = 1; i < Count; ++i)
  990. Sum += sign_sub(i);
  991. std::clock_t Timestamp5 = std::clock();
  992. std::printf("Sum %d\n", static_cast<int>(Sum));
  993. std::printf("sign_cmp(linear_cal) Time %d clocks\n", static_cast<int>(Timestamp1 - Timestamp0));
  994. std::printf("sign_if(linear_cal) Time %d clocks\n", static_cast<int>(Timestamp2 - Timestamp1));
  995. std::printf("sign_alu1(linear_cal) Time %d clocks\n", static_cast<int>(Timestamp3 - Timestamp2));
  996. std::printf("sign_alu2(linear_cal) Time %d clocks\n", static_cast<int>(Timestamp4 - Timestamp3));
  997. std::printf("sign_sub(linear_cal) Time %d clocks\n", static_cast<int>(Timestamp5 - Timestamp4));
  998. return Error;
  999. }
  1000. static int perf(std::size_t Samples)
  1001. {
  1002. int Error(0);
  1003. Error += perf_linear_cal(Samples);
  1004. Error += perf_linear(Samples);
  1005. Error += perf_rand(Samples);
  1006. return Error;
  1007. }
  1008. }//namespace sign
  1009. namespace frexp_
  1010. {
  1011. static int test()
  1012. {
  1013. int Error = 0;
  1014. {
  1015. glm::vec1 const x(1024);
  1016. glm::ivec1 exp;
  1017. glm::vec1 A = glm::frexp(x, exp);
  1018. Error += glm::all(glm::equal(A, glm::vec1(0.5), glm::epsilon<float>())) ? 0 : 1;
  1019. Error += glm::all(glm::equal(exp, glm::ivec1(11))) ? 0 : 1;
  1020. }
  1021. {
  1022. glm::vec2 const x(1024, 0.24);
  1023. glm::ivec2 exp;
  1024. glm::vec2 A = glm::frexp(x, exp);
  1025. Error += glm::all(glm::equal(A, glm::vec2(0.5, 0.96), glm::epsilon<float>())) ? 0 : 1;
  1026. Error += glm::all(glm::equal(exp, glm::ivec2(11, -2))) ? 0 : 1;
  1027. }
  1028. {
  1029. glm::vec3 const x(1024, 0.24, 0);
  1030. glm::ivec3 exp;
  1031. glm::vec3 A = glm::frexp(x, exp);
  1032. Error += glm::all(glm::equal(A, glm::vec3(0.5, 0.96, 0.0), glm::epsilon<float>())) ? 0 : 1;
  1033. Error += glm::all(glm::equal(exp, glm::ivec3(11, -2, 0))) ? 0 : 1;
  1034. }
  1035. {
  1036. glm::vec4 const x(1024, 0.24, 0, -1.33);
  1037. glm::ivec4 exp;
  1038. glm::vec4 A = glm::frexp(x, exp);
  1039. Error += glm::all(glm::equal(A, glm::vec4(0.5, 0.96, 0.0, -0.665), glm::epsilon<float>())) ? 0 : 1;
  1040. Error += glm::all(glm::equal(exp, glm::ivec4(11, -2, 0, 1))) ? 0 : 1;
  1041. }
  1042. return Error;
  1043. }
  1044. }//namespace frexp_
  1045. namespace ldexp_
  1046. {
  1047. static int test()
  1048. {
  1049. int Error = 0;
  1050. {
  1051. glm::vec1 A = glm::vec1(0.5);
  1052. glm::ivec1 exp = glm::ivec1(11);
  1053. glm::vec1 x = glm::ldexp(A, exp);
  1054. Error += glm::all(glm::equal(x, glm::vec1(1024),0.00001f)) ? 0 : 1;
  1055. }
  1056. {
  1057. glm::vec2 A = glm::vec2(0.5, 0.96);
  1058. glm::ivec2 exp = glm::ivec2(11, -2);
  1059. glm::vec2 x = glm::ldexp(A, exp);
  1060. Error += glm::all(glm::equal(x, glm::vec2(1024, .24),0.00001f)) ? 0 : 1;
  1061. }
  1062. {
  1063. glm::vec3 A = glm::vec3(0.5, 0.96, 0.0);
  1064. glm::ivec3 exp = glm::ivec3(11, -2, 0);
  1065. glm::vec3 x = glm::ldexp(A, exp);
  1066. Error += glm::all(glm::equal(x, glm::vec3(1024, .24, 0),0.00001f)) ? 0 : 1;
  1067. }
  1068. {
  1069. glm::vec4 A = glm::vec4(0.5, 0.96, 0.0, -0.665);
  1070. glm::ivec4 exp = glm::ivec4(11, -2, 0, 1);
  1071. glm::vec4 x = glm::ldexp(A, exp);
  1072. Error += glm::all(glm::equal(x, glm::vec4(1024, .24, 0, -1.33),0.00001f)) ? 0 : 1;
  1073. }
  1074. return Error;
  1075. }
  1076. }//namespace ldexp_
  1077. static int test_constexpr()
  1078. {
  1079. #if GLM_HAS_CONSTEXPR
  1080. static_assert(glm::abs(1.0f) > 0.0f, "GLM: Failed constexpr");
  1081. constexpr glm::vec1 const A = glm::abs(glm::vec1(1.0f));
  1082. constexpr glm::vec2 const B = glm::abs(glm::vec2(1.0f));
  1083. constexpr glm::vec3 const C = glm::abs(glm::vec3(1.0f));
  1084. constexpr glm::vec4 const D = glm::abs(glm::vec4(1.0f));
  1085. static_assert(glm::all(glm::equal(A, glm::vec1(1.0f), glm::epsilon<float>())), "GLM: Failed constexpr");
  1086. static_assert(glm::all(glm::equal(B, glm::vec2(1.0f), glm::epsilon<float>())), "GLM: Failed constexpr");
  1087. static_assert(glm::all(glm::equal(C, glm::vec3(1.0f), glm::epsilon<float>())), "GLM: Failed constexpr");
  1088. static_assert(glm::all(glm::equal(D, glm::vec4(1.0f), glm::epsilon<float>())), "GLM: Failed constexpr");
  1089. #endif // GLM_HAS_CONSTEXPR
  1090. return 0;
  1091. }
  1092. int main()
  1093. {
  1094. int Error = 0;
  1095. Error += test_constexpr();
  1096. Error += sign::test();
  1097. Error += floor_::test();
  1098. Error += mod_::test();
  1099. Error += modf_::test();
  1100. Error += floatBitsToInt::test();
  1101. Error += floatBitsToUint::test();
  1102. Error += mix_::test();
  1103. Error += step_::test();
  1104. Error += max_::test();
  1105. Error += min_::test();
  1106. Error += clamp_::test();
  1107. Error += round_::test();
  1108. Error += roundEven::test();
  1109. Error += isnan_::test();
  1110. Error += isinf_::test();
  1111. Error += frexp_::test();
  1112. Error += ldexp_::test();
  1113. # ifdef NDEBUG
  1114. std::size_t Samples = 1000;
  1115. # else
  1116. std::size_t Samples = 1;
  1117. # endif
  1118. Error += sign::perf(Samples);
  1119. Error += min_::perf(Samples);
  1120. return Error;
  1121. }
  1122. #if(GLM_COMPILER & GLM_COMPILER_VC)
  1123. # pragma warning(pop)
  1124. #endif