mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -04:00
optimizations, a few more interfaces
This commit is contained in:
parent
ac1a7e272e
commit
8cef27663e
@ -25,7 +25,8 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE double PerlinNoise::
|
||||
fade(double t) {
|
||||
return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);
|
||||
// return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);
|
||||
return (3.0 - 2.0 * t) * t * t;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -33,9 +33,21 @@ bool PerlinNoise::_got_first_seed = false;
|
||||
PerlinNoise::
|
||||
PerlinNoise(int table_size, unsigned long seed) :
|
||||
_table_size(table_size),
|
||||
_table_size_mask(table_size - 1),
|
||||
_mersenne(seed != 0 ? seed : get_next_seed())
|
||||
{
|
||||
// The _index table is just a randomly shuffled index.
|
||||
// It is necessary for _table_size to be a power of 2.
|
||||
#ifndef NDEBUG
|
||||
if (_table_size != 0) {
|
||||
bool table_size_power_2 = ((_table_size ^ _table_size_mask) == (_table_size + _table_size_mask));
|
||||
nassertd(table_size_power_2) {
|
||||
_table_size = 0;
|
||||
_table_size_mask = 0;
|
||||
}
|
||||
}
|
||||
#endif // NDEBUG
|
||||
|
||||
// The _index table is just a randomly shuffled index
|
||||
// table.
|
||||
_index.reserve(_table_size * 2);
|
||||
int i;
|
||||
@ -56,3 +68,32 @@ PerlinNoise(int table_size, unsigned long seed) :
|
||||
_index.push_back(_index[i]);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PerlinNoise::Copy Constructor
|
||||
// Access: Protected
|
||||
// Description: Makes an exact copy of the existing PerlinNoise
|
||||
// object, including its random seed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PerlinNoise::
|
||||
PerlinNoise(const PerlinNoise ©) :
|
||||
_table_size(copy._table_size),
|
||||
_table_size_mask(copy._table_size_mask),
|
||||
_mersenne(copy._mersenne),
|
||||
_index(copy._index)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PerlinNoise::Copy Assignment Operator
|
||||
// Access: Protected
|
||||
// Description: Makes an exact copy of the existing PerlinNoise
|
||||
// object, including its random seed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PerlinNoise::
|
||||
operator = (const PerlinNoise ©) {
|
||||
_table_size = copy._table_size;
|
||||
_table_size_mask = copy._table_size_mask;
|
||||
_mersenne = copy._mersenne;
|
||||
_index = copy._index;
|
||||
}
|
||||
|
@ -34,6 +34,8 @@
|
||||
class EXPCL_PANDA PerlinNoise {
|
||||
protected:
|
||||
PerlinNoise(int table_size, unsigned long seed);
|
||||
PerlinNoise(const PerlinNoise ©);
|
||||
void operator = (const PerlinNoise ©);
|
||||
|
||||
INLINE static double fade(double t);
|
||||
INLINE static double lerp(double t, double a, double b);
|
||||
@ -49,6 +51,7 @@ PUBLISHED:
|
||||
|
||||
protected:
|
||||
int _table_size;
|
||||
int _table_size_mask;
|
||||
|
||||
Mersenne _mersenne;
|
||||
static Mersenne _next_seed;
|
||||
|
@ -17,6 +17,49 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PerlinNoise2::Default Constructor
|
||||
// Access: Published
|
||||
// Description: The default constructor makes an invalid PerlinNoise2
|
||||
// object. You must at least pass in a scale of each
|
||||
// dimension.
|
||||
//
|
||||
// This constructor exists only so you can create a
|
||||
// temporary placeholder PerlinNoise2 object, and later
|
||||
// fill it in with the assignment operator.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PerlinNoise2::
|
||||
PerlinNoise2() :
|
||||
PerlinNoise(0, 1)
|
||||
{
|
||||
_input_xform.fill(0.0f);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PerlinNoise2::Copy Constructor
|
||||
// Access: Published
|
||||
// Description: Makes an exact copy of the existing PerlinNoise
|
||||
// object, including its random seed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PerlinNoise2::
|
||||
PerlinNoise2(const PerlinNoise2 ©) :
|
||||
PerlinNoise(copy),
|
||||
_input_xform(copy._input_xform)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PerlinNoise2::Copy Assignment Operator
|
||||
// Access: Published
|
||||
// Description: Makes an exact copy of the existing PerlinNoise
|
||||
// object, including its random seed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PerlinNoise2::
|
||||
operator = (const PerlinNoise2 ©) {
|
||||
PerlinNoise::operator = (copy);
|
||||
_input_xform = copy._input_xform;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PerlinNoise2::noise
|
||||
// Access: Published
|
||||
@ -37,6 +80,36 @@ noise(const LVecBase2f &value) {
|
||||
return (float)noise(value[0], value[1]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PerlinNoise2::operator ()
|
||||
// Access: Published
|
||||
// Description: Returns the noise function of the two inputs.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE double PerlinNoise2::
|
||||
operator ()(double x, double y) {
|
||||
return noise(x, y);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PerlinNoise2::noise
|
||||
// Access: Published
|
||||
// Description: Returns the noise function of the two inputs.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float PerlinNoise2::
|
||||
operator ()(const LVecBase2f &value) {
|
||||
return noise(value);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PerlinNoise2::noise
|
||||
// Access: Published
|
||||
// Description: Returns the noise function of the two inputs.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE double PerlinNoise2::
|
||||
operator ()(const LVecBase2d &value) {
|
||||
return noise(value);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PerlinNoise2::grad
|
||||
// Access: Private, Static
|
||||
@ -46,8 +119,22 @@ noise(const LVecBase2f &value) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE double PerlinNoise2::
|
||||
grad(int hash, double x, double y) {
|
||||
// Convert lo 3 bits of hash code into 8 gradient directions.
|
||||
// Convert low 3 bits of hash code into 8 gradient directions.
|
||||
switch (hash & 7) {
|
||||
// Four corners.
|
||||
case 0: return x + y;
|
||||
case 1: return x - y;
|
||||
case 2: return -x + y;
|
||||
case 3: return -x - y;
|
||||
|
||||
int h = hash & 7;
|
||||
return _grad_table[h].dot(LVector2d(x, y));
|
||||
// Four edges. Here we scale by 1.707 to make all the vectors equal
|
||||
// length, and to make their lengths consistent with PerlinNoise3.
|
||||
case 4: return 1.707 * x;
|
||||
case 5: return 1.707 * y;
|
||||
case 6: return -1.707 * x;
|
||||
case 7: return -1.707 * y;
|
||||
}
|
||||
|
||||
nassertr(false, 0);
|
||||
return 0;
|
||||
}
|
||||
|
@ -19,21 +19,6 @@
|
||||
#include "perlinNoise2.h"
|
||||
#include "cmath.h"
|
||||
|
||||
LVector2d PerlinNoise2::_grad_table[8] = {
|
||||
// Four corners.
|
||||
LVector2d(1, 1),
|
||||
LVector2d(1, -1),
|
||||
LVector2d(-1, 1),
|
||||
LVector2d(-1, -1),
|
||||
|
||||
// Four edges. Here we scale by 1.707 to make all the vectors equal
|
||||
// length, and to make their lengths consistent with PerlinNoise3.
|
||||
LVector2d(1.707, 0),
|
||||
LVector2d(0, 1.707),
|
||||
LVector2d(-1.707, 0),
|
||||
LVector2d(0, -1.707),
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PerlinNoise2::Constructor
|
||||
// Access: Published
|
||||
@ -77,22 +62,25 @@ noise(const LVecBase2d &value) {
|
||||
double y = vec._v.v._1;
|
||||
|
||||
// Find unit square that contains point.
|
||||
int X = cmod((int)cfloor(x), _table_size);
|
||||
int Y = cmod((int)cfloor(y), _table_size);
|
||||
double xf = cfloor(x);
|
||||
double yf = cfloor(y);
|
||||
|
||||
int X = ((int)xf) & _table_size_mask;
|
||||
int Y = ((int)yf) & _table_size_mask;
|
||||
|
||||
// Find relative x,y of point in square.
|
||||
x -= cfloor(x);
|
||||
y -= cfloor(y);
|
||||
x -= xf;
|
||||
y -= yf;
|
||||
|
||||
// Compute fade curves for each of x,y.
|
||||
double u = fade(x);
|
||||
double v = fade(y);
|
||||
|
||||
// Hash coordinates of the 4 square corners . . .
|
||||
// Hash coordinates of the 4 square corners (A, B, A + 1, and B + 1)
|
||||
int A = _index[X] + Y;
|
||||
int B = _index[X + 1] + Y;
|
||||
|
||||
// . . . and add blended results from 8 corners of cube.
|
||||
// and add blended results from 4 corners of square.
|
||||
double result =
|
||||
lerp(v, lerp(u, grad(_index[A], x, y),
|
||||
grad(_index[B], x - 1, y)),
|
||||
|
@ -31,21 +31,26 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA PerlinNoise2 : public PerlinNoise {
|
||||
PUBLISHED:
|
||||
INLINE PerlinNoise2();
|
||||
PerlinNoise2(double sx, double sy,
|
||||
int table_size = 256,
|
||||
unsigned long seed = 0);
|
||||
INLINE PerlinNoise2(const PerlinNoise2 ©);
|
||||
INLINE void operator = (const PerlinNoise2 ©);
|
||||
|
||||
INLINE double noise(double x, double y);
|
||||
INLINE float noise(const LVecBase2f &value);
|
||||
double noise(const LVecBase2d &value);
|
||||
|
||||
INLINE double operator ()(double x, double y);
|
||||
INLINE float operator ()(const LVecBase2f &value);
|
||||
INLINE double operator ()(const LVecBase2d &value);
|
||||
|
||||
private:
|
||||
INLINE static double grad(int hash, double x, double y);
|
||||
|
||||
private:
|
||||
LMatrix3d _input_xform;
|
||||
|
||||
static LVector2d _grad_table[8];
|
||||
};
|
||||
|
||||
#include "perlinNoise2.I"
|
||||
|
@ -17,6 +17,49 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PerlinNoise3::Default Constructor
|
||||
// Access: Published
|
||||
// Description: The default constructor makes an invalid PerlinNoise3
|
||||
// object. You must at least pass in a scale of each
|
||||
// dimension.
|
||||
//
|
||||
// This constructor exists only so you can create a
|
||||
// temporary placeholder PerlinNoise3 object, and later
|
||||
// fill it in with the assignment operator.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PerlinNoise3::
|
||||
PerlinNoise3() :
|
||||
PerlinNoise(0, 1)
|
||||
{
|
||||
_input_xform.fill(0.0f);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PerlinNoise3::Copy Constructor
|
||||
// Access: Published
|
||||
// Description: Makes an exact copy of the existing PerlinNoise
|
||||
// object, including its random seed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PerlinNoise3::
|
||||
PerlinNoise3(const PerlinNoise3 ©) :
|
||||
PerlinNoise(copy),
|
||||
_input_xform(copy._input_xform)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PerlinNoise3::Copy Assignment Operator
|
||||
// Access: Published
|
||||
// Description: Makes an exact copy of the existing PerlinNoise
|
||||
// object, including its random seed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PerlinNoise3::
|
||||
operator = (const PerlinNoise3 ©) {
|
||||
PerlinNoise::operator = (copy);
|
||||
_input_xform = copy._input_xform;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PerlinNoise3::noise
|
||||
// Access: Published
|
||||
@ -37,6 +80,36 @@ noise(const LVecBase3f &value) {
|
||||
return (float)noise(value[0], value[1], value[2]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PerlinNoise3::operator ()
|
||||
// Access: Published
|
||||
// Description: Returns the noise function of the three inputs.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE double PerlinNoise3::
|
||||
operator ()(double x, double y, double z) {
|
||||
return noise(x, y, z);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PerlinNoise3::noise
|
||||
// Access: Published
|
||||
// Description: Returns the noise function of the three inputs.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float PerlinNoise3::
|
||||
operator ()(const LVecBase3f &value) {
|
||||
return noise(value);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PerlinNoise3::noise
|
||||
// Access: Published
|
||||
// Description: Returns the noise function of the three inputs.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE double PerlinNoise3::
|
||||
operator ()(const LVecBase3d &value) {
|
||||
return noise(value);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PerlinNoise3::grad
|
||||
// Access: Private, Static
|
||||
@ -46,17 +119,38 @@ noise(const LVecBase3f &value) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE double PerlinNoise3::
|
||||
grad(int hash, double x, double y, double z) {
|
||||
// Convert lo 4 bits of hash code into 12 gradient directions.
|
||||
|
||||
int h = hash & 15;
|
||||
return _grad_table[h].dot(LVector3d(x, y, z));
|
||||
|
||||
// Convert low 4 bits of hash code into 12 gradient directions.
|
||||
/*
|
||||
This is Perlin's reference code, but the table lookup above is
|
||||
slightly faster (no jump instructions) and produces exactly the
|
||||
same results.
|
||||
This is Perlin's reference code, but the switch statement below is
|
||||
slightly faster and produces exactly the same results.
|
||||
int h = hash & 15;
|
||||
double u = (h < 8) ? x : y;
|
||||
double v = (h < 4) ? y : ((h == 12 || h == 14) ? x : z);
|
||||
return ((h & 1) ? -u : u) + ((h & 2) ? -v : v);
|
||||
*/
|
||||
|
||||
switch (hash & 15) {
|
||||
case 0: return x + y;
|
||||
case 1: return -x + y;
|
||||
case 2: return x - y;
|
||||
case 3: return -x - y;
|
||||
|
||||
case 4: return x + z;
|
||||
case 5: return -x + z;
|
||||
case 6: return x - z;
|
||||
case 7: return -x - z;
|
||||
|
||||
case 8: return y + z;
|
||||
case 9: return -y + z;
|
||||
case 10: return y - z;
|
||||
case 11: return -y - z;
|
||||
|
||||
case 12: return x + y;
|
||||
case 13: return -y + z;
|
||||
case 14: return -x + y;
|
||||
case 15: return -y - z;
|
||||
}
|
||||
|
||||
nassertr(false, 0);
|
||||
return 0;
|
||||
}
|
||||
|
@ -19,28 +19,6 @@
|
||||
#include "perlinNoise3.h"
|
||||
#include "cmath.h"
|
||||
|
||||
LVector3d PerlinNoise3::_grad_table[16] = {
|
||||
LVector3d(1, 1, 0),
|
||||
LVector3d(-1, 1, 0),
|
||||
LVector3d(1, -1, 0),
|
||||
LVector3d(-1, -1, 0),
|
||||
|
||||
LVector3d(1, 0, 1),
|
||||
LVector3d(-1, 0, 1),
|
||||
LVector3d(1, 0, -1),
|
||||
LVector3d(-1, 0, -1),
|
||||
|
||||
LVector3d(0, 1, 1),
|
||||
LVector3d(0, -1, 1),
|
||||
LVector3d(0, 1, -1),
|
||||
LVector3d(0, -1, -1),
|
||||
|
||||
LVector3d(1, 1, 0),
|
||||
LVector3d(0, -1, 1),
|
||||
LVector3d(-1, 1, 0),
|
||||
LVector3d(0, -1, -1),
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PerlinNoise3::Constructor
|
||||
// Access: Published
|
||||
@ -90,21 +68,26 @@ noise(const LVecBase3d &value) {
|
||||
double z = vec._v.v._2;
|
||||
|
||||
// Find unit cube that contains point.
|
||||
int X = cmod((int)cfloor(x), _table_size);
|
||||
int Y = cmod((int)cfloor(y), _table_size);
|
||||
int Z = cmod((int)cfloor(z), _table_size);
|
||||
double xf = cfloor(x);
|
||||
double yf = cfloor(y);
|
||||
double zf = cfloor(z);
|
||||
|
||||
int X = ((int)xf) & _table_size_mask;
|
||||
int Y = ((int)yf) & _table_size_mask;
|
||||
int Z = ((int)zf) & _table_size_mask;
|
||||
|
||||
// Find relative x,y,z of point in cube.
|
||||
x -= cfloor(x);
|
||||
y -= cfloor(y);
|
||||
z -= cfloor(z);
|
||||
x -= xf;
|
||||
y -= yf;
|
||||
z -= zf;
|
||||
|
||||
// Compute fade curves for each of x,y,z.
|
||||
double u = fade(x);
|
||||
double v = fade(y);
|
||||
double w = fade(z);
|
||||
|
||||
// Hash coordinates of the 8 cube corners . . .
|
||||
// Hash coordinates of the 8 cube corners. The 8 corners correspond
|
||||
// to AA, BA, AB, BB, AA + 1, BA + 1, AB + 1, and BB + 1.
|
||||
int A = _index[X] + Y;
|
||||
int AA = _index[A] + Z;
|
||||
int AB = _index[A + 1] + Z;
|
||||
@ -112,7 +95,7 @@ noise(const LVecBase3d &value) {
|
||||
int BA = _index[B] + Z;
|
||||
int BB = _index[B + 1] + Z;
|
||||
|
||||
// . . . and add blended results from 8 corners of cube.
|
||||
// and add blended results from 8 corners of cube.
|
||||
double result =
|
||||
lerp(w, lerp(v, lerp(u, grad(_index[AA], x, y, z),
|
||||
grad(_index[BA], x - 1, y, z)),
|
||||
|
@ -31,21 +31,26 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA PerlinNoise3 : public PerlinNoise {
|
||||
PUBLISHED:
|
||||
INLINE PerlinNoise3();
|
||||
PerlinNoise3(double sx, double sy, double sz,
|
||||
int table_size = 256,
|
||||
unsigned long seed = 0);
|
||||
INLINE PerlinNoise3(const PerlinNoise3 ©);
|
||||
INLINE void operator = (const PerlinNoise3 ©);
|
||||
|
||||
INLINE double noise(double x, double y, double z);
|
||||
INLINE float noise(const LVecBase3f &value);
|
||||
double noise(const LVecBase3d &value);
|
||||
|
||||
INLINE double operator ()(double x, double y, double z);
|
||||
INLINE float operator ()(const LVecBase3f &value);
|
||||
INLINE double operator ()(const LVecBase3d &value);
|
||||
|
||||
private:
|
||||
INLINE static double grad(int hash, double x, double y, double z);
|
||||
|
||||
private:
|
||||
LMatrix4d _input_xform;
|
||||
|
||||
static LVector3d _grad_table[16];
|
||||
};
|
||||
|
||||
#include "perlinNoise3.I"
|
||||
|
@ -17,6 +17,17 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: StackedPerlinNoise2::Default Constructor
|
||||
// Access: Published
|
||||
// Description: Creates a StackedPerlinNoise2 object with no levels.
|
||||
// You should call add_level() to add each level by
|
||||
// hand.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE StackedPerlinNoise2::
|
||||
StackedPerlinNoise2() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: StackedPerlinNoise2::noise
|
||||
// Access: Published
|
||||
@ -36,3 +47,33 @@ INLINE float StackedPerlinNoise2::
|
||||
noise(const LVecBase2f &value) {
|
||||
return (float)noise(value[0], value[1]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: StackedPerlinNoise2::operator ()
|
||||
// Access: Published
|
||||
// Description: Returns the noise function of the three inputs.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE double StackedPerlinNoise2::
|
||||
operator ()(double x, double y) {
|
||||
return noise(x, y);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: StackedPerlinNoise2::noise
|
||||
// Access: Published
|
||||
// Description: Returns the noise function of the three inputs.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float StackedPerlinNoise2::
|
||||
operator ()(const LVecBase2f &value) {
|
||||
return noise(value);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: StackedPerlinNoise2::noise
|
||||
// Access: Published
|
||||
// Description: Returns the noise function of the three inputs.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE double StackedPerlinNoise2::
|
||||
operator ()(const LVecBase2d &value) {
|
||||
return noise(value);
|
||||
}
|
||||
|
@ -31,19 +31,70 @@
|
||||
StackedPerlinNoise2::
|
||||
StackedPerlinNoise2(double sx, double sy, int num_levels,
|
||||
double scale_factor, double amp_scale,
|
||||
int table_size, unsigned long seed) :
|
||||
_amp_scale(amp_scale)
|
||||
{
|
||||
int table_size, unsigned long seed) {
|
||||
_noises.reserve(num_levels);
|
||||
double amp = 1.0;
|
||||
for (int i = 0; i < num_levels; ++i) {
|
||||
PerlinNoise2 noise(sx, sy, table_size, seed);
|
||||
_noises.push_back(noise);
|
||||
add_level(noise, amp);
|
||||
|
||||
seed = noise.get_seed();
|
||||
amp *= amp_scale;
|
||||
sx /= scale_factor;
|
||||
sy /= scale_factor;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: StackedPerlinNoise2::Copy Constructor
|
||||
// Access: Published
|
||||
// Description: Creates an exact duplicate of the existing
|
||||
// StackedPerlinNoise2 object, including the random
|
||||
// seed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
StackedPerlinNoise2::
|
||||
StackedPerlinNoise2(const StackedPerlinNoise2 ©) :
|
||||
_noises(copy._noises)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: StackedPerlinNoise2::Copy Assignment Operator
|
||||
// Access: Published
|
||||
// Description: Creates an exact duplicate of the existing
|
||||
// StackedPerlinNoise2 object, including the random
|
||||
// seed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void StackedPerlinNoise2::
|
||||
operator = (const StackedPerlinNoise2 ©) {
|
||||
_noises = copy._noises;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: StackedPerlinNoise2::add_level
|
||||
// Access: Published
|
||||
// Description: Adds an arbitrary PerlinNoise2 object, and an
|
||||
// associated amplitude, to the stack.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void StackedPerlinNoise2::
|
||||
add_level(const PerlinNoise2 &level, double amp) {
|
||||
_noises.push_back(Noise());
|
||||
Noise &n = _noises.back();
|
||||
n._noise = level;
|
||||
n._amp = amp;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: StackedPerlinNoise2::clear
|
||||
// Access: Published
|
||||
// Description: Removes all levels from the stack. You must call
|
||||
// add_level() again to restore them.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void StackedPerlinNoise2::
|
||||
clear() {
|
||||
_noises.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: StackedPerlinNoise2::noise
|
||||
// Access: Published
|
||||
@ -51,13 +102,11 @@ StackedPerlinNoise2(double sx, double sy, int num_levels,
|
||||
////////////////////////////////////////////////////////////////////
|
||||
double StackedPerlinNoise2::
|
||||
noise(const LVecBase2d &value) {
|
||||
double result = 0.0f;
|
||||
double amp = 1.0f;
|
||||
double result = 0.0;
|
||||
|
||||
Noises::iterator ni;
|
||||
for (ni = _noises.begin(); ni != _noises.end(); ++ni) {
|
||||
result += (*ni).noise(value) * amp;
|
||||
amp *= _amp_scale;
|
||||
result += (*ni)._noise(value) * (*ni)._amp;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -31,18 +31,32 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA StackedPerlinNoise2 {
|
||||
PUBLISHED:
|
||||
StackedPerlinNoise2(double sx, double sy, int num_levels = 3,
|
||||
INLINE StackedPerlinNoise2();
|
||||
StackedPerlinNoise2(double sx, double sy, int num_levels = 2,
|
||||
double scale_factor = 4.0f, double amp_scale = 0.5f,
|
||||
int table_size = 256, unsigned long seed = 0);
|
||||
StackedPerlinNoise2(const StackedPerlinNoise2 ©);
|
||||
void operator = (const StackedPerlinNoise2 ©);
|
||||
|
||||
void add_level(const PerlinNoise2 &level, double amp = 1.0);
|
||||
void clear();
|
||||
|
||||
INLINE double noise(double x, double y);
|
||||
INLINE float noise(const LVecBase2f &value);
|
||||
double noise(const LVecBase2d &value);
|
||||
|
||||
private:
|
||||
double _amp_scale;
|
||||
INLINE double operator ()(double x, double y);
|
||||
INLINE float operator ()(const LVecBase2f &value);
|
||||
INLINE double operator ()(const LVecBase2d &value);
|
||||
|
||||
typedef pvector<PerlinNoise2> Noises;
|
||||
private:
|
||||
class Noise {
|
||||
public:
|
||||
PerlinNoise2 _noise;
|
||||
double _amp;
|
||||
};
|
||||
|
||||
typedef pvector<Noise> Noises;
|
||||
Noises _noises;
|
||||
};
|
||||
|
||||
|
@ -17,6 +17,17 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: StackedPerlinNoise3::Default Constructor
|
||||
// Access: Published
|
||||
// Description: Creates a StackedPerlinNoise3 object with no levels.
|
||||
// You should call add_level() to add each level by
|
||||
// hand.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE StackedPerlinNoise3::
|
||||
StackedPerlinNoise3() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: StackedPerlinNoise3::noise
|
||||
// Access: Published
|
||||
@ -36,3 +47,33 @@ INLINE float StackedPerlinNoise3::
|
||||
noise(const LVecBase3f &value) {
|
||||
return (float)noise(value[0], value[1], value[2]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: StackedPerlinNoise3::operator ()
|
||||
// Access: Published
|
||||
// Description: Returns the noise function of the three inputs.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE double StackedPerlinNoise3::
|
||||
operator ()(double x, double y, double z) {
|
||||
return noise(x, y, z);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: StackedPerlinNoise3::noise
|
||||
// Access: Published
|
||||
// Description: Returns the noise function of the three inputs.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float StackedPerlinNoise3::
|
||||
operator ()(const LVecBase3f &value) {
|
||||
return noise(value);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: StackedPerlinNoise3::noise
|
||||
// Access: Published
|
||||
// Description: Returns the noise function of the three inputs.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE double StackedPerlinNoise3::
|
||||
operator ()(const LVecBase3d &value) {
|
||||
return noise(value);
|
||||
}
|
||||
|
@ -31,20 +31,71 @@
|
||||
StackedPerlinNoise3::
|
||||
StackedPerlinNoise3(double sx, double sy, double sz, int num_levels,
|
||||
double scale_factor, double amp_scale,
|
||||
int table_size, unsigned long seed) :
|
||||
_amp_scale(amp_scale)
|
||||
{
|
||||
int table_size, unsigned long seed) {
|
||||
_noises.reserve(num_levels);
|
||||
double amp = 1.0;
|
||||
for (int i = 0; i < num_levels; ++i) {
|
||||
PerlinNoise3 noise(sx, sy, sz, table_size, seed);
|
||||
_noises.push_back(noise);
|
||||
add_level(noise, amp);
|
||||
|
||||
seed = noise.get_seed();
|
||||
amp *= amp_scale;
|
||||
sx /= scale_factor;
|
||||
sy /= scale_factor;
|
||||
sz /= scale_factor;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: StackedPerlinNoise3::Copy Constructor
|
||||
// Access: Published
|
||||
// Description: Creates an exact duplicate of the existing
|
||||
// StackedPerlinNoise3 object, including the random
|
||||
// seed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
StackedPerlinNoise3::
|
||||
StackedPerlinNoise3(const StackedPerlinNoise3 ©) :
|
||||
_noises(copy._noises)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: StackedPerlinNoise3::Copy Assignment Operator
|
||||
// Access: Published
|
||||
// Description: Creates an exact duplicate of the existing
|
||||
// StackedPerlinNoise3 object, including the random
|
||||
// seed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void StackedPerlinNoise3::
|
||||
operator = (const StackedPerlinNoise3 ©) {
|
||||
_noises = copy._noises;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: StackedPerlinNoise3::add_level
|
||||
// Access: Published
|
||||
// Description: Adds an arbitrary PerlinNoise3 object, and an
|
||||
// associated amplitude, to the stack.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void StackedPerlinNoise3::
|
||||
add_level(const PerlinNoise3 &level, double amp) {
|
||||
_noises.push_back(Noise());
|
||||
Noise &n = _noises.back();
|
||||
n._noise = level;
|
||||
n._amp = amp;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: StackedPerlinNoise3::clear
|
||||
// Access: Published
|
||||
// Description: Removes all levels from the stack. You must call
|
||||
// add_level() again to restore them.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void StackedPerlinNoise3::
|
||||
clear() {
|
||||
_noises.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: StackedPerlinNoise3::noise
|
||||
// Access: Published
|
||||
@ -52,13 +103,11 @@ StackedPerlinNoise3(double sx, double sy, double sz, int num_levels,
|
||||
////////////////////////////////////////////////////////////////////
|
||||
double StackedPerlinNoise3::
|
||||
noise(const LVecBase3d &value) {
|
||||
double result = 0.0f;
|
||||
double amp = 1.0f;
|
||||
double result = 0.0;
|
||||
|
||||
Noises::iterator ni;
|
||||
for (ni = _noises.begin(); ni != _noises.end(); ++ni) {
|
||||
result += (*ni).noise(value) * amp;
|
||||
amp *= _amp_scale;
|
||||
result += (*ni)._noise(value) * (*ni)._amp;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -31,18 +31,32 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA StackedPerlinNoise3 {
|
||||
PUBLISHED:
|
||||
INLINE StackedPerlinNoise3();
|
||||
StackedPerlinNoise3(double sx, double sy, double sz, int num_levels = 3,
|
||||
double scale_factor = 4.0f, double amp_scale = 0.5f,
|
||||
int table_size = 256, unsigned long seed = 0);
|
||||
StackedPerlinNoise3(const StackedPerlinNoise3 ©);
|
||||
void operator = (const StackedPerlinNoise3 ©);
|
||||
|
||||
void add_level(const PerlinNoise3 &level, double amp = 1.0);
|
||||
void clear();
|
||||
|
||||
INLINE double noise(double x, double y, double z);
|
||||
INLINE float noise(const LVecBase3f &value);
|
||||
double noise(const LVecBase3d &value);
|
||||
|
||||
private:
|
||||
double _amp_scale;
|
||||
INLINE double operator ()(double x, double y, double z);
|
||||
INLINE float operator ()(const LVecBase3f &value);
|
||||
INLINE double operator ()(const LVecBase3d &value);
|
||||
|
||||
typedef pvector<PerlinNoise3> Noises;
|
||||
private:
|
||||
class Noise {
|
||||
public:
|
||||
PerlinNoise3 _noise;
|
||||
double _amp;
|
||||
};
|
||||
|
||||
typedef pvector<Noise> Noises;
|
||||
Noises _noises;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user