Initial commit
This commit is contained in:
164
deps/g3dlite/include/G3D/Random.h
vendored
Normal file
164
deps/g3dlite/include/G3D/Random.h
vendored
Normal file
@@ -0,0 +1,164 @@
|
||||
/**
|
||||
\file G3D/Random.h
|
||||
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
\created 2009-01-02
|
||||
\edited 2012-07-20
|
||||
|
||||
Copyright 2000-2012, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
#ifndef G3D_Random_h
|
||||
#define G3D_Random_h
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/g3dmath.h"
|
||||
#include "G3D/GMutex.h"
|
||||
|
||||
namespace G3D {
|
||||
|
||||
/** Random number generator.
|
||||
|
||||
Threadsafe.
|
||||
|
||||
Useful for generating consistent random numbers across platforms
|
||||
and when multiple threads are involved.
|
||||
|
||||
Uses the Fast Mersenne Twister (FMT-19937) algorithm.
|
||||
|
||||
On average, uniform() runs about 2x-3x faster than rand().
|
||||
|
||||
@cite http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html
|
||||
|
||||
On OS X, Random is about 10x faster than drand48() (which is
|
||||
threadsafe) and 4x faster than rand() (which is not threadsafe).
|
||||
|
||||
\sa Noise
|
||||
*/
|
||||
class Random {
|
||||
protected:
|
||||
|
||||
/** Constants (important for the algorithm; do not modify) */
|
||||
enum {
|
||||
N = 624,
|
||||
M = 397,
|
||||
R = 31,
|
||||
U = 11,
|
||||
S = 7,
|
||||
T = 15,
|
||||
L = 18,
|
||||
A = 0x9908B0DF,
|
||||
B = 0x9D2C5680,
|
||||
C = 0xEFC60000};
|
||||
|
||||
/**
|
||||
Prevents multiple overlapping calls to generate().
|
||||
*/
|
||||
Spinlock lock;
|
||||
|
||||
/** State vector (these are the next N values that will be returned) */
|
||||
uint32* state;
|
||||
|
||||
/** Index into state */
|
||||
int index;
|
||||
|
||||
bool m_threadsafe;
|
||||
|
||||
/** Generate the next N ints, and store them for readback later.
|
||||
Called from bits() */
|
||||
virtual void generate();
|
||||
|
||||
/** For subclasses. The void* parameter is just to distinguish this from the
|
||||
public constructor.*/
|
||||
Random(void*);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
Random& operator=(const Random&) {
|
||||
alwaysAssertM(false,
|
||||
"There is no copy constructor or assignment operator for Random because you "
|
||||
"probably didn't actually want to copy the state--it would "
|
||||
"be slow and duplicate the state of a pseudo-random sequence. Maybe you could "
|
||||
"provide arguments to a member variable in the constructor, "
|
||||
"or pass the Random by reference?");
|
||||
return *this;
|
||||
}
|
||||
|
||||
Random(const Random& r) {
|
||||
*this = r;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/** \param threadsafe Set to false if you know that this random
|
||||
will only be used on a single thread. This eliminates the
|
||||
lock and improves performance on some platforms.
|
||||
*/
|
||||
Random(uint32 seed = 0xF018A4D2, bool threadsafe = true);
|
||||
|
||||
virtual ~Random();
|
||||
|
||||
virtual void reset(uint32 seed = 0xF018A4D2, bool threadsafe = true);
|
||||
|
||||
/** Each bit is random. Subclasses can choose to override just
|
||||
this method and the other methods will all work automatically. */
|
||||
virtual uint32 bits();
|
||||
|
||||
/** Uniform random integer on the range [min, max] */
|
||||
virtual int integer(int min, int max);
|
||||
|
||||
/** Uniform random float on the range [min, max] */
|
||||
virtual inline float uniform(float low, float high) {
|
||||
// We could compute the ratio in double precision here for
|
||||
// about 1.5x slower performance and slightly better
|
||||
// precision.
|
||||
return low + (high - low) * ((float)bits() / (float)0xFFFFFFFFUL);
|
||||
}
|
||||
|
||||
/** Uniform random float on the range [0, 1] */
|
||||
virtual inline float uniform() {
|
||||
// We could compute the ratio in double precision here for
|
||||
// about 1.5x slower performance and slightly better
|
||||
// precision.
|
||||
const float norm = 1.0f / (float)0xFFFFFFFFUL;
|
||||
return (float)bits() * norm;
|
||||
}
|
||||
|
||||
/** Normally distributed reals. */
|
||||
virtual float gaussian(float mean, float stdev);
|
||||
|
||||
/** Returns 3D unit vectors distributed according to
|
||||
a cosine distribution about the positive z-axis. */
|
||||
virtual void cosHemi(float& x, float& y, float& z);
|
||||
|
||||
/** Returns 3D unit vectors distributed according to
|
||||
a cosine distribution about the z-axis. */
|
||||
virtual void cosSphere(float& x, float& y, float& z);
|
||||
|
||||
/** Returns 3D unit vectors distributed according to a cosine
|
||||
power distribution (\f$ \cos^k \theta \f$) about
|
||||
the z-axis. */
|
||||
virtual void cosPowHemi(const float k, float& x, float& y, float& z);
|
||||
|
||||
/** Returns 3D unit vectors uniformly distributed on the
|
||||
hemisphere about the z-axis. */
|
||||
virtual void hemi(float& x, float& y, float& z);
|
||||
|
||||
/** Returns 3D unit vectors uniformly distributed on the sphere */
|
||||
virtual void sphere(float& x, float& y, float& z);
|
||||
|
||||
/**
|
||||
A shared instance for when the performance and features but not
|
||||
consistency of the class are desired. It is slightly (10%)
|
||||
faster to use a distinct instance than to use the common one.
|
||||
|
||||
Threadsafe.
|
||||
*/
|
||||
static Random& common();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user