gtc_random.cpp 8.9 KB

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