Free Electron
FastNoise.h
1 // FastNoise.h
2 //
3 // MIT License
4 //
5 // Copyright(c) 2017 Jordan Peck
6 //
7 // Permission is hereby granted, free of charge, to any person obtaining a copy
8 // of this software and associated documentation files(the "Software"), to deal
9 // in the Software without restriction, including without limitation the rights
10 // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
11 // copies of the Software, and to permit persons to whom the Software is
12 // furnished to do so, subject to the following conditions :
13 //
14 // The above copyright notice and this permission notice shall be included in all
15 // copies or substantial portions of the Software.
16 //
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 // SOFTWARE.
24 //
25 // The developer's email is jorzixdan.me2@gzixmail.com (for great email, take
26 // off every 'zix'.)
27 //
28 
29 // VERSION: 0.4.1
30 
31 #ifndef FASTNOISE_H
32 #define FASTNOISE_H
33 
34 // Uncomment the line below to use doubles throughout FastNoise instead of floats
35 //#define FN_USE_DOUBLES
36 
37 #define FN_CELLULAR_INDEX_MAX 3
38 
39 #ifdef FN_USE_DOUBLES
40 typedef double FN_DECIMAL;
41 #else
42 typedef float FN_DECIMAL;
43 #endif
44 
45 class FastNoise
46 {
47 public:
48  explicit FastNoise(int seed = 1337) { SetSeed(seed); CalculateFractalBounding(); }
49 
50  enum NoiseType { Value, ValueFractal, Perlin, PerlinFractal, Simplex, SimplexFractal, Cellular, WhiteNoise, Cubic, CubicFractal };
51  enum Interp { Linear, Hermite, Quintic };
52  enum FractalType { FBM, Billow, RigidMulti };
53  enum CellularDistanceFunction { Euclidean, Manhattan, Natural };
54  enum CellularReturnType { CellValue, NoiseLookup, Distance, Distance2, Distance2Add, Distance2Sub, Distance2Mul, Distance2Div };
55 
56  // Sets seed used for all noise types
57  // Default: 1337
58  void SetSeed(int seed);
59 
60  // Returns seed used for all noise types
61  int GetSeed() const { return m_seed; }
62 
63  // Sets frequency for all noise types
64  // Default: 0.01
65  void SetFrequency(FN_DECIMAL frequency) { m_frequency = frequency; }
66 
67  // Returns frequency used for all noise types
68  FN_DECIMAL GetFrequency() const { return m_frequency; }
69 
70  // Changes the interpolation method used to smooth between noise values
71  // Possible interpolation methods (lowest to highest quality) :
72  // - Linear
73  // - Hermite
74  // - Quintic
75  // Used in Value, Perlin Noise and Position Warping
76  // Default: Quintic
77  void SetInterp(Interp interp) { m_interp = interp; }
78 
79  // Returns interpolation method used for supported noise types
80  Interp GetInterp() const { return m_interp; }
81 
82  // Sets noise return type of GetNoise(...)
83  // Default: Simplex
84  void SetNoiseType(NoiseType noiseType) { m_noiseType = noiseType; }
85 
86  // Returns the noise type used by GetNoise
87  NoiseType GetNoiseType() const { return m_noiseType; }
88 
89  // Sets octave count for all fractal noise types
90  // Default: 3
91  void SetFractalOctaves(int octaves) { m_octaves = octaves; CalculateFractalBounding(); }
92 
93  // Returns octave count for all fractal noise types
94  int GetFractalOctaves() const { return m_octaves; }
95 
96  // Sets octave lacunarity for all fractal noise types
97  // Default: 2.0
98  void SetFractalLacunarity(FN_DECIMAL lacunarity) { m_lacunarity = lacunarity; }
99 
100  // Returns octave lacunarity for all fractal noise types
101  FN_DECIMAL GetFractalLacunarity() const { return m_lacunarity; }
102 
103  // Sets octave gain for all fractal noise types
104  // Default: 0.5
105  void SetFractalGain(FN_DECIMAL gain) { m_gain = gain; CalculateFractalBounding(); }
106 
107  // Returns octave gain for all fractal noise types
108  FN_DECIMAL GetFractalGain() const { return m_gain; }
109 
110  // Sets method for combining octaves in all fractal noise types
111  // Default: FBM
112  void SetFractalType(FractalType fractalType) { m_fractalType = fractalType; }
113 
114  // Returns method for combining octaves in all fractal noise types
115  FractalType GetFractalType() const { return m_fractalType; }
116 
117 
118  // Sets distance function used in cellular noise calculations
119  // Default: Euclidean
120  void SetCellularDistanceFunction(CellularDistanceFunction cellularDistanceFunction) { m_cellularDistanceFunction = cellularDistanceFunction; }
121 
122  // Returns the distance function used in cellular noise calculations
123  CellularDistanceFunction GetCellularDistanceFunction() const { return m_cellularDistanceFunction; }
124 
125  // Sets return type from cellular noise calculations
126  // Note: NoiseLookup requires another FastNoise object be set with SetCellularNoiseLookup() to function
127  // Default: CellValue
128  void SetCellularReturnType(CellularReturnType cellularReturnType) { m_cellularReturnType = cellularReturnType; }
129 
130  // Returns the return type from cellular noise calculations
131  CellularReturnType GetCellularReturnType() const { return m_cellularReturnType; }
132 
133  // Noise used to calculate a cell value if cellular return type is NoiseLookup
134  // The lookup value is acquired through GetNoise() so ensure you SetNoiseType() on the noise lookup, value, Perlin or simplex is recommended
135  void SetCellularNoiseLookup(FastNoise* noise) { m_cellularNoiseLookup = noise; }
136 
137  // Returns the noise used to calculate a cell value if the cellular return type is NoiseLookup
138  FastNoise* GetCellularNoiseLookup() const { return m_cellularNoiseLookup; }
139 
140  // Sets the 2 distance indices used for distance2 return types
141  // Default: 0, 1
142  // Note: index0 should be lower than index1
143  // Both indices must be >= 0, index1 must be < 4
144  void SetCellularDistance2Indices(int cellularDistanceIndex0, int cellularDistanceIndex1);
145 
146  // Returns the 2 distance indices used for distance2 return types
147  void GetCellularDistance2Indices(int& cellularDistanceIndex0, int& cellularDistanceIndex1) const;
148 
149  // Sets the maximum distance a cellular point can move from its grid position
150  // Setting this high will make artifacts more common
151  // Default: 0.45
152  void SetCellularJitter(FN_DECIMAL cellularJitter) { m_cellularJitter = cellularJitter; }
153 
154  // Returns the maximum distance a cellular point can move from its grid position
155  FN_DECIMAL GetCellularJitter() const { return m_cellularJitter; }
156 
157  // Sets the maximum warp distance from original location when using GradientPerturb{Fractal}(...)
158  // Default: 1.0
159  void SetGradientPerturbAmp(FN_DECIMAL gradientPerturbAmp) { m_gradientPerturbAmp = gradientPerturbAmp; }
160 
161  // Returns the maximum warp distance from original location when using GradientPerturb{Fractal}(...)
162  FN_DECIMAL GetGradientPerturbAmp() const { return m_gradientPerturbAmp; }
163 
164  //2D
165  FN_DECIMAL GetValue(FN_DECIMAL x, FN_DECIMAL y) const;
166  FN_DECIMAL GetValueFractal(FN_DECIMAL x, FN_DECIMAL y) const;
167 
168  FN_DECIMAL GetPerlin(FN_DECIMAL x, FN_DECIMAL y) const;
169  FN_DECIMAL GetPerlinFractal(FN_DECIMAL x, FN_DECIMAL y) const;
170 
171  FN_DECIMAL GetSimplex(FN_DECIMAL x, FN_DECIMAL y) const;
172  FN_DECIMAL GetSimplexFractal(FN_DECIMAL x, FN_DECIMAL y) const;
173 
174  FN_DECIMAL GetCellular(FN_DECIMAL x, FN_DECIMAL y) const;
175 
176  FN_DECIMAL GetWhiteNoise(FN_DECIMAL x, FN_DECIMAL y) const;
177  FN_DECIMAL GetWhiteNoiseInt(int x, int y) const;
178 
179  FN_DECIMAL GetCubic(FN_DECIMAL x, FN_DECIMAL y) const;
180  FN_DECIMAL GetCubicFractal(FN_DECIMAL x, FN_DECIMAL y) const;
181 
182  FN_DECIMAL GetNoise(FN_DECIMAL x, FN_DECIMAL y) const;
183 
184  void GradientPerturb(FN_DECIMAL& x, FN_DECIMAL& y) const;
185  void GradientPerturbFractal(FN_DECIMAL& x, FN_DECIMAL& y) const;
186 
187  //3D
188  FN_DECIMAL GetValue(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
189  FN_DECIMAL GetValueFractal(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
190 
191  FN_DECIMAL GetPerlin(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
192  FN_DECIMAL GetPerlinFractal(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
193 
194  FN_DECIMAL GetSimplex(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
195  FN_DECIMAL GetSimplexFractal(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
196 
197  FN_DECIMAL GetCellular(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
198 
199  FN_DECIMAL GetWhiteNoise(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
200  FN_DECIMAL GetWhiteNoiseInt(int x, int y, int z) const;
201 
202  FN_DECIMAL GetCubic(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
203  FN_DECIMAL GetCubicFractal(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
204 
205  FN_DECIMAL GetNoise(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
206 
207  void GradientPerturb(FN_DECIMAL& x, FN_DECIMAL& y, FN_DECIMAL& z) const;
208  void GradientPerturbFractal(FN_DECIMAL& x, FN_DECIMAL& y, FN_DECIMAL& z) const;
209 
210  //4D
211  FN_DECIMAL GetSimplex(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z, FN_DECIMAL w) const;
212 
213  FN_DECIMAL GetWhiteNoise(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z, FN_DECIMAL w) const;
214  FN_DECIMAL GetWhiteNoiseInt(int x, int y, int z, int w) const;
215 
216 private:
217  unsigned char m_perm[512];
218  unsigned char m_perm12[512];
219 
220  int m_seed = 1337;
221  FN_DECIMAL m_frequency = FN_DECIMAL(0.01);
222  Interp m_interp = Quintic;
223  NoiseType m_noiseType = Simplex;
224 
225  int m_octaves = 3;
226  FN_DECIMAL m_lacunarity = FN_DECIMAL(2);
227  FN_DECIMAL m_gain = FN_DECIMAL(0.5);
228  FractalType m_fractalType = FBM;
229  FN_DECIMAL m_fractalBounding;
230 
231  CellularDistanceFunction m_cellularDistanceFunction = Euclidean;
232  CellularReturnType m_cellularReturnType = CellValue;
233  FastNoise* m_cellularNoiseLookup = nullptr;
234  int m_cellularDistanceIndex0 = 0;
235  int m_cellularDistanceIndex1 = 1;
236  FN_DECIMAL m_cellularJitter = FN_DECIMAL(0.45);
237 
238  FN_DECIMAL m_gradientPerturbAmp = FN_DECIMAL(1);
239 
240  void CalculateFractalBounding();
241 
242  //2D
243  FN_DECIMAL SingleValueFractalFBM(FN_DECIMAL x, FN_DECIMAL y) const;
244  FN_DECIMAL SingleValueFractalBillow(FN_DECIMAL x, FN_DECIMAL y) const;
245  FN_DECIMAL SingleValueFractalRigidMulti(FN_DECIMAL x, FN_DECIMAL y) const;
246  FN_DECIMAL SingleValue(unsigned char offset, FN_DECIMAL x, FN_DECIMAL y) const;
247 
248  FN_DECIMAL SinglePerlinFractalFBM(FN_DECIMAL x, FN_DECIMAL y) const;
249  FN_DECIMAL SinglePerlinFractalBillow(FN_DECIMAL x, FN_DECIMAL y) const;
250  FN_DECIMAL SinglePerlinFractalRigidMulti(FN_DECIMAL x, FN_DECIMAL y) const;
251  FN_DECIMAL SinglePerlin(unsigned char offset, FN_DECIMAL x, FN_DECIMAL y) const;
252 
253  FN_DECIMAL SingleSimplexFractalFBM(FN_DECIMAL x, FN_DECIMAL y) const;
254  FN_DECIMAL SingleSimplexFractalBillow(FN_DECIMAL x, FN_DECIMAL y) const;
255  FN_DECIMAL SingleSimplexFractalRigidMulti(FN_DECIMAL x, FN_DECIMAL y) const;
256  FN_DECIMAL SingleSimplexFractalBlend(FN_DECIMAL x, FN_DECIMAL y) const;
257  FN_DECIMAL SingleSimplex(unsigned char offset, FN_DECIMAL x, FN_DECIMAL y) const;
258 
259  FN_DECIMAL SingleCubicFractalFBM(FN_DECIMAL x, FN_DECIMAL y) const;
260  FN_DECIMAL SingleCubicFractalBillow(FN_DECIMAL x, FN_DECIMAL y) const;
261  FN_DECIMAL SingleCubicFractalRigidMulti(FN_DECIMAL x, FN_DECIMAL y) const;
262  FN_DECIMAL SingleCubic(unsigned char offset, FN_DECIMAL x, FN_DECIMAL y) const;
263 
264  FN_DECIMAL SingleCellular(FN_DECIMAL x, FN_DECIMAL y) const;
265  FN_DECIMAL SingleCellular2Edge(FN_DECIMAL x, FN_DECIMAL y) const;
266 
267  void SingleGradientPerturb(unsigned char offset, FN_DECIMAL warpAmp, FN_DECIMAL frequency, FN_DECIMAL& x, FN_DECIMAL& y) const;
268 
269  //3D
270  FN_DECIMAL SingleValueFractalFBM(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
271  FN_DECIMAL SingleValueFractalBillow(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
272  FN_DECIMAL SingleValueFractalRigidMulti(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
273  FN_DECIMAL SingleValue(unsigned char offset, FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
274 
275  FN_DECIMAL SinglePerlinFractalFBM(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
276  FN_DECIMAL SinglePerlinFractalBillow(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
277  FN_DECIMAL SinglePerlinFractalRigidMulti(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
278  FN_DECIMAL SinglePerlin(unsigned char offset, FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
279 
280  FN_DECIMAL SingleSimplexFractalFBM(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
281  FN_DECIMAL SingleSimplexFractalBillow(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
282  FN_DECIMAL SingleSimplexFractalRigidMulti(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
283  FN_DECIMAL SingleSimplex(unsigned char offset, FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
284 
285  FN_DECIMAL SingleCubicFractalFBM(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
286  FN_DECIMAL SingleCubicFractalBillow(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
287  FN_DECIMAL SingleCubicFractalRigidMulti(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
288  FN_DECIMAL SingleCubic(unsigned char offset, FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
289 
290  FN_DECIMAL SingleCellular(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
291  FN_DECIMAL SingleCellular2Edge(FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const;
292 
293  void SingleGradientPerturb(unsigned char offset, FN_DECIMAL warpAmp, FN_DECIMAL frequency, FN_DECIMAL& x, FN_DECIMAL& y, FN_DECIMAL& z) const;
294 
295  //4D
296  FN_DECIMAL SingleSimplex(unsigned char offset, FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z, FN_DECIMAL w) const;
297 
298  inline unsigned char Index2D_12(unsigned char offset, int x, int y) const;
299  inline unsigned char Index3D_12(unsigned char offset, int x, int y, int z) const;
300  inline unsigned char Index4D_32(unsigned char offset, int x, int y, int z, int w) const;
301  inline unsigned char Index2D_256(unsigned char offset, int x, int y) const;
302  inline unsigned char Index3D_256(unsigned char offset, int x, int y, int z) const;
303  inline unsigned char Index4D_256(unsigned char offset, int x, int y, int z, int w) const;
304 
305  inline FN_DECIMAL ValCoord2DFast(unsigned char offset, int x, int y) const;
306  inline FN_DECIMAL ValCoord3DFast(unsigned char offset, int x, int y, int z) const;
307  inline FN_DECIMAL GradCoord2D(unsigned char offset, int x, int y, FN_DECIMAL xd, FN_DECIMAL yd) const;
308  inline FN_DECIMAL GradCoord3D(unsigned char offset, int x, int y, int z, FN_DECIMAL xd, FN_DECIMAL yd, FN_DECIMAL zd) const;
309  inline FN_DECIMAL GradCoord4D(unsigned char offset, int x, int y, int z, int w, FN_DECIMAL xd, FN_DECIMAL yd, FN_DECIMAL zd, FN_DECIMAL wd) const;
310 };
311 #endif