1 /** 2 Holds the noise generator. Mostly a copy and reimplementation of https://gist.github.com/KdotJPG/b1270127455a94ac5d19 and http://uniblock.tumblr.com/ 3 */ 4 module dosimplex.generator; 5 6 import dosimplex.osimplex2d; 7 import dosimplex.osimplex3d; 8 import dosimplex.osimplex4d; 9 import dosimplex.seed; 10 import dosimplex.util; 11 12 13 /** 14 The noise generator. 15 somehow impelments OpenSimplexNoise - https://gist.github.com/KdotJPG/b1270127455a94ac5d19 and http://uniblock.tumblr.com/ 16 */ 17 struct SNoiseGenerator 18 { 19 /// (Default) Values for noise generation 20 enum : long { 21 DEFAULT_SEED = 1787569, /// why not 22 }; 23 24 /// Disabled Default struct constructor 25 @disable this(); 26 27 /// Initializes a generator from a long seed 28 @nogc @safe this(long seed) 29 { 30 short[256] source; 31 for (short i=0; i<256; i++) { 32 source[i]=i; 33 } 34 seed = seed * 6364136223846793005L + 1442695040888963407L; 35 seed = seed * 6364136223846793005L + 1442695040888963407L; 36 seed = seed * 6364136223846793005L + 1442695040888963407L; 37 for (int i = 255; i >= 0; i--) { 38 seed = seed * 6364136223846793005L + 1442695040888963407L; 39 int r = ((seed + 31) % (i + 1)); 40 if (r < 0) 41 r += (i + 1); 42 _perm[i] = source[r]; 43 _permGradIndex3D[i] = cast(short)((_perm[i] % (GRADIENTS.GRADIENTS_3D.length / 3)) * 3); 44 source[r] = source[i]; 45 } 46 } 47 48 /// Initializes a generator from a Seed struct 49 @nogc @safe this(Seed seed) 50 { 51 this(seed.seed); 52 } 53 54 /// Initializes a generator from a given permutation array 55 @nogc @safe this(short[256] perm) 56 { 57 _perm = perm; 58 for (int i = 0; i < 256; i++) { 59 //Since 3D has 24 gradients, simple bitmask won't work, so precompute modulo array. 60 _permGradIndex3D[i] = cast(short)((_perm[i] % (GRADIENTS.GRADIENTS_3D.length / 3)) * 3); 61 } 62 } 63 64 /// 2D OpenSimplexNoise 65 @nogc @safe pure double noise2D(double x, double y) 66 { 67 return osNoise2D(x,y,_perm); 68 } 69 /// Ditto 70 @nogc @safe pure double noise2D(const double[2] p) 71 { 72 return osNoise2D(p[0],p[1],_perm); 73 } 74 75 /// 3D OpenSimplexNoise 76 @nogc @safe pure double noise3D(double x, double y, double z) 77 { 78 return osNoise3D(x,y,z,_perm,_permGradIndex3D); 79 } 80 /// Ditto 81 @nogc @safe pure double noise3D(const double[3] p) 82 { 83 return osNoise3D(p[0],p[1],p[2],_perm,_permGradIndex3D); 84 } 85 86 /// 3D OpenSimplexNoise 87 @nogc @safe pure double noise4D(double x, double y, double z, double w) 88 { 89 return osNoise4D(x,y,z,w,_perm); 90 } 91 /// Ditto 92 @nogc @safe pure double noise4D(const double[4] p) 93 { 94 return osNoise4D(p[0],p[1],p[2],p[3],_perm); 95 } 96 97 private: 98 /// Permutation Array 99 short[256] _perm; 100 /// Grad index precomputed for 3D noise 101 short[256] _permGradIndex3D; 102 } 103