diff options
Diffstat (limited to 'dep/src/g3dlite/PrecomputedRandom.cpp')
-rw-r--r-- | dep/src/g3dlite/PrecomputedRandom.cpp | 125 |
1 files changed, 0 insertions, 125 deletions
diff --git a/dep/src/g3dlite/PrecomputedRandom.cpp b/dep/src/g3dlite/PrecomputedRandom.cpp deleted file mode 100644 index 387ded35195..00000000000 --- a/dep/src/g3dlite/PrecomputedRandom.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/** - @file PrecomputedRandom.cpp - - @maintainer Morgan McGuire, http://graphics.cs.williams.edu - - @created 2009-03-31 - @edited 2009-07-01 - - Copyright 2000-2009, Morgan McGuire. - All rights reserved. - */ - -#include "G3D/PrecomputedRandom.h" -#include "G3D/System.h" - -namespace G3D { - -PrecomputedRandom::PrecomputedRandom(int dataSize, uint32 seed) : - Random((void*)NULL), - m_hemiUniform(NULL), - m_sphereBits(NULL), - m_modMask(dataSize - 1), - m_freeData(true) { - - alwaysAssertM(isPow2(dataSize), "dataSize must be a power of 2"); - m_index = seed & m_modMask; - - HemiUniformData* h; - SphereBitsData* s; - m_hemiUniform = h = (HemiUniformData*) System::malloc(sizeof(HemiUniformData) * dataSize); - m_sphereBits = s = (SphereBitsData*) System::malloc(sizeof(SphereBitsData) * dataSize); - - Random r; - - for (int i = 0; i < dataSize; ++i) { - h[i].uniform = r.uniform(); - r.cosHemi(h[i].cosHemiX, h[i].cosHemiY, h[i].cosHemiZ); - - s[i].bits = r.bits(); - r.sphere(s[i].sphereX, s[i].sphereY, s[i].sphereZ); - } - -} - - -PrecomputedRandom::PrecomputedRandom(const HemiUniformData* data1, const SphereBitsData* data2, int dataSize, uint32 seed) : - Random((void*)NULL), - m_hemiUniform(data1), - m_sphereBits(data2), - m_modMask(dataSize - 1), - m_freeData(false) { - - m_index = seed & m_modMask; - alwaysAssertM(isPow2(dataSize), "dataSize must be a power of 2"); -} - - -PrecomputedRandom::~PrecomputedRandom() { - if (m_freeData) { - System::free(const_cast<HemiUniformData*>(m_hemiUniform)); - System::free(const_cast<SphereBitsData*>(m_sphereBits)); - } -} - -float PrecomputedRandom::uniform(float low, float high) { - m_index = (m_index + 1) & m_modMask; - return low + m_hemiUniform[m_index].uniform * (high - low); -} - - -float PrecomputedRandom::uniform() { - m_index = (m_index + 1) & m_modMask; - return m_hemiUniform[m_index].uniform; -} - - -void PrecomputedRandom::cosHemi(float& x, float& y, float& z) { - m_index = (m_index + 1) & m_modMask; - x = m_hemiUniform[m_index].cosHemiX; - y = m_hemiUniform[m_index].cosHemiY; - z = m_hemiUniform[m_index].cosHemiZ; -} - -void PrecomputedRandom::cosPowHemi(const float k, float& x, float& y, float& z) { - // Computing a cosPowHemi costs 4 slow functions (pow, sqrt, sin, - // cos). We can do it with two, given a cosHemi sample, basically - // saving the cost of sin and cos and making a single 128-byte - // memory read (for a vector) instead of two (for adjacent uniform - // floats). - - // cos^1 distribution sample - float cos1; - cosHemi(x, y, cos1); - - // Fix the distribution by adjusting the cosine: - // rnd(cos^k t) = (rnd(cos(t))^2)^(1/k) - - // produces cos^k distribution sample - z = pow(cos1, 2.0f / (1.0f + k)); - - // Rescale x and y by sqrt(1.0f - square(z)) / sqrt(x*x + y*y). - // Add a very tiny offset to handle the (almost impossibly unlikely) case where - // z = 1 and x^2+y^2 = 0. - static const float eps = 0.000001f; - const float s = sqrt((1.0f + eps - square(z)) / (square(x) + square(y) + eps)); - - x *= s; - y *= s; -} - - -uint32 PrecomputedRandom::bits() { - m_index = (m_index + 1) & m_modMask; - return m_sphereBits[m_index].bits; -} - - -void PrecomputedRandom::sphere(float& x, float& y, float& z) { - m_index = (m_index + 1) & m_modMask; - x = m_sphereBits[m_index].sphereX; - y = m_sphereBits[m_index].sphereY; - z = m_sphereBits[m_index].sphereZ; -} - -} |