154 lines
4.4 KiB
C++
154 lines
4.4 KiB
C++
// Copyright (C) 2007 Id Software, Inc.
|
|
//
|
|
|
|
|
|
#ifndef __MATH_PERLIN_H__
|
|
#define __MATH_PERLIN_H__
|
|
|
|
/*
|
|
===============================================================================
|
|
|
|
Perlin 3D noise generator
|
|
|
|
===============================================================================
|
|
*/
|
|
|
|
class sdPerlin {
|
|
public:
|
|
//if alternative is true use other seed primes so we get a different noise shape
|
|
sdPerlin( float _persistence = 0.5f, int _octaves = 4, float _frequency = 1.0f );
|
|
|
|
void SetTileX( int tile );
|
|
void SetTileY( int tile );
|
|
void SetTileZ( int tile );
|
|
|
|
float NoiseFloat( const idVec3 &pos ); // random number in the range [-1.0f, 1.0f]
|
|
int NoiseInt( const idVec3 &pos, int max ); // random integer in the range [0, max]
|
|
float RawNoise( int x, int y, int z );
|
|
|
|
private:
|
|
float persistence;
|
|
float frequency;
|
|
int octaves;
|
|
|
|
int tilex;
|
|
int tiley;
|
|
int tilez;
|
|
|
|
int localtilex; //for lower octaves with increased frequency
|
|
int localtiley;
|
|
int localtilez;
|
|
|
|
float CosineInterp( float number1, float number2, float x );
|
|
//float SmoothedNoise( int x, int y, int z );
|
|
float InterpolatedNoise( float x, float y, float z );
|
|
};
|
|
|
|
ID_INLINE int sdPerlin::NoiseInt( const idVec3 &pos, int max ) {
|
|
return idMath::Ftoi( NoiseFloat( pos ) * max );
|
|
}
|
|
|
|
ID_INLINE float sdPerlin::CosineInterp( float number1, float number2, float x ) {
|
|
float f = ( 1 - idMath::Cos16( x * idMath::PI ) ) * 0.5f;
|
|
return number1 * ( 1 - f ) + number2 * f;
|
|
}
|
|
|
|
#if 0
|
|
|
|
const int PERLIN_RANDOM_SAMPLES = 256;
|
|
|
|
class sdPerlin2 {
|
|
public:
|
|
sdPerlin2( void );
|
|
|
|
static void Init( void );
|
|
float Noise( const idVec3& noisePos );
|
|
|
|
protected:
|
|
static bool inited;
|
|
static int p[ ( PERLIN_RANDOM_SAMPLES + 1 ) * 2 ];
|
|
static idVec3 g[ ( PERLIN_RANDOM_SAMPLES + 1 ) * 2 ];
|
|
};
|
|
|
|
#endif // 0
|
|
|
|
const int NOISE_WRAP_INDEX = 256;
|
|
const int NOISE_MOD_MASK = 255;
|
|
const int NOISE_LARGE_PWR2 = 4096;
|
|
|
|
class sdPerlin2 {
|
|
private:
|
|
unsigned long initialized;
|
|
|
|
unsigned long permutationTable[ NOISE_WRAP_INDEX* 2 + 2 ]; // permutation table
|
|
float gradientTable1d[ NOISE_WRAP_INDEX * 2 + 2 ]; // 1d gradient lookup table.
|
|
float gradientTable2d[ NOISE_WRAP_INDEX * 2 + 2 ][ 2 ]; // 2d gradient lookup table.
|
|
float gradientTable3d[ NOISE_WRAP_INDEX * 2 + 2 ][ 3 ]; // 3d gradient lookup table.
|
|
|
|
float RandNoiseFloat( void ); // generate a random float in [-1,1]
|
|
void Normalize2d( float* vector ); // normalize a 2d vector
|
|
void Normalize3d( float* vector ); // normalize a 3d vector
|
|
void GenerateLookupTables( void ); // fill in table entries
|
|
|
|
public:
|
|
sdPerlin2() :
|
|
initialized( 0 ) {
|
|
}
|
|
void Reseed( void ); // reseed random generator & regenerate tables
|
|
void Reseed( unsigned int rSeed ); // same, but with specified seed
|
|
|
|
float Noise1d( float* pos ); // 1D call using an array for passing pos
|
|
float Noise2d( float* pos ); // 2D call using an array for passing pos
|
|
float Noise3d( float* pos ); // 3D call using an array for passing pos
|
|
|
|
float Noise( float ); // use individual elements for passing pos
|
|
float Noise( float, float );
|
|
float Noise( float, float, float );
|
|
};
|
|
|
|
class sdPerlin3 {
|
|
public:
|
|
static float Noise1D( float* pos );
|
|
static float Noise2D( float* pos );
|
|
static float Noise3D( float* pos );
|
|
|
|
static float Noise( float x );
|
|
static float Noise( float x, float y );
|
|
static float Noise( float x, float y, float z );
|
|
|
|
private:
|
|
static float Fade( float t );
|
|
static float Lerp( float t, float a, float b );
|
|
static float Grad( int hash, float x, float y, float z );
|
|
|
|
private:
|
|
static int p[ 512 ];
|
|
};
|
|
|
|
ID_INLINE float sdPerlin3::Noise1D( float* pos ) {
|
|
return Noise( *pos );
|
|
}
|
|
|
|
ID_INLINE float sdPerlin3::Noise2D( float* pos ) {
|
|
return Noise( *pos, *(pos + 1) );
|
|
}
|
|
|
|
ID_INLINE float sdPerlin3::Noise3D( float* pos ) {
|
|
return Noise( *pos, *(pos + 1), *(pos + 2) );
|
|
}
|
|
|
|
ID_INLINE float sdPerlin3::Fade( float t ) {
|
|
return( t * t * t * ( t * ( t * 6 - 15 ) + 10 ) );
|
|
}
|
|
|
|
ID_INLINE float sdPerlin3::Lerp( float t, float a, float b ) {
|
|
return( a + t * ( b - a ) );
|
|
}
|
|
ID_INLINE float sdPerlin3::Grad( int hash, float x, float y, float z ) {
|
|
int h = hash & 14;
|
|
float u = h < 8 ? x : y;
|
|
float v = h < 4 ? y : ( h == 12 || h == 14 ? x : z );
|
|
return( ( ( h & 1 ) == 0 ? u : -u ) + ( ( h & 2 ) == 0 ? v : -v ) );
|
|
}
|
|
|
|
#endif //__MATH_PERLIN_H__
|