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