2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19 * All rights reserved.
21 * The Original Code is: all of this file.
23 * Contributor(s): none yet.
25 * ***** END GPL LICENSE BLOCK *****
28 /** \file blender/blenlib/intern/rand.c
38 #include "MEM_guardedalloc.h"
40 #include "BLI_threads.h"
44 /* defines BLI_INLINE */
45 #include "BLI_compiler_compat.h"
47 #include "BLI_sys_types.h"
48 #include "BLI_strict_flags.h"
50 #define MULTIPLIER 0x5DEECE66Dll
51 #define MASK 0x0000FFFFFFFFFFFFll
55 #define LOWSEED 0x330E
57 extern unsigned char hash[]; // noise.c
60 * Random Number Generator.
66 RNG *BLI_rng_new(unsigned int seed)
68 RNG *rng = MEM_mallocN(sizeof(*rng), "rng");
70 BLI_rng_seed(rng, seed);
76 * A version of #BLI_rng_new that hashes the seed.
78 RNG *BLI_rng_new_srandom(unsigned int seed)
80 RNG *rng = MEM_mallocN(sizeof(*rng), "rng");
82 BLI_rng_srandom(rng, seed);
87 void BLI_rng_free(RNG *rng)
92 void BLI_rng_seed(RNG *rng, unsigned int seed)
94 rng->X = (((uint64_t) seed) << 16) | LOWSEED;
98 * Use a hash table to create better seed.
100 void BLI_rng_srandom(RNG *rng, unsigned int seed)
102 BLI_rng_seed(rng, seed + hash[seed & 255]);
103 seed = BLI_rng_get_uint(rng);
104 BLI_rng_seed(rng, seed + hash[seed & 255]);
105 seed = BLI_rng_get_uint(rng);
106 BLI_rng_seed(rng, seed + hash[seed & 255]);
109 BLI_INLINE void rng_step(RNG *rng)
111 rng->X = (MULTIPLIER * rng->X + ADDEND) & MASK;
114 void BLI_rng_get_char_n(RNG *rng, char *bytes, size_t bytes_len)
117 size_t trim_len = bytes_len;
119 #define RAND_STRIDE (sizeof(rng->X) - MASK_BYTES)
121 if (trim_len > RAND_STRIDE) {
122 last_len = trim_len % RAND_STRIDE;
123 trim_len = trim_len - last_len;
127 last_len = bytes_len;
130 const char *data_src = (void *)&(rng->X);
132 while (i != trim_len) {
133 BLI_assert(i < trim_len);
134 #ifdef __BIG_ENDIAN__
135 for (size_t j = (RAND_STRIDE + MASK_BYTES) - 1; j != MASK_BYTES - 1; j--)
137 for (size_t j = 0; j != RAND_STRIDE; j++)
140 bytes[i++] = data_src[j];
145 for (size_t j = 0; j != last_len; j++) {
146 bytes[i++] = data_src[j];
153 int BLI_rng_get_int(RNG *rng)
156 return (int) (rng->X >> 17);
159 unsigned int BLI_rng_get_uint(RNG *rng)
162 return (unsigned int) (rng->X >> 17);
166 * \return Random value (0..1), but never 1.0.
168 double BLI_rng_get_double(RNG *rng)
170 return (double) BLI_rng_get_int(rng) / 0x80000000;
174 * \return Random value (0..1), but never 1.0.
176 float BLI_rng_get_float(RNG *rng)
178 return (float) BLI_rng_get_int(rng) / 0x80000000;
181 void BLI_rng_get_float_unit_v2(RNG *rng, float v[2])
183 float a = (float)(M_PI * 2.0) * BLI_rng_get_float(rng);
188 void BLI_rng_get_float_unit_v3(RNG *rng, float v[3])
191 v[2] = (2.0f * BLI_rng_get_float(rng)) - 1.0f;
192 if ((r = 1.0f - (v[2] * v[2])) > 0.0f) {
193 float a = (float)(M_PI * 2.0) * BLI_rng_get_float(rng);
204 * Generate a random point inside given tri.
206 void BLI_rng_get_tri_sample_float_v2(
207 RNG *rng, const float v1[2], const float v2[2], const float v3[2],
210 float u = BLI_rng_get_float(rng);
211 float v = BLI_rng_get_float(rng);
213 float side_u[2], side_v[2];
215 if ((u + v) > 1.0f) {
220 sub_v2_v2v2(side_u, v2, v1);
221 sub_v2_v2v2(side_v, v3, v1);
223 copy_v2_v2(r_pt, v1);
224 madd_v2_v2fl(r_pt, side_u, u);
225 madd_v2_v2fl(r_pt, side_v, v);
228 void BLI_rng_shuffle_array(RNG *rng, void *data, unsigned int elem_size_i, unsigned int elem_tot)
230 const size_t elem_size = (size_t)elem_size_i;
231 unsigned int i = elem_tot;
238 temp = malloc(elem_size);
241 unsigned int j = BLI_rng_get_uint(rng) % elem_tot;
243 void *iElem = (unsigned char *)data + i * elem_size_i;
244 void *jElem = (unsigned char *)data + j * elem_size_i;
245 memcpy(temp, iElem, elem_size);
246 memcpy(iElem, jElem, elem_size);
247 memcpy(jElem, temp, elem_size);
255 * Simulate getting \a n random values.
257 * \note Useful when threaded code needs consistent values, independent of task division.
259 void BLI_rng_skip(RNG *rng, int n)
268 /* initialize with some non-zero seed */
269 static RNG theBLI_rng = {611330372042337130};
271 void BLI_srandom(unsigned int seed)
273 BLI_rng_srandom(&theBLI_rng, seed);
278 return BLI_rng_get_int(&theBLI_rng);
281 float BLI_frand(void)
283 return BLI_rng_get_float(&theBLI_rng);
286 void BLI_frand_unit_v3(float v[3])
288 BLI_rng_get_float_unit_v3(&theBLI_rng, v);
291 float BLI_hash_frand(unsigned int seed)
295 BLI_rng_srandom(&rng, seed);
296 return BLI_rng_get_float(&rng);
299 void BLI_array_randomize(void *data, unsigned int elem_size, unsigned int elem_tot, unsigned int seed)
303 BLI_rng_seed(&rng, seed);
304 BLI_rng_shuffle_array(&rng, data, elem_size, elem_tot);
307 /* ********* for threaded random ************** */
309 static RNG rng_tab[BLENDER_MAX_THREADS];
311 void BLI_thread_srandom(int thread, unsigned int seed)
313 if (thread >= BLENDER_MAX_THREADS)
316 BLI_rng_seed(&rng_tab[thread], seed + hash[seed & 255]);
317 seed = BLI_rng_get_uint(&rng_tab[thread]);
318 BLI_rng_seed(&rng_tab[thread], seed + hash[seed & 255]);
319 seed = BLI_rng_get_uint(&rng_tab[thread]);
320 BLI_rng_seed(&rng_tab[thread], seed + hash[seed & 255]);
323 int BLI_thread_rand(int thread)
325 return BLI_rng_get_int(&rng_tab[thread]);
328 float BLI_thread_frand(int thread)
330 return BLI_rng_get_float(&rng_tab[thread]);
333 struct RNG_THREAD_ARRAY {
334 RNG rng_tab[BLENDER_MAX_THREADS];
337 RNG_THREAD_ARRAY *BLI_rng_threaded_new(void)
340 RNG_THREAD_ARRAY *rngarr = MEM_mallocN(sizeof(RNG_THREAD_ARRAY), "random_array");
342 for (i = 0; i < BLENDER_MAX_THREADS; i++) {
343 BLI_rng_srandom(&rngarr->rng_tab[i], (unsigned int)clock());
349 void BLI_rng_threaded_free(struct RNG_THREAD_ARRAY *rngarr)
354 int BLI_rng_thread_rand(RNG_THREAD_ARRAY *rngarr, int thread)
356 return BLI_rng_get_int(&rngarr->rng_tab[thread]);
359 /* ********* Low-discrepancy sequences ************** */
361 /* incremental halton sequence generator, from:
362 * "Instant Radiosity", Keller A. */
363 BLI_INLINE double halton_ex(double invprimes, double *offset)
365 double e = fabs((1.0 - *offset) - 1e-10);
367 if (invprimes >= e) {
369 double h = invprimes;
376 *offset += ((lasth + h) - 1.0);
379 *offset += invprimes;
385 void BLI_halton_1D(unsigned int prime, double offset, int n, double *r)
387 const double invprime = 1.0 / (double)prime;
389 for (int s = 0; s < n; s++) {
390 *r = halton_ex(invprime, &offset);
394 void BLI_halton_2D(unsigned int prime[2], double offset[2], int n, double *r)
396 const double invprimes[2] = {1.0 / (double)prime[0], 1.0 / (double)prime[1]};
398 for (int s = 0; s < n; s++) {
399 for (int i = 0; i < 2; i++) {
400 r[i] = halton_ex(invprimes[i], &offset[i]);
405 void BLI_halton_3D(unsigned int prime[3], double offset[3], int n, double *r)
407 const double invprimes[3] = {1.0 / (double)prime[0], 1.0 / (double)prime[1], 1.0 / (double)prime[2]};
409 for (int s = 0; s < n; s++) {
410 for (int i = 0; i < 3; i++) {
411 r[i] = halton_ex(invprimes[i], &offset[i]);
416 void BLI_halton_2D_sequence(unsigned int prime[2], double offset[2], int n, double *r)
418 const double invprimes[2] = {1.0 / (double)prime[0], 1.0 / (double)prime[1]};
420 for (int s = 0; s < n; s++) {
421 for (int i = 0; i < 2; i++) {
422 r[s * 2 + i] = halton_ex(invprimes[i], &offset[i]);
428 /* From "Sampling with Hammersley and Halton Points" TT Wong
429 * Appendix: Source Code 1 */
430 BLI_INLINE double radical_inverse(unsigned int n)
434 /* This reverse the bitwise representation
435 * around the decimal point. */
436 for (double p = 0.5; n; p *= 0.5, n >>= 1) {
445 void BLI_hammersley_1D(unsigned int n, double *r)
447 *r = radical_inverse(n);
450 void BLI_hammersley_2D_sequence(unsigned int n, double *r)
452 for (unsigned int s = 0; s < n; s++) {
453 r[s * 2 + 0] = (double)(s + 0.5) / (double)n;
454 r[s * 2 + 1] = radical_inverse(s);