111 lines
3.0 KiB
C
111 lines
3.0 KiB
C
|
/**
|
||
|
@file PrecomputedRandom.h
|
||
|
|
||
|
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||
|
|
||
|
@created 2009-03-31
|
||
|
@edited 2009-03-31
|
||
|
|
||
|
Copyright 2000-2009, Morgan McGuire.
|
||
|
All rights reserved.
|
||
|
*/
|
||
|
#ifndef G3D_PrecomputedRandom_h
|
||
|
#define G3D_PrecomputedRandom_h
|
||
|
|
||
|
#include "G3D/platform.h"
|
||
|
#include "G3D/Random.h"
|
||
|
|
||
|
namespace G3D {
|
||
|
|
||
|
/** Fast random numbers using a precomputed data table.
|
||
|
|
||
|
e.g., generates cosHemi about 13x faster than Random.
|
||
|
This is useful for quickly generating seeded random
|
||
|
numbers for reproducibility. G3D::Random takes a long
|
||
|
time to seed; this is instantaneous (providing the
|
||
|
precomputed data is already available.)
|
||
|
|
||
|
Not threadsafe.*/
|
||
|
class PrecomputedRandom : public Random {
|
||
|
public:
|
||
|
/** Put the cosHemi and the uniform together so that when
|
||
|
alternating between them we stay in cache. This is also packed
|
||
|
into a good size for SIMD and GPU operations.*/
|
||
|
class HemiUniformData {
|
||
|
public:
|
||
|
float cosHemiX;
|
||
|
float cosHemiY;
|
||
|
float cosHemiZ;
|
||
|
float uniform;
|
||
|
};
|
||
|
|
||
|
class SphereBitsData {
|
||
|
public:
|
||
|
float sphereX;
|
||
|
float sphereY;
|
||
|
float sphereZ;
|
||
|
uint32 bits;
|
||
|
};
|
||
|
|
||
|
protected:
|
||
|
|
||
|
/** Array of 2^n elements. */
|
||
|
const HemiUniformData* m_hemiUniform;
|
||
|
const SphereBitsData* m_sphereBits;
|
||
|
|
||
|
/** 2^n - 1; the AND mask for computing a fast modulo */
|
||
|
int m_modMask;
|
||
|
|
||
|
int m_index;
|
||
|
|
||
|
/** If true, free m_hemiUniform and m_sphereBits in destructor */
|
||
|
bool m_freeData;
|
||
|
|
||
|
public:
|
||
|
|
||
|
/*
|
||
|
\param dataSize Must be a power of 2
|
||
|
\param data Will NOT be deleted by the destructor.
|
||
|
*/
|
||
|
PrecomputedRandom(const HemiUniformData* data1, const SphereBitsData* data2, int dataSize, uint32 seed = 0xF018A4D2);
|
||
|
|
||
|
/**
|
||
|
\param dataSize Number of random numbers that can be requested before periodicity. Must be a power of 2.
|
||
|
*/
|
||
|
PrecomputedRandom(int dataSize, uint32 seed = 0xF018A4D2);
|
||
|
|
||
|
~PrecomputedRandom();
|
||
|
|
||
|
/** Each bit is random. Subclasses can choose to override just
|
||
|
this method and the other methods will all work automatically. */
|
||
|
virtual uint32 bits();
|
||
|
|
||
|
// integer is inherited
|
||
|
|
||
|
/** Uniform random float on the range [min, max] */
|
||
|
virtual float uniform(float low, float high);
|
||
|
|
||
|
/** Uniform random float on the range [0, 1] */
|
||
|
virtual float uniform();
|
||
|
|
||
|
// gaussian is inherited
|
||
|
|
||
|
/** Returns 3D unit vectors distributed according to
|
||
|
a cosine distribution about the z axis. */
|
||
|
virtual void cosHemi(float& x, float& y, float& z);
|
||
|
|
||
|
/** Returns 3D unit vectors distributed according to a cosine
|
||
|
power distribution (\f$ \mbox{cos}^k \theta \f$) about
|
||
|
the z-axis. */
|
||
|
virtual void cosPowHemi(const float k, float& x, float& y, float& z);
|
||
|
|
||
|
// hemi is inherited
|
||
|
|
||
|
/** Returns 3D unit vectors uniformly distributed on the sphere */
|
||
|
virtual void sphere(float& x, float& y, float& z);
|
||
|
};
|
||
|
|
||
|
}
|
||
|
|
||
|
#endif
|