Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2005-07-26 00:33:10 +0400
committerDaniel Dunbar <daniel@zuster.org>2005-07-26 00:33:10 +0400
commit40a5ed791df248c5cb3d19f714dde67cd8c91458 (patch)
treeb727cdf6f96c36c99401f6ac5c27c64bdcab6ade /source/blender
parentcb988ff8a9c9df1d1e85c5ec1296857ffcb06dbd (diff)
- 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.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenlib/BLI_rand.h28
-rw-r--r--source/blender/blenlib/intern/rand.c96
2 files changed, 81 insertions, 43 deletions
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 <stdlib.h>
#include <string.h>
+#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);
+}
+