gtc_random.cpp 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. #ifndef GLM_FORCE_PURE
  2. #define GLM_FORCE_DEFAULT_ALIGNED_GENTYPES
  3. #endif
  4. #include <glm/gtc/random.hpp>
  5. #include <glm/gtc/epsilon.hpp>
  6. #include <glm/gtc/type_precision.hpp>
  7. #if GLM_LANG & GLM_LANG_CXX0X_FLAG
  8. # include <array>
  9. #endif
  10. std::size_t const TestSamples = 10000;
  11. static int test_linearRand()
  12. {
  13. int Error = 0;
  14. glm::int32 const Min = 16;
  15. glm::int32 const Max = 32;
  16. {
  17. glm::u8vec2 AMin(std::numeric_limits<glm::u8>::max());
  18. glm::u8vec2 AMax(std::numeric_limits<glm::u8>::min());
  19. {
  20. for(std::size_t i = 0; i < TestSamples; ++i)
  21. {
  22. glm::u8vec2 A = glm::linearRand(glm::u8vec2(Min), glm::u8vec2(Max));
  23. AMin = glm::min(AMin, A);
  24. AMax = glm::max(AMax, A);
  25. if(!glm::all(glm::lessThanEqual(A, glm::u8vec2(Max))))
  26. ++Error;
  27. if(!glm::all(glm::greaterThanEqual(A, glm::u8vec2(Min))))
  28. ++Error;
  29. assert(!Error);
  30. }
  31. Error += glm::all(glm::equal(AMin, glm::u8vec2(Min))) ? 0 : 1;
  32. Error += glm::all(glm::equal(AMax, glm::u8vec2(Max))) ? 0 : 1;
  33. assert(!Error);
  34. }
  35. glm::u16vec2 BMin(std::numeric_limits<glm::u16>::max());
  36. glm::u16vec2 BMax(std::numeric_limits<glm::u16>::min());
  37. {
  38. for(std::size_t i = 0; i < TestSamples; ++i)
  39. {
  40. glm::u16vec2 B = glm::linearRand(glm::u16vec2(Min), glm::u16vec2(Max));
  41. BMin = glm::min(BMin, B);
  42. BMax = glm::max(BMax, B);
  43. if(!glm::all(glm::lessThanEqual(B, glm::u16vec2(Max))))
  44. ++Error;
  45. if(!glm::all(glm::greaterThanEqual(B, glm::u16vec2(Min))))
  46. ++Error;
  47. assert(!Error);
  48. }
  49. Error += glm::all(glm::equal(BMin, glm::u16vec2(Min))) ? 0 : 1;
  50. Error += glm::all(glm::equal(BMax, glm::u16vec2(Max))) ? 0 : 1;
  51. assert(!Error);
  52. }
  53. glm::u32vec2 CMin(std::numeric_limits<glm::u32>::max());
  54. glm::u32vec2 CMax(std::numeric_limits<glm::u32>::min());
  55. {
  56. for(std::size_t i = 0; i < TestSamples; ++i)
  57. {
  58. glm::u32vec2 C = glm::linearRand(glm::u32vec2(Min), glm::u32vec2(Max));
  59. CMin = glm::min(CMin, C);
  60. CMax = glm::max(CMax, C);
  61. if(!glm::all(glm::lessThanEqual(C, glm::u32vec2(Max))))
  62. ++Error;
  63. if(!glm::all(glm::greaterThanEqual(C, glm::u32vec2(Min))))
  64. ++Error;
  65. assert(!Error);
  66. }
  67. Error += glm::all(glm::equal(CMin, glm::u32vec2(Min))) ? 0 : 1;
  68. Error += glm::all(glm::equal(CMax, glm::u32vec2(Max))) ? 0 : 1;
  69. assert(!Error);
  70. }
  71. glm::u64vec2 DMin(std::numeric_limits<glm::u64>::max());
  72. glm::u64vec2 DMax(std::numeric_limits<glm::u64>::min());
  73. {
  74. for(std::size_t i = 0; i < TestSamples; ++i)
  75. {
  76. glm::u64vec2 D = glm::linearRand(glm::u64vec2(Min), glm::u64vec2(Max));
  77. DMin = glm::min(DMin, D);
  78. DMax = glm::max(DMax, D);
  79. if(!glm::all(glm::lessThanEqual(D, glm::u64vec2(Max))))
  80. ++Error;
  81. if(!glm::all(glm::greaterThanEqual(D, glm::u64vec2(Min))))
  82. ++Error;
  83. assert(!Error);
  84. }
  85. Error += glm::all(glm::equal(DMin, glm::u64vec2(Min))) ? 0 : 1;
  86. Error += glm::all(glm::equal(DMax, glm::u64vec2(Max))) ? 0 : 1;
  87. assert(!Error);
  88. }
  89. }
  90. {
  91. glm::i8vec2 AMin(std::numeric_limits<glm::i8>::max());
  92. glm::i8vec2 AMax(std::numeric_limits<glm::i8>::min());
  93. {
  94. for(std::size_t i = 0; i < TestSamples; ++i)
  95. {
  96. glm::i8vec2 A = glm::linearRand(glm::i8vec2(Min), glm::i8vec2(Max));
  97. AMin = glm::min(AMin, A);
  98. AMax = glm::max(AMax, A);
  99. if(!glm::all(glm::lessThanEqual(A, glm::i8vec2(Max))))
  100. ++Error;
  101. if(!glm::all(glm::greaterThanEqual(A, glm::i8vec2(Min))))
  102. ++Error;
  103. assert(!Error);
  104. }
  105. Error += glm::all(glm::equal(AMin, glm::i8vec2(Min))) ? 0 : 1;
  106. Error += glm::all(glm::equal(AMax, glm::i8vec2(Max))) ? 0 : 1;
  107. assert(!Error);
  108. }
  109. glm::i16vec2 BMin(std::numeric_limits<glm::i16>::max());
  110. glm::i16vec2 BMax(std::numeric_limits<glm::i16>::min());
  111. {
  112. for(std::size_t i = 0; i < TestSamples; ++i)
  113. {
  114. glm::i16vec2 B = glm::linearRand(glm::i16vec2(Min), glm::i16vec2(Max));
  115. BMin = glm::min(BMin, B);
  116. BMax = glm::max(BMax, B);
  117. if(!glm::all(glm::lessThanEqual(B, glm::i16vec2(Max))))
  118. ++Error;
  119. if(!glm::all(glm::greaterThanEqual(B, glm::i16vec2(Min))))
  120. ++Error;
  121. assert(!Error);
  122. }
  123. Error += glm::all(glm::equal(BMin, glm::i16vec2(Min))) ? 0 : 1;
  124. Error += glm::all(glm::equal(BMax, glm::i16vec2(Max))) ? 0 : 1;
  125. assert(!Error);
  126. }
  127. glm::i32vec2 CMin(std::numeric_limits<glm::i32>::max());
  128. glm::i32vec2 CMax(std::numeric_limits<glm::i32>::min());
  129. {
  130. for(std::size_t i = 0; i < TestSamples; ++i)
  131. {
  132. glm::i32vec2 C = glm::linearRand(glm::i32vec2(Min), glm::i32vec2(Max));
  133. CMin = glm::min(CMin, C);
  134. CMax = glm::max(CMax, C);
  135. if(!glm::all(glm::lessThanEqual(C, glm::i32vec2(Max))))
  136. ++Error;
  137. if(!glm::all(glm::greaterThanEqual(C, glm::i32vec2(Min))))
  138. ++Error;
  139. assert(!Error);
  140. }
  141. Error += glm::all(glm::equal(CMin, glm::i32vec2(Min))) ? 0 : 1;
  142. Error += glm::all(glm::equal(CMax, glm::i32vec2(Max))) ? 0 : 1;
  143. assert(!Error);
  144. }
  145. glm::i64vec2 DMin(std::numeric_limits<glm::i64>::max());
  146. glm::i64vec2 DMax(std::numeric_limits<glm::i64>::min());
  147. {
  148. for(std::size_t i = 0; i < TestSamples; ++i)
  149. {
  150. glm::i64vec2 D = glm::linearRand(glm::i64vec2(Min), glm::i64vec2(Max));
  151. DMin = glm::min(DMin, D);
  152. DMax = glm::max(DMax, D);
  153. if(!glm::all(glm::lessThanEqual(D, glm::i64vec2(Max))))
  154. ++Error;
  155. if(!glm::all(glm::greaterThanEqual(D, glm::i64vec2(Min))))
  156. ++Error;
  157. assert(!Error);
  158. }
  159. Error += glm::all(glm::equal(DMin, glm::i64vec2(Min))) ? 0 : 1;
  160. Error += glm::all(glm::equal(DMax, glm::i64vec2(Max))) ? 0 : 1;
  161. assert(!Error);
  162. }
  163. }
  164. for(std::size_t i = 0; i < TestSamples; ++i)
  165. {
  166. glm::f32vec2 const A(glm::linearRand(glm::f32vec2(static_cast<float>(Min)), glm::f32vec2(static_cast<float>(Max))));
  167. if(!glm::all(glm::lessThanEqual(A, glm::f32vec2(static_cast<float>(Max)))))
  168. ++Error;
  169. if(!glm::all(glm::greaterThanEqual(A, glm::f32vec2(static_cast<float>(Min)))))
  170. ++Error;
  171. glm::f64vec2 const B(glm::linearRand(glm::f64vec2(Min), glm::f64vec2(Max)));
  172. if(!glm::all(glm::lessThanEqual(B, glm::f64vec2(Max))))
  173. ++Error;
  174. if(!glm::all(glm::greaterThanEqual(B, glm::f64vec2(Min))))
  175. ++Error;
  176. assert(!Error);
  177. }
  178. {
  179. float ResultFloat = 0.0f;
  180. double ResultDouble = 0.0;
  181. for(std::size_t i = 0; i < TestSamples; ++i)
  182. {
  183. ResultFloat += glm::linearRand(-1.0f, 1.0f);
  184. ResultDouble += glm::linearRand(-1.0, 1.0);
  185. }
  186. Error += glm::epsilonEqual(ResultFloat, 0.0f, 0.0001f);
  187. Error += glm::epsilonEqual(ResultDouble, 0.0, 0.0001);
  188. assert(!Error);
  189. }
  190. return Error;
  191. }
  192. static int test_circularRand()
  193. {
  194. int Error = 0;
  195. {
  196. std::size_t Max = TestSamples;
  197. float ResultFloat = 0.0f;
  198. double ResultDouble = 0.0;
  199. double Radius = 2.0;
  200. for(std::size_t i = 0; i < Max; ++i)
  201. {
  202. ResultFloat += glm::length(glm::circularRand(1.0f));
  203. ResultDouble += glm::length(glm::circularRand(Radius));
  204. }
  205. Error += glm::epsilonEqual(ResultFloat, float(Max), 0.01f) ? 0 : 1;
  206. Error += glm::epsilonEqual(ResultDouble, double(Max) * double(Radius), 0.01) ? 0 : 1;
  207. assert(!Error);
  208. }
  209. return Error;
  210. }
  211. static int test_sphericalRand()
  212. {
  213. int Error = 0;
  214. {
  215. std::size_t Max = TestSamples;
  216. float ResultFloatA = 0.0f;
  217. float ResultFloatB = 0.0f;
  218. float ResultFloatC = 0.0f;
  219. double ResultDoubleA = 0.0;
  220. double ResultDoubleB = 0.0;
  221. double ResultDoubleC = 0.0;
  222. for(std::size_t i = 0; i < Max; ++i)
  223. {
  224. ResultFloatA += glm::length(glm::sphericalRand(1.0f));
  225. ResultDoubleA += glm::length(glm::sphericalRand(1.0));
  226. ResultFloatB += glm::length(glm::sphericalRand(2.0f));
  227. ResultDoubleB += glm::length(glm::sphericalRand(2.0));
  228. ResultFloatC += glm::length(glm::sphericalRand(3.0f));
  229. ResultDoubleC += glm::length(glm::sphericalRand(3.0));
  230. }
  231. Error += glm::epsilonEqual(ResultFloatA, float(Max), 0.01f) ? 0 : 1;
  232. Error += glm::epsilonEqual(ResultDoubleA, double(Max), 0.0001) ? 0 : 1;
  233. Error += glm::epsilonEqual(ResultFloatB, float(Max * 2), 0.01f) ? 0 : 1;
  234. Error += glm::epsilonEqual(ResultDoubleB, double(Max * 2), 0.0001) ? 0 : 1;
  235. Error += glm::epsilonEqual(ResultFloatC, float(Max * 3), 0.01f) ? 0 : 1;
  236. Error += glm::epsilonEqual(ResultDoubleC, double(Max * 3), 0.01) ? 0 : 1;
  237. assert(!Error);
  238. }
  239. return Error;
  240. }
  241. static int test_diskRand()
  242. {
  243. int Error = 0;
  244. {
  245. float ResultFloat = 0.0f;
  246. double ResultDouble = 0.0;
  247. for(std::size_t i = 0; i < TestSamples; ++i)
  248. {
  249. ResultFloat += glm::length(glm::diskRand(2.0f));
  250. ResultDouble += glm::length(glm::diskRand(2.0));
  251. }
  252. Error += ResultFloat < float(TestSamples) * 2.f ? 0 : 1;
  253. Error += ResultDouble < double(TestSamples) * 2.0 ? 0 : 1;
  254. assert(!Error);
  255. }
  256. return Error;
  257. }
  258. static int test_ballRand()
  259. {
  260. int Error = 0;
  261. {
  262. float ResultFloat = 0.0f;
  263. double ResultDouble = 0.0;
  264. for(std::size_t i = 0; i < TestSamples; ++i)
  265. {
  266. ResultFloat += glm::length(glm::ballRand(2.0f));
  267. ResultDouble += glm::length(glm::ballRand(2.0));
  268. }
  269. Error += ResultFloat < float(TestSamples) * 2.f ? 0 : 1;
  270. Error += ResultDouble < double(TestSamples) * 2.0 ? 0 : 1;
  271. assert(!Error);
  272. }
  273. return Error;
  274. }
  275. /*
  276. #if(GLM_LANG & GLM_LANG_CXX0X_FLAG)
  277. int test_grid()
  278. {
  279. int Error = 0;
  280. typedef std::array<int, 8> colors;
  281. typedef std::array<int, 8 * 8> grid;
  282. grid Grid;
  283. colors Colors;
  284. grid GridBest;
  285. colors ColorsBest;
  286. while(true)
  287. {
  288. for(std::size_t i = 0; i < Grid.size(); ++i)
  289. Grid[i] = int(glm::linearRand(0.0, 8.0 * 8.0 * 8.0 - 1.0) / 64.0);
  290. for(std::size_t i = 0; i < Grid.size(); ++i)
  291. ++Colors[Grid[i]];
  292. bool Exit = true;
  293. for(std::size_t i = 0; i < Colors.size(); ++i)
  294. {
  295. if(Colors[i] == 8)
  296. continue;
  297. Exit = false;
  298. break;
  299. }
  300. if(Exit == true)
  301. break;
  302. }
  303. return Error;
  304. }
  305. #endif
  306. */
  307. int main()
  308. {
  309. int Error = 0;
  310. Error += test_linearRand();
  311. Error += test_circularRand();
  312. Error += test_sphericalRand();
  313. Error += test_diskRand();
  314. Error += test_ballRand();
  315. /*
  316. #if(GLM_LANG & GLM_LANG_CXX0X_FLAG)
  317. Error += test_grid();
  318. #endif
  319. */
  320. return Error;
  321. }