PerlinNoise.cpp 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. #include "PerlinNoise.h"
  2. #include "Constants.h"
  3. #include <random>
  4. #include <algorithm>
  5. PerlinNoise::PerlinNoise( int seed )
  6. : Noise()
  7. {
  8. this->seed = seed;
  9. p.resize( 256 );
  10. std::iota( p.begin(), p.end(), 0 );
  11. std::default_random_engine engine( seed );
  12. std::shuffle( p.begin(), p.end(), engine );
  13. p.insert( p.end(), p.begin(), p.end() );
  14. }
  15. int PerlinNoise::getSeed() const
  16. {
  17. return seed;
  18. }
  19. double PerlinNoise::getNoise( double x, double y, double z )
  20. {
  21. x = (double)((int)x % (CHUNK_SIZE * 10)) / (CHUNK_SIZE * 10);
  22. y = (double)((int)y % (CHUNK_SIZE * 10)) / (CHUNK_SIZE * 10);
  23. z = (double)((int)z % (CHUNK_SIZE * 10)) / (CHUNK_SIZE * 10);
  24. // Find the unit cube that contains the point
  25. int X = (int)floor( x ) & 255;
  26. int Y = (int)floor( y ) & 255;
  27. int Z = (int)floor( z ) & 255;
  28. // Find relative x, y,z of point in cube
  29. x -= floor( x );
  30. y -= floor( y );
  31. z -= floor( z );
  32. // Compute fade curves for each of x, y, z
  33. double u = fade( x );
  34. double v = fade( y );
  35. double w = fade( z );
  36. // Hash coordinates of the 8 cube corners
  37. int A = p[ X ] + Y;
  38. int AA = p[ A ] + Z;
  39. int AB = p[ A + 1 ] + Z;
  40. int B = p[ X + 1 ] + Y;
  41. int BA = p[ B ] + Z;
  42. int BB = p[ B + 1 ] + Z;
  43. // Add blended results from 8 corners of cube
  44. double res = 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 ) ) ) );
  45. // TODO: why is res here allways 0?
  46. return (res + 1.0) / 2.0;
  47. }
  48. double PerlinNoise::fade( double t ) const
  49. {
  50. return t * t * t * (t * (t * 6 - 15) + 10);
  51. }
  52. double PerlinNoise::lerp( double t, double a, double b ) const
  53. {
  54. return a + t * (b - a);
  55. }
  56. double PerlinNoise::grad( int hash, double x, double y, double z ) const
  57. {
  58. int h = hash & 15;
  59. // Convert lower 4 bits of hash into 12 gradient directions
  60. double u = h < 8 ? x : y,
  61. v = h < 4 ? y : h == 12 || h == 14 ? x : z;
  62. return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
  63. }