1
2 //
3 // This source file is part of appleseed.
4 // Visit https://appleseedhq.net/ for additional information and resources.
5 //
6 // This software is released under the MIT license.
7 //
8 // Copyright (c) 2010-2013 Francois Beaune, Jupiter Jazz Limited
9 // Copyright (c) 2014-2018 Francois Beaune, The appleseedhq Organization
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining a copy
12 // of this software and associated documentation files (the "Software"), to deal
13 // in the Software without restriction, including without limitation the rights
14 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 // copies of the Software, and to permit persons to whom the Software is
16 // furnished to do so, subject to the following conditions:
17 //
18 // The above copyright notice and this permission notice shall be included in
19 // all copies or substantial portions of the Software.
20 //
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 // THE SOFTWARE.
28 //
29
30 #pragma once
31
32 // appleseed.foundation headers.
33 #include "foundation/math/scalar.h"
34 #include "foundation/platform/types.h"
35
36 // Standard headers.
37 #include <cassert>
38 #include <cstddef>
39 #include <limits>
40
41 namespace foundation
42 {
43
44 //
45 // Distribution adapters.
46 //
47 // Interesting reference:
48 //
49 // Uniform random floats: How to generate a double-precision floating-point number
50 // in [0, 1] uniformly at random given a uniform random source of bits.
51 // http://mumble.net/~campbell/tmp/random_real.c
52 //
53
54 // Return a random number in the integer interval [0, 0x7FFFFFFF].
55 template <typename RNG> int32 rand_int31(RNG& rng);
56
57 // Return a random number in the integer interval [min, max].
58 template <typename RNG> int32 rand_int1(RNG& rng, const int32 min, const int32 max);
59
60 // Return a random number in the real interval [0,1].
61 template <typename RNG> float rand_float1(RNG& rng);
62 template <typename RNG> double rand_double1(RNG& rng);
63 template <typename T, typename RNG> T rand1(RNG& rng);
64
65 // Return a random number in the real interval [min, max].
66 template <typename RNG> float rand_float1(RNG& rng, const float min, const float max);
67 template <typename RNG> double rand_double1(RNG& rng, const double min, const double max);
68 template <typename RNG> float rand1(RNG& rng, const float min, const float max);
69 template <typename RNG> double rand1(RNG& rng, const double min, const double max);
70
71 // Return a random number in the real interval [0,1).
72 template <typename RNG> float rand_float2(RNG& rng);
73 template <typename RNG> double rand_double2(RNG& rng);
74 template <typename T, typename RNG> T rand2(RNG& rng);
75
76 // Return a random number in the real interval [min, max).
77 template <typename RNG> float rand_float2(RNG& rng, const float min, const float max);
78 template <typename RNG> double rand_double2(RNG& rng, const double min, const double max);
79 template <typename RNG> float rand2(RNG& rng, const float min, const float max);
80 template <typename RNG> double rand2(RNG& rng, const double min, const double max);
81
82 // Return a random number in the real interval (0,1).
83 template <typename RNG> float rand_float3(RNG& rng);
84 template <typename RNG> double rand_double3(RNG& rng);
85 template <typename T, typename RNG> T rand3(RNG& rng);
86
87 // Return a random number in the real interval (min, max).
88 template <typename RNG> float rand_float3(RNG& rng, const float min, const float max);
89 template <typename RNG> double rand_double3(RNG& rng, const double min, const double max);
90 template <typename RNG> float rand3(RNG& rng, const float min, const float max);
91 template <typename RNG> double rand3(RNG& rng, const double min, const double max);
92
93 // Return a random number in the real interval [0,1) with 53-bit resolution.
94 template <typename RNG> double rand_double2_res53(RNG& rng);
95
96
97 //
98 // Random vectors.
99 //
100
101 // Return a random vector whose components are in the real interval [0,1].
102 template <typename VectorType, typename RNG>
103 VectorType rand_vector1(RNG& rng);
104
105 // Return a random vector whose components are in the real interval [0,1).
106 template <typename VectorType, typename RNG>
107 VectorType rand_vector2(RNG& rng);
108
109 // Return a random vector whose components are in the real interval (0,1).
110 template <typename VectorType, typename RNG>
111 VectorType rand_vector3(RNG& rng);
112
113
114 //
115 // Implementation.
116 //
117
118 template <typename RNG>
rand_int31(RNG & rng)119 inline int32 rand_int31(RNG& rng)
120 {
121 const int32 result = static_cast<int32>(rng.rand_uint32() >> 1);
122
123 assert(result >= 0);
124 assert(result <= 0x7FFFFFFFu);
125
126 return result;
127 }
128
129 template <typename RNG>
rand_int1(RNG & rng,const int32 min,const int32 max)130 inline int32 rand_int1(RNG& rng, const int32 min, const int32 max)
131 {
132 assert(min <= max);
133
134 const double x =
135 rand_double2(
136 rng,
137 static_cast<double>(min),
138 static_cast<double>(max) + 1);
139
140 const int32 result = truncate<int32>(x);
141
142 assert(result >= min);
143 assert(result <= max);
144
145 return result;
146 }
147
148 template <typename RNG>
rand_float1(RNG & rng)149 inline float rand_float1(RNG& rng)
150 {
151 const float result = rng.rand_uint32() * (1.0f / 0xFFFFFFFFu);
152
153 assert(result >= 0.0f);
154 assert(result <= 1.0f);
155
156 return result;
157 }
158
159 template <typename RNG>
rand_double1(RNG & rng)160 inline double rand_double1(RNG& rng)
161 {
162 const double result = rng.rand_uint32() * (1.0 / 0xFFFFFFFFu);
163
164 assert(result >= 0.0);
165 assert(result <= 1.0);
166
167 return result;
168 }
169
170 template <typename T, typename RNG>
171 struct Rand1Helper;
172
173 template <typename RNG>
174 struct Rand1Helper<float, RNG>
175 {
176 float operator()(RNG& rng) { return rand_float1(rng); }
177 };
178
179 template <typename RNG>
180 struct Rand1Helper<double, RNG>
181 {
182 double operator()(RNG& rng) { return rand_double1(rng); }
183 };
184
185 template <typename T, typename RNG>
186 inline T rand1(RNG& rng)
187 {
188 Rand1Helper<T, RNG> helper;
189 return helper(rng);
190 }
191
192 template <typename RNG>
193 inline float rand_float1(RNG& rng, const float min, const float max)
194 {
195 assert(min <= max);
196
197 const float result = lerp(min, max, rand_float1(rng));
198
199 assert(result >= min);
200 assert(result <= max);
201
202 return result;
203 }
204
205 template <typename RNG>
206 inline double rand_double1(RNG& rng, const double min, const double max)
207 {
208 assert(min <= max);
209
210 const double result = lerp(min, max, rand_double1(rng));
211
212 assert(result >= min);
213 assert(result <= max);
214
215 return result;
216 }
217
218 template <typename RNG>
219 inline float rand1(RNG& rng, const float min, const float max)
220 {
221 return rand_float1(rng, min, max);
222 }
223
224 template <typename RNG>
225 inline double rand1(RNG& rng, const double min, const double max)
226 {
227 return rand_double1(rng, min, max);
228 }
229
230 template <typename RNG>
231 inline float rand_float2(RNG& rng)
232 {
233 const float result = rng.rand_uint32() * Rcp2Pow32<float>();
234
235 assert(result >= 0.0f);
236 assert(result < 1.0f);
237
238 return result;
239 }
240
241 template <typename RNG>
242 inline double rand_double2(RNG& rng)
243 {
244 const double result = rng.rand_uint32() * Rcp2Pow32<double>();
245
246 assert(result >= 0.0);
247 assert(result < 1.0);
248
249 return result;
250 }
251
252 template <typename T, typename RNG>
253 struct Rand2Helper;
254
255 template <typename RNG>
256 struct Rand2Helper<float, RNG>
257 {
258 float operator()(RNG& rng) { return rand_float2(rng); }
259 };
260
261 template <typename RNG>
262 struct Rand2Helper<double, RNG>
263 {
264 double operator()(RNG& rng) { return rand_double2(rng); }
265 };
266
267 template <typename T, typename RNG>
268 inline T rand2(RNG& rng)
269 {
270 Rand2Helper<T, RNG> helper;
271 return helper(rng);
272 }
273
274 template <typename RNG>
275 inline float rand_float2(RNG& rng, const float min, const float max)
276 {
277 assert(min <= max);
278
279 const float result = lerp(min, max, rand_float2(rng));
280
281 assert(result >= min);
282 assert(result < max);
283
284 return result;
285 }
286
287 template <typename RNG>
288 inline double rand_double2(RNG& rng, const double min, const double max)
289 {
290 assert(min <= max);
291
292 const double result = lerp(min, max, rand_double2(rng));
293
294 assert(result >= min);
295 assert(result < max);
296
297 return result;
298 }
299
300 template <typename RNG>
301 inline float rand2(RNG& rng, const float min, const float max)
302 {
303 return rand_float2(rng, min, max);
304 }
305
306 template <typename RNG>
307 inline double rand2(RNG& rng, const double min, const double max)
308 {
309 return rand_double2(rng, min, max);
310 }
311
312 template <typename RNG>
313 inline float rand_float3(RNG& rng)
314 {
315 const float result = rng.rand_uint32() * 2.3283060e-010f + std::numeric_limits<float>::epsilon();
316
317 assert(result > 0.0f);
318 assert(result < 1.0f);
319
320 return result;
321 }
322
323 template <typename RNG>
324 inline double rand_double3(RNG& rng)
325 {
326 const double result = rng.rand_uint32() * 2.3283064370807963e-10 + std::numeric_limits<double>::epsilon();
327
328 assert(result > 0.0);
329 assert(result < 1.0);
330
331 return result;
332 }
333
334 template <typename T, typename RNG>
335 struct Rand3Helper;
336
337 template <typename RNG>
338 struct Rand3Helper<float, RNG>
339 {
340 float operator()(RNG& rng) { return rand_float3(rng); }
341 };
342
343 template <typename RNG>
344 struct Rand3Helper<double, RNG>
345 {
346 double operator()(RNG& rng) { return rand_double3(rng); }
347 };
348
349 template <typename T, typename RNG>
350 inline T rand3(RNG& rng)
351 {
352 Rand3Helper<T, RNG> helper;
353 return helper(rng);
354 }
355
356 template <typename RNG>
357 inline float rand_float3(RNG& rng, const float min, const float max)
358 {
359 assert(min <= max);
360
361 const float result = lerp(min, max, rand_float3(rng));
362
363 assert(result > min);
364 assert(result < max);
365
366 return result;
367 }
368
369 template <typename RNG>
370 inline double rand_double3(RNG& rng, const double min, const double max)
371 {
372 assert(min <= max);
373
374 const double result = lerp(min, max, rand_double3(rng));
375
376 assert(result > min);
377 assert(result < max);
378
379 return result;
380 }
381
382 template <typename RNG>
383 inline float rand3(RNG& rng, const float min, const float max)
384 {
385 return rand_float3(rng, min, max);
386 }
387
388 template <typename RNG>
389 inline double rand3(RNG& rng, const double min, const double max)
390 {
391 return rand_double3(rng, min, max);
392 }
393
394 template <typename RNG>
395 inline double rand_double2_res53(RNG& rng)
396 {
397 const uint32 a = rng.rand_uint32() >> 5;
398 const uint32 b = rng.rand_uint32() >> 6;
399
400 const double result = (a * 67108864.0 + b) * (1.0 / 9007199254740992.0);
401
402 assert(result >= 0.0);
403 assert(result < 1.0);
404
405 return result;
406 }
407
408 template <typename VectorType, typename RNG>
409 inline VectorType rand_vector1(RNG& rng)
410 {
411 VectorType v;
412
413 for (size_t i = 0; i < VectorType::Dimension; ++i)
414 v[i] = rand1<typename VectorType::ValueType>(rng);
415
416 return v;
417 }
418
419 template <typename VectorType, typename RNG>
420 inline VectorType rand_vector2(RNG& rng)
421 {
422 VectorType v;
423
424 for (size_t i = 0; i < VectorType::Dimension; ++i)
425 v[i] = rand2<typename VectorType::ValueType>(rng);
426
427 return v;
428 }
429
430 template <typename VectorType, typename RNG>
431 inline VectorType rand_vector3(RNG& rng)
432 {
433 VectorType v;
434
435 for (size_t i = 0; i < VectorType::Dimension; ++i)
436 v[i] = rand3<typename VectorType::ValueType>(rng);
437
438 return v;
439 }
440
441 } // namespace foundation
442