From 40a5ed791df248c5cb3d19f714dde67cd8c91458 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Mon, 25 Jul 2005 20:33:10 +0000 Subject: - added RNG abstract random object rng_{new/free/seed/get{Int,Double,Float}} to avoid use of global generator. at the moment the renderer owns the number generator and this is important for retaining render consistency. --- source/blender/blenlib/BLI_rand.h | 28 +++++++---- source/blender/blenlib/intern/rand.c | 96 +++++++++++++++++++++++------------- 2 files changed, 81 insertions(+), 43 deletions(-) (limited to 'source') diff --git a/source/blender/blenlib/BLI_rand.h b/source/blender/blenlib/BLI_rand.h index c352016ff53..5168d4b9fea 100644 --- a/source/blender/blenlib/BLI_rand.h +++ b/source/blender/blenlib/BLI_rand.h @@ -36,6 +36,21 @@ #ifndef BLI_RAND_H #define BLI_RAND_H + /* RNG is just an abstract random number generator + * type that avoids using globals, otherwise identical + * to BLI_rand functions below. + */ +struct RNG; + +struct RNG* rng_new (unsigned int seed); +void rng_free (struct RNG* rng); + +void rng_seed (struct RNG* rng, unsigned int seed); +int rng_getInt (struct RNG* rng); +double rng_getDouble (struct RNG* rng); +float rng_getFloat (struct RNG* rng); +void rng_shuffleArray(struct RNG *rng, void *data, int elemSize, int numElems); + /** Seed the random number generator */ void BLI_srand (unsigned int seed); @@ -55,17 +70,10 @@ float BLI_frand (void); */ void BLI_fillrand (void *addr, int len); - /** Stores the BLI randum number generator state - * into the buffer in @a loc_r. - */ -void BLI_storerand (unsigned int loc_r[2]); - - /** Retores the BLI randum number generator state - * from the buffer in @a loc. + /** Shuffle an array randomly using the given seed. + * contents. This routine does not use nor modify + * the state of the BLI random number generator. */ -void BLI_restorerand (unsigned int loc[2]); - - /** Shuffle an array randomly using the given seed. */ void BLI_array_randomize (void *data, int elemSize, int numElems, unsigned int seed); #endif diff --git a/source/blender/blenlib/intern/rand.c b/source/blender/blenlib/intern/rand.c index 28a50a62922..ef048a5dd5e 100644 --- a/source/blender/blenlib/intern/rand.c +++ b/source/blender/blenlib/intern/rand.c @@ -33,6 +33,8 @@ #include #include +#include "MEM_guardedalloc.h" + #include "PIL_time.h" #include "BLI_rand.h" @@ -51,57 +53,50 @@ typedef unsigned long long r_uint64; #define LOWSEED 0x330E -static r_uint64 X= 0; +/***/ -void BLI_srand(unsigned int seed) { - X= (((r_uint64) seed)<<16) | LOWSEED; -} +typedef struct RNG { + r_uint64 X; +} RNG; -int BLI_rand(void) { - X= (MULTIPLIER*X + ADDEND)&0x0000FFFFFFFFFFFF; - return (int) (X>>17); -} +RNG *rng_new(unsigned int seed) +{ + RNG *rng = MEM_mallocN(sizeof(*rng), "rng"); -double BLI_drand(void) { - return (double) BLI_rand()/0x80000000; + rng_seed(rng, seed); + + return rng; } -float BLI_frand(void) { - return (float) BLI_rand()/0x80000000; +void rng_free(RNG* rng) +{ + MEM_freeN(rng); } -void BLI_storerand(unsigned int loc_r[2]) { - loc_r[0]= (unsigned int) (X>>32); - loc_r[1]= (unsigned int) (X&0xFFFFFFFF); +void rng_seed(RNG *rng, unsigned int seed) { + rng->X= (((r_uint64) seed)<<16) | LOWSEED; } -void BLI_restorerand(unsigned int loc[2]) { - X= ((r_uint64) loc[0])<<32; - X|= loc[1]; +int rng_getInt(RNG *rng) { + rng->X= (MULTIPLIER*rng->X + ADDEND)&0x0000FFFFFFFFFFFF; + return (int) (rng->X>>17); } -void BLI_fillrand(void *addr, int len) { - unsigned char *p= addr; - unsigned int save[2]; +double rng_getDouble(RNG *rng) { + return (double) rng_getInt(rng)/0x80000000; +} - BLI_storerand(save); - - BLI_srand((unsigned int) (PIL_check_seconds_timer()*0x7FFFFFFF)); - while (len--) *p++= BLI_rand()&0xFF; - BLI_restorerand(save); +float rng_getFloat(RNG *rng) { + return (float) rng_getInt(rng)/0x80000000; } -void BLI_array_randomize(void *data, int elemSize, int numElems, unsigned int seed) +void rng_shuffleArray(RNG *rng, void *data, int elemSize, int numElems) { - unsigned int oldrand[2]; int i = numElems; void *temp = malloc(elemSize); - BLI_storerand(oldrand); - BLI_srand(seed); - while (--i) { - int j = BLI_rand()%i; + int j = rng_getInt(rng)%i; void *iElem = (unsigned char*)data + i*elemSize; void *jElem = (unsigned char*)data + j*elemSize; @@ -110,7 +105,42 @@ void BLI_array_randomize(void *data, int elemSize, int numElems, unsigned int se memcpy(jElem, temp, elemSize); } - BLI_restorerand(oldrand); free(temp); } +/***/ + +static RNG theBLI_rng = {0}; + +void BLI_srand(unsigned int seed) { + rng_seed(&theBLI_rng, seed); +} + +int BLI_rand(void) { + return rng_getInt(&theBLI_rng); +} + +double BLI_drand(void) { + return rng_getDouble(&theBLI_rng); +} + +float BLI_frand(void) { + return rng_getFloat(&theBLI_rng); +} + +void BLI_fillrand(void *addr, int len) { + RNG rng; + unsigned char *p= addr; + + rng_seed(&rng, (unsigned int) (PIL_check_seconds_timer()*0x7FFFFFFF)); + while (len--) *p++= rng_getInt(&rng)&0xFF; +} + +void BLI_array_randomize(void *data, int elemSize, int numElems, unsigned int seed) +{ + RNG rng; + + rng_seed(&rng, seed); + rng_shuffleArray(&rng, data, elemSize, numElems); +} + -- cgit v1.2.3