LCOV - code coverage report
Current view: top level - shared - PerlinNoise.cpp (source / functions) Hit Total Coverage
Test: code-coverage.info.cleaned Lines: 34 34 100.0 %
Date: 2023-01-28 00:08:57 Functions: 5 5 100.0 %

          Line data    Source code
       1             : #include <shared.hpp>
       2             : #include <cmath>
       3             : #include <random>
       4             : #include <algorithm>
       5             : #include <numeric>
       6             : 
       7             : // THIS IS A DIRECT TRANSLATION TO C++11 FROM THE REFERENCE
       8             : // JAVA IMPLEMENTATION OF THE IMPROVED PERLIN FUNCTION (see http://mrl.nyu.edu/~perlin/noise/)
       9             : // THE ORIGINAL JAVA IMPLEMENTATION IS COPYRIGHT 2002 KEN PERLIN
      10             : 
      11             : using namespace shared;
      12             : 
      13             : // Generate a new permutation vector based on the value of seed
      14           3 : PerlinNoise::PerlinNoise(unsigned int seed)
      15             : {
      16           3 :         p.resize(256);
      17             : 
      18             :         // Fill p with values from 0 to 255
      19           3 :         std::iota(p.begin(), p.end(), 0);
      20             : 
      21             :         // Initialize a random engine with seed
      22           3 :         std::default_random_engine engine(seed);
      23             : 
      24             :         // Suffle  using the above random engine
      25           3 :         std::shuffle(p.begin(), p.end(), engine);
      26             : 
      27             :         // Duplicate the permutation vector
      28           3 :         p.insert(p.end(), p.begin(), p.end());
      29           3 : }
      30             : 
      31         500 : double PerlinNoise::noise(double x, double y, double z)
      32             : {
      33             :         // Find the unit cube that contains the point
      34         500 :         int X = (int)floor(x) & 255;
      35         500 :         int Y = (int)floor(y) & 255;
      36         500 :         int Z = (int)floor(z) & 255;
      37             : 
      38             :         // Find relative x, y,z of point in cube
      39         500 :         x -= floor(x);
      40         500 :         y -= floor(y);
      41         500 :         z -= floor(z);
      42             : 
      43             :         // Compute fade curves for each of x, y, z
      44         500 :         double u = fade(x);
      45         500 :         double v = fade(y);
      46         500 :         double w = fade(z);
      47             : 
      48             :         // Hash coordinates of the 8 cube corners
      49         500 :         int A = p[X] + Y;
      50         500 :         int AA = p[A] + Z;
      51         500 :         int AB = p[A + 1] + Z;
      52         500 :         int B = p[X + 1] + Y;
      53         500 :         int BA = p[B] + Z;
      54         500 :         int BB = p[B + 1] + Z;
      55             : 
      56             :         // Add blended results from 8 corners of cube
      57         500 :         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))));
      58         500 :         return (res + 1.0) / 2.0;
      59             : }
      60             : 
      61        1500 : double PerlinNoise::fade(double t)
      62             : {
      63        1500 :         return t * t * t * (t * (t * 6 - 15) + 10);
      64             : }
      65             : 
      66        3500 : double PerlinNoise::lerp(double t, double a, double b)
      67             : {
      68        3500 :         return a + t * (b - a);
      69             : }
      70             : 
      71        4000 : double PerlinNoise::grad(int hash, double x, double y, double z)
      72             : {
      73        4000 :         int h = hash & 15;
      74             :         // Convert lower 4 bits of hash into 12 gradient directions
      75        4000 :         double u = h < 8 ? x : y,
      76        4000 :                    v = h < 4 ? y : h == 12 || h == 14 ? x
      77             :                                                                                           : z;
      78        4000 :         return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
      79             : }

Generated by: LCOV version 1.14