1 #ifndef PerlinNoise_HXX
  2 #define PerlinNoise_HXX
  3 
  4 /**
  5  * As the PerlinNoise written in the exercises
  6  * but from 2D to 3D
  7  */
  8 class PerlinNoise
  9 {
 10     private:
 11         /**
 12          * 'random' generator
 13          */
 14         float Noise3D (int x, int y, int z)
 15         {
 16             int n = x + y * 57 + z * 3366;
 17             n = (n << 13) ^ n;
 18             float r = ( 1.0 - ( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);
 19             return r;   
 20         }  
 21 
 22         /**
 23          * get interpolated noise around the given pixel in all three dimensions
 24          * therefore: average the noise of all neighbour pixels
 25          */
 26         float SmoothNoise3D (int x, int y, int z)
 27         {
 28             float result = 0.0;
 29             
 30             for (int i = -1; i <= 1; i++)
 31               for (int j = -1; j <= 1; j++)
 32                 for (int k = -1; k <= 1; k++)
 33                     result += Noise3D(x-i,y-j,z-k);
 34                     
 35             float average = result / ( powf(3.0,3.0) );
 36                     
 37             return average;
 38         }
 39 
 40         /**
 41          * cosine interpolation
 42          */
 43         float cosrp(float a, float b, float x)
 44         {
 45             float f = x * (float) M_PI;
 46             f = (1 - cosf(f)) * .5f;
 47             return lerp(a,b,f);
 48         }
 49     
 50     public:
 51         PerlinNoise()
 52         {};
 53         
 54         ~PerlinNoise()
 55         {};
 56         
 57         /**
 58          * interpolation around a given point 'a'
 59          * nearly the same as for one of the exercise sheet, just one dimension added
 60          */  
 61         float Interpolation( Vec3f a )
 62         {
 63             int int_x = (int) floorf(a.x());
 64             int int_y = (int) floorf(a.y());
 65             int int_z = (int) floorf(a.z());
 66 
 67             float frac_x = a.x() - int_x;
 68             float frac_y = a.y() - int_y;
 69             float frac_z = a.z() - int_z;
 70             
 71             float value[2];
 72             for (int i = 0; i <= 1; i++)
 73             {
 74                 float v1 = SmoothNoise3D(int_x + 0, int_y + 0, int_z + i);
 75                 float v2 = SmoothNoise3D(int_x + 1, int_y + 0, int_z + i);
 76                 float v3 = SmoothNoise3D(int_x + 0, int_y + 1, int_z + i);
 77                 float v4 = SmoothNoise3D(int_x + 1, int_y + 1, int_z + i);
 78 
 79                 float i1 = cosrp(v1, v2, frac_x);
 80                 float i2 = cosrp(v3, v4, frac_x);
 81 
 82                 value[i] = cosrp(i1, i2, frac_y);   
 83             }
 84             
 85             return cosrp(value[0] , value[1] , frac_z);
 86         }   
 87   
 88         /**
 89          * main function
 90          */
 91         float PerlinNoise3D(Vec3f point, float persistence, float octaves)
 92         {
 93             float result    = 0.0;
 94             float amplitude = 1.0;
 95             float frequency = 1.0;
 96         
 97             for (int i = 0; i < octaves; i++)
 98             {
 99                 result += Interpolation( frequency * point ) * amplitude;
100                 
101                 frequency *= 2.0;
102                 amplitude *= persistence;
103             }
104             
105             return result;
106         }
107 };
108 
109 #endif


syntax highlighted by Code2HTML, v. 0.9.1