diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2013-04-16 03:12:40 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2013-04-16 03:12:40 +0400 |
commit | afb4b65167165613f177a531bd3d4dcb3649c1c6 (patch) | |
tree | 32e1446b5fc3ce8ec00fa0e8b9e0fcb2eedda127 /source/blender/blenlib | |
parent | 638b084f824bc345468bc8e02422b5da65a641a7 (diff) |
Random number generator: replace a bunch of usage of the global random number
generator with a local one. It's not thread safe and will not give repeatable
results, so in most cases it should not be used.
Also fixes #34992 where the noise texture of a displacement modifier was not
properly random in opengl animation render, because the seed got reset to a
fixed value by an unrelated function while for final render it changed each
frame.
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r-- | source/blender/blenlib/BLI_rand.h | 23 | ||||
-rw-r--r-- | source/blender/blenlib/intern/jitter.c | 10 | ||||
-rw-r--r-- | source/blender/blenlib/intern/rand.c | 42 |
3 files changed, 39 insertions, 36 deletions
diff --git a/source/blender/blenlib/BLI_rand.h b/source/blender/blenlib/BLI_rand.h index 3bc9a3bdb32..378beff3aa0 100644 --- a/source/blender/blenlib/BLI_rand.h +++ b/source/blender/blenlib/BLI_rand.h @@ -33,14 +33,15 @@ * \brief Random number functions. */ -/** RNG is just an abstract random number generator - * type that avoids using globals, otherwise identical - * to BLI_rand functions below. +/* RNG is an abstract random number generator type that avoids using globals. + * Always use this instead of the global RNG unless you have a good reason, + * the global RNG is not thread safe and will not give repeatable results. */ struct RNG; typedef struct RNG RNG; struct RNG *BLI_rng_new(unsigned int seed); +struct RNG *BLI_rng_new_srandom(unsigned int seed); void BLI_rng_free(struct RNG *rng); void BLI_rng_seed(struct RNG *rng, unsigned int seed); @@ -53,27 +54,17 @@ void BLI_rng_shuffle_array(struct RNG *rng, void *data, int elemSize, int /** Note that skipping is as slow as generating n numbers! */ void BLI_rng_skip(struct RNG *rng, int n); -/** Seed the random number generator */ -void BLI_srand(unsigned int seed); - -/** Better seed for the random number generator, using noise.c hash[] */ +/** Seed for the random number generator, using noise.c hash[] */ void BLI_srandom(unsigned int seed); /** Return a pseudo-random number N where 0<=N<(2^31) */ int BLI_rand(void); -/** Return a pseudo-random number N where 0.0<=N<1.0 */ -double BLI_drand(void); - /** Return a pseudo-random number N where 0.0f<=N<1.0f */ float BLI_frand(void); -/** Fills a block of memory starting at \a addr - * and extending \a len bytes with pseudo-random - * contents. This routine does not use nor modify - * the state of the BLI random number generator. - */ -void BLI_fillrand(void *addr, int len); +/** Return a pseudo-random (hash) float from an integer value */ +float BLI_hash_frand(unsigned int seed); /** Shuffle an array randomly using the given seed. * contents. This routine does not use nor modify diff --git a/source/blender/blenlib/intern/jitter.c b/source/blender/blenlib/intern/jitter.c index 3fe0ef158df..7141bedcf05 100644 --- a/source/blender/blenlib/intern/jitter.c +++ b/source/blender/blenlib/intern/jitter.c @@ -139,6 +139,7 @@ void BLI_jitterate2(float *jit1, float *jit2, int num, float rad2) void BLI_jitter_init(float *jitarr, int num) { float *jit2, x, rad1, rad2, rad3; + RNG *rng; int i; if (num == 0) return; @@ -148,15 +149,18 @@ void BLI_jitter_init(float *jitarr, int num) rad2 = 1.0f / ((float)num); rad3 = sqrtf((float)num) / ((float)num); - BLI_srand(31415926 + num); + rng = BLI_rng_new(31415926 + num); + x = 0; for (i = 0; i < 2 * num; i += 2) { - jitarr[i] = x + rad1 * (float)(0.5 - BLI_drand()); - jitarr[i + 1] = ((float)i / 2) / num + rad1 * (float)(0.5 - BLI_drand()); + jitarr[i] = x + rad1 * (float)(0.5 - BLI_rng_get_double(rng)); + jitarr[i + 1] = ((float)i / 2) / num + rad1 * (float)(0.5 - BLI_rng_get_double(rng)); x += rad3; x -= floorf(x); } + BLI_rng_free(rng); + for (i = 0; i < 24; i++) { BLI_jitterate1(jitarr, jit2, num, rad1); BLI_jitterate1(jitarr, jit2, num, rad1); diff --git a/source/blender/blenlib/intern/rand.c b/source/blender/blenlib/intern/rand.c index 76d17f34b5e..743d910e418 100644 --- a/source/blender/blenlib/intern/rand.c +++ b/source/blender/blenlib/intern/rand.c @@ -73,6 +73,15 @@ RNG *BLI_rng_new(unsigned int seed) return rng; } +RNG *BLI_rng_new_srandom(unsigned int seed) +{ + RNG *rng = MEM_mallocN(sizeof(*rng), "rng"); + + BLI_rng_srandom(rng, seed); + + return rng; +} + void BLI_rng_free(RNG *rng) { MEM_freeN(rng); @@ -145,13 +154,8 @@ void BLI_rng_skip(RNG *rng, int n) /***/ -static RNG theBLI_rng = {0}; - -/* note, this one creates periodical patterns */ -void BLI_srand(unsigned int seed) -{ - BLI_rng_seed(&theBLI_rng, seed); -} +/* initialize with some non-zero seed */ +static RNG theBLI_rng = {611330372042337130}; /* using hash table to create better seed */ void BLI_srandom(unsigned int seed) @@ -164,23 +168,27 @@ int BLI_rand(void) return BLI_rng_get_int(&theBLI_rng); } -double BLI_drand(void) -{ - return BLI_rng_get_double(&theBLI_rng); -} - float BLI_frand(void) { return BLI_rng_get_float(&theBLI_rng); } -void BLI_fillrand(void *addr, int len) +float BLI_hash_frand(unsigned int seed) { - RNG rng; - unsigned char *p = addr; + r_uint64 X; + + seed = seed + hash[seed & 255]; + X = (((r_uint64) seed) << 16) | LOWSEED; + seed = (int)(((MULTIPLIER * X + ADDEND) & MASK) >> 17); + + seed = seed + hash[seed & 255]; + X = (((r_uint64) seed) << 16) | LOWSEED; + X = (int)(((MULTIPLIER * X + ADDEND) & MASK) >> 17); + + seed = seed + hash[seed & 255]; + X = (((r_uint64) seed) << 16) | LOWSEED; - BLI_rng_seed(&rng, (unsigned int) (PIL_check_seconds_timer() * 0x7FFFFFFF)); - while (len--) *p++ = BLI_rng_get_int(&rng) & 0xFF; + return (int)(((MULTIPLIER * X + ADDEND) & MASK) >> 17); } void BLI_array_randomize(void *data, int elemSize, int numElems, unsigned int seed) |