| /* |
| * PerlinNoise.hpp |
| * |
| * Created on: Jul 11, 2008 |
| * Author: pete |
| */ |
| |
| #ifndef PERLINNOISE_HPP_ |
| #define PERLINNOISE_HPP_ |
| |
| #include <math.h> |
| |
| |
| class PerlinNoise |
| { |
| public: |
| float noise_lq[256][256]; |
| float noise_lq_lite[32][32]; |
| float noise_mq[256][256]; |
| float noise_hq[256][256]; |
| float noise_perlin[512][512]; |
| float noise_lq_vol[32][32][32]; |
| float noise_hq_vol[32][32][32]; |
| |
| |
| PerlinNoise(); |
| virtual ~PerlinNoise(); |
| |
| private: |
| |
| static inline float noise( int x) |
| { |
| x = (x<<13)^x; |
| return (((x * (x * x * 15731 + 789221) + 1376312589) & 0x7fffffff) / 2147483648.0); |
| } |
| |
| static inline float noise(int x, int y) |
| { |
| int n = x + y * 57; |
| return noise(n); |
| } |
| |
| static inline float noise(int x, int y, int z) |
| { |
| int n = x + y * 57 + z * 141; |
| return noise(n); |
| } |
| |
| static inline float cos_interp(float a, float b, float x) |
| { |
| float ft = x * 3.1415927; |
| float f = (1 - cos(ft)) * .5; |
| |
| return a*(1-f) + b*f; |
| } |
| |
| static inline float cubic_interp(float v0, float v1, float v2, float v3, float x) |
| { |
| float P = (v3 - v2) - (v0 - v1); |
| float Q = (v0 - v1) - P; |
| float R = v2 - v0; |
| |
| return P*pow(x,3) + Q * pow(x,2) + R*x + v1; |
| } |
| |
| static inline float InterpolatedNoise(float x, float y) |
| { |
| int integer_X = int(x); |
| float fractional_X = x - integer_X; |
| |
| int integer_Y = int(y); |
| float fractional_Y = y - integer_Y; |
| |
| float a0 = noise(integer_X - 1, integer_Y - 1); |
| float a1 = noise(integer_X, integer_Y - 1); |
| float a2 = noise(integer_X + 1, integer_Y - 1); |
| float a3 = noise(integer_X + 2, integer_Y - 1); |
| |
| float x0 = noise(integer_X - 1, integer_Y); |
| float x1 = noise(integer_X, integer_Y); |
| float x2 = noise(integer_X + 1, integer_Y); |
| float x3 = noise(integer_X + 2, integer_Y); |
| |
| float y0 = noise(integer_X + 0, integer_Y + 1); |
| float y1 = noise(integer_X, integer_Y + 1); |
| float y2 = noise(integer_X + 1, integer_Y + 1); |
| float y3 = noise(integer_X + 2, integer_Y + 1); |
| |
| float b0 = noise(integer_X - 1, integer_Y + 2); |
| float b1 = noise(integer_X, integer_Y + 2); |
| float b2 = noise(integer_X + 1, integer_Y + 2); |
| float b3 = noise(integer_X + 2, integer_Y + 2); |
| |
| float i0 = cubic_interp(a0 , a1, a2, a3, fractional_X); |
| float i1 = cubic_interp(x0 , x1, x2, x3, fractional_X); |
| float i2 = cubic_interp(y0 , y1, y2, y3, fractional_X); |
| float i3 = cubic_interp(b0 , b1, b2, b3, fractional_X); |
| |
| return cubic_interp(i0, i1 , i2 , i3, fractional_Y); |
| |
| } |
| |
| static inline float perlin_octave_2d(float x,float y, int width, int seed, float period) |
| { |
| float freq=1/(float)(period); |
| |
| int num=(int)(width*freq); |
| int step_x=(int)(x*freq); |
| int step_y=(int)(y*freq); |
| float zone_x=x*freq-step_x; |
| float zone_y=y*freq-step_y; |
| int box=step_x+step_y*num; |
| int noisedata=(box+seed); |
| |
| float u=cubic_interp(noise(noisedata-num-1),noise(noisedata-num),noise(noisedata-num+1),noise(noisedata-num+2),zone_x); |
| float a=cubic_interp(noise(noisedata-1),noise(noisedata),noise(noisedata+1),noise(noisedata+2),zone_x); |
| float b=cubic_interp(noise(noisedata+num -1),noise(noisedata+num),noise(noisedata+1+num),noise(noisedata+2+num),zone_x); |
| float v=cubic_interp(noise(noisedata+2*num -1),noise(noisedata+2*num),noise(noisedata+1+2*num),noise(noisedata+2+2*num),zone_x); |
| |
| float value=cubic_interp(u,a,b,v,zone_y); |
| |
| return value; |
| } |
| |
| |
| static inline float perlin_octave_2d_cos(float x,float y, int width, int seed, float period) |
| { |
| float freq=1/(float)(period); |
| |
| int num=(int)(width*freq); |
| int step_x=(int)(x*freq); |
| int step_y=(int)(y*freq); |
| float zone_x=x*freq-step_x; |
| float zone_y=y*freq-step_y; |
| int box=step_x+step_y*num; |
| int noisedata=(box+seed); |
| |
| float a=cos_interp(noise(noisedata),noise(noisedata+1),zone_x); |
| float b=cos_interp(noise(noisedata+num),noise(noisedata+1+num),zone_x); |
| |
| float value=cos_interp(a,b,zone_y); |
| |
| return value; |
| } |
| |
| |
| |
| static inline float perlin_octave_3d(float x,float y, float z,int width, int seed, float period) |
| { |
| float freq=1/(float)(period); |
| |
| int num=(int)(width*freq); |
| int step_x=(int)(x*freq); |
| int step_y=(int)(y*freq); |
| int step_z=(int)(z*freq); |
| float zone_x=x*freq-step_x; |
| float zone_y=y*freq-step_y; |
| float zone_z=z*freq-step_z; |
| |
| int boxB=step_x+step_y+step_z*num; |
| int boxC=step_x+step_y+step_z*(num+1); |
| int boxD=step_x+step_y+step_z*(num+2); |
| int boxA=step_x+step_y+step_z*(num-1); |
| |
| float u,a,b,v,noisedata,box; |
| |
| box = boxA; |
| noisedata=(box+seed); |
| u=cubic_interp(noise(noisedata-num-1),noise(noisedata-num),noise(noisedata-num+1),noise(noisedata-num+2),zone_x); |
| a=cubic_interp(noise(noisedata-1),noise(noisedata),noise(noisedata+1),noise(noisedata+2),zone_x); |
| b=cubic_interp(noise(noisedata+num -1),noise(noisedata+num),noise(noisedata+1+num),noise(noisedata+2+num),zone_x); |
| v=cubic_interp(noise(noisedata+2*num -1),noise(noisedata+2*num),noise(noisedata+1+2*num),noise(noisedata+2+2*num),zone_x); |
| float A=cubic_interp(u,a,b,v,zone_y); |
| |
| box = boxB; |
| noisedata=(box+seed); |
| u=cubic_interp(noise(noisedata-num-1),noise(noisedata-num),noise(noisedata-num+1),noise(noisedata-num+2),zone_x); |
| a=cubic_interp(noise(noisedata-1),noise(noisedata),noise(noisedata+1),noise(noisedata+2),zone_x); |
| b=cubic_interp(noise(noisedata+num -1),noise(noisedata+num),noise(noisedata+1+num),noise(noisedata+2+num),zone_x); |
| v=cubic_interp(noise(noisedata+2*num -1),noise(noisedata+2*num),noise(noisedata+1+2*num),noise(noisedata+2+2*num),zone_x); |
| float B=cubic_interp(u,a,b,v,zone_y); |
| |
| box = boxC; |
| noisedata=(box+seed); |
| u=cubic_interp(noise(noisedata-num-1),noise(noisedata-num),noise(noisedata-num+1),noise(noisedata-num+2),zone_x); |
| a=cubic_interp(noise(noisedata-1),noise(noisedata),noise(noisedata+1),noise(noisedata+2),zone_x); |
| b=cubic_interp(noise(noisedata+num -1),noise(noisedata+num),noise(noisedata+1+num),noise(noisedata+2+num),zone_x); |
| v=cubic_interp(noise(noisedata+2*num -1),noise(noisedata+2*num),noise(noisedata+1+2*num),noise(noisedata+2+2*num),zone_x); |
| float C=cubic_interp(u,a,b,v,zone_y); |
| |
| box = boxD; |
| noisedata=(box+seed); |
| u=cubic_interp(noise(noisedata-num-1),noise(noisedata-num),noise(noisedata-num+1),noise(noisedata-num+2),zone_x); |
| a=cubic_interp(noise(noisedata-1),noise(noisedata),noise(noisedata+1),noise(noisedata+2),zone_x); |
| b=cubic_interp(noise(noisedata+num -1),noise(noisedata+num),noise(noisedata+1+num),noise(noisedata+2+num),zone_x); |
| v=cubic_interp(noise(noisedata+2*num -1),noise(noisedata+2*num),noise(noisedata+1+2*num),noise(noisedata+2+2*num),zone_x); |
| float D=cubic_interp(u,a,b,v,zone_y); |
| |
| float value =cubic_interp(A,B,C,D,zone_z); |
| |
| return value; |
| } |
| |
| |
| static inline float perlin_noise_2d(int x, int y, int width, int octaves, int seed, float persistance, float basePeriod) |
| { |
| float p = persistance; |
| float val = 0.0; |
| |
| for (int i = 0; i<octaves;i++) |
| { |
| val += perlin_octave_2d_cos(x,y,width,seed,basePeriod) * p; |
| |
| basePeriod *= 0.5; |
| p *= persistance; |
| } |
| return val; |
| } |
| |
| static inline float perlin_noise_3d(int x, int y, int z, int width, int octaves, int seed, float persistance, float basePeriod) |
| { |
| float p = persistance; |
| float val = 0.0; |
| |
| for (int i = 0; i<octaves;i++) |
| { |
| val += perlin_octave_3d(x,y,z,width,seed,basePeriod) * p; |
| |
| basePeriod *= 0.5; |
| p *= persistance; |
| } |
| return val; |
| } |
| }; |
| |
| #endif /* PERLINNOISE_HPP_ */ |