/* * See Copyright Notice in perlin.h */ #include #include #include #include #include #include "perlin.h" PerlinNoise::PerlinNoise( unsigned seed ) { if(seed==0) seed = std::mt19937::default_seed; // p[0]..p[255] contains all numbers in [0..255] in random order std::iota(std::begin(p),std::begin(p)+256,0); std::shuffle(std::begin(p),std::begin(p)+256,std::mt19937(seed)); for(int i=0; i<256; ++i) p[256+i] = p[i]; } double PerlinNoise::noise( double x, double y, double z ) const { const int X = static_cast(::floor(x)) & 255; const int Y = static_cast(::floor(y)) & 255; const int Z = static_cast(::floor(z)) & 255; x -= ::floor(x); y -= ::floor(y); z -= ::floor(z); const double u = fade(x); const double v = fade(y); const double w = fade(z); const int A = p[X ]+Y, AA = p[A]+Z, AB = p[A+1]+Z; const int B = p[X+1]+Y, BA = p[B]+Z, BB = p[B+1]+Z; return lerp(w, lerp(v, lerp(u, grad(p[AA ], x , y , z ), grad(p[BA ], x-1, y , z )), lerp(u, grad(p[AB ], x , y-1, z ), grad(p[BB ], x-1, y-1, z ))), lerp(v, lerp(u, grad(p[AA+1], x , y , z-1 ), grad(p[BA+1], x-1, y , z-1 )), lerp(u, grad(p[AB+1], x , y-1, z-1 ), grad(p[BB+1], x-1, y-1, z-1 )))); } double PerlinNoise::octaveNoise( double x, int octaves ) const { double result = 0.0; double amp = 1.0; for(int i=0; i