src/PerlinNoise.h

Go to the documentation of this file.
00001 #ifndef PERLINNOISE_H
00002 #define PERLINNOISE_H
00003 
00004 #include<cmath>
00005 
00006 
00012 class PerlinNoise
00013 {
00017   public:
00019 
00022     PerlinNoise(const float persistence, const float frequency, const int octaves)
00023         :mPersistence(persistence),
00024           mFrequency(frequency),
00025           mOctaves(octaves)
00026         {}
00027     
00030     ~PerlinNoise()
00031     {
00032     }
00033     
00039     const float perlinNoise(float x, float y) const
00040     {
00041         float frequency = mFrequency;
00042         float total = 0.0;
00043         for (float round = 0.0f; round < mOctaves; round += 1.0f)
00044         {
00045             const float amplitude = powf(mPersistence, round);
00046             
00047             total += interpolatedNoise(x * frequency, y * frequency) * amplitude;
00048             frequency *= 2;
00049         }
00050         return total;
00051     }
00052 
00053 
00059     const float perlinNoise3D(float x, float y, float z) const
00060     {
00061                 float frequency = mFrequency;
00062         float total = 0.0;
00063         for (float round = 0.0f; round < mOctaves; round += 1.0f)
00064         {
00065             const float amplitude = powf(mPersistence, round);
00066             
00067             total += interpolatedNoise3D(x * frequency, y * frequency, z * frequency) * amplitude;
00068             frequency *= 2;
00069         }
00070         return total;
00071     }
00072     
00073   protected:
00074     
00075   private:
00076     const float mPersistence;   
00077     const float mFrequency;     
00078     const int mOctaves;         
00079 
00080 
00083     const float noise(const int x, const int y) const
00084     {
00085         int n = x + y * 57;
00086         n = n<<13 ^ n;
00087         return ( 1.0 - ( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0); // *magic*
00088     }
00089     
00090     
00093     const float cosInterpolate(const float a, const float b, const float x) const
00094     {
00095         float f = (1 - cosf(x*M_PI)) * 0.5;
00096         return  a*(1-f) + b*f;
00097     }
00098     
00099     
00102     const float weightedNoise(const int x, const int y) const
00103     {
00104         const float corners = ( noise(x-1, y-1) + noise(x+1, y-1) + noise(x-1, y+1) + noise(x+1, y+1) ) / 16;
00105         const float sides   = ( noise(x-1, y) + noise(x+1, y) + noise(x, y-1) + noise(x, y+1) ) /  8;
00106         const float center  =  noise(x, y) / 4;
00107         return corners + sides + center;
00108     }
00109     
00110 
00113     const float interpolatedNoise(const float x, const float y) const
00114     {
00115         const int intX    = int(x);
00116         const float fracX = x - intX;
00117         
00118         const int intY    = int(y);
00119         const float fracY = y - intY;
00120         
00121         const float v1 = weightedNoise(intX,     intY);
00122         const float v2 = weightedNoise(intX + 1, intY);
00123         const float v3 = weightedNoise(intX,     intY + 1);
00124         const float v4 = weightedNoise(intX + 1, intY + 1);
00125         
00126         const float i1 = cosInterpolate(v1 , v2 , fracX);
00127         const float i2 = cosInterpolate(v3 , v4 , fracX);
00128         
00129         return cosInterpolate(i1 , i2 , fracY);
00130     }
00131 
00132 
00133 
00134 //------------------- 3d noise
00135 
00138     const float noise3D(const int x, const int y, const int z) const
00139     {
00140         int n = x + y * 57 + z * 63;
00141         n = n<<13 ^ n;
00142         return ( 1.0 - ( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0); // *magic*
00143     }
00144     
00145 
00146 
00149     const float interpolatedNoise3D(const float x, const float y, const float z) const
00150     {
00151         
00152         const int intX    = int(x);
00153         const float fracX = x - intX;
00154         
00155         const int intY    = int(y);
00156         const float fracY = y - intY;
00157         
00158         const int intZ    = int(z);
00159         const float fracZ = z - intZ;
00160 
00161         const float v1 = noise3D(intX,     intY,    intZ);
00162         const float v2 = noise3D(intX + 1, intY,    intZ);
00163         const float v3 = noise3D(intX,     intY + 1,intZ);
00164         const float v4 = noise3D(intX + 1, intY + 1,intZ);
00165         
00166 
00167         const float w1 = noise3D(intX,     intY,    intZ + 1);
00168         const float w2 = noise3D(intX + 1, intY,    intZ + 1);
00169         const float w3 = noise3D(intX,     intY + 1,intZ + 1);
00170         const float w4 = noise3D(intX + 1, intY + 1,intZ + 1);
00171         return lerp(fracZ, lerp(fracY, lerp(fracX, v1, v2), lerp(fracX, v3, v4)),
00172                            lerp(fracY, lerp(fracX, w1, w2), lerp(fracX, w3, w4)));
00173     }
00174     
00175 };  
00176 #endif

Generated on Fri Feb 1 00:01:42 2008 for Grayfall by  doxygen 1.5.1