Cuberite
A lightweight, fast and extensible game server for Minecraft
Noise.h
Go to the documentation of this file.
1 
2 // Noise.h
3 
4 // Declares the cNoise, cCubicNoise and cPerlinNoise classes for generating noise
5 
6 #pragma once
7 
9 typedef float NOISE_DATATYPE;
10 
11 #include "../Vector3.h"
12 #include "OctavedNoise.h"
13 #include "RidgedNoise.h"
14 
15 
16 
17 
18 
19 class cNoise
20 {
21 public:
22  cNoise(int a_Seed);
23  cNoise(const cNoise & a_Noise);
24 
25  // The following functions, if not marked INLINE, are about 20 % slower
26  inline NOISE_DATATYPE IntNoise1D(int a_X) const;
27  inline NOISE_DATATYPE IntNoise2D(int a_X, int a_Y) const;
28  inline NOISE_DATATYPE IntNoise3D(int a_X, int a_Y, int a_Z) const;
29  inline NOISE_DATATYPE IntNoise3D(Vector3i a_Pos) const;
30 
31  // Return a float number in the specified range:
32  inline NOISE_DATATYPE IntNoise2DInRange(int a_X, int a_Y, float a_Min, float a_Max) const
33  {
34  return a_Min + std::abs(IntNoise2D(a_X, a_Y)) * (a_Max - a_Min);
35  }
36 
37  // Note: These functions have a mod8-irregular chance - each of the mod8 remainders has different chance of occurrence. Divide by 8 to rectify.
38  inline int IntNoise1DInt(int a_X) const;
39  inline int IntNoise2DInt(int a_X, int a_Y) const;
40  inline int IntNoise3DInt(int a_X, int a_Y, int a_Z) const;
41  inline int IntNoise3DInt(Vector3i a_Pos) const;
42 
46  NOISE_DATATYPE SmoothNoise1D(int a_X) const;
47 
49 
51 
52  void SetSeed(int a_Seed) { m_Seed = a_Seed; }
53  int GetSeed(void) const { return m_Seed; }
54 
58 
59 private:
60  int m_Seed;
61 } ;
62 
63 
64 
65 
66 
68 {
69 public:
71  static const int MAX_SIZE = 512;
72 
73 
75  cCubicNoise(int a_Seed);
76 
77 
79  void Generate2D(
80  NOISE_DATATYPE * a_Array,
81  int a_SizeX, int a_SizeY,
82  NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX,
83  NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY
84  ) const;
85 
86 
88  void Generate3D(
89  NOISE_DATATYPE * a_Array,
90  int a_SizeX, int a_SizeY, int a_SizeZ,
91  NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX,
92  NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY,
93  NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ
94  ) const;
95 
96 protected:
97 
100 
101 
107  void CalcFloorFrac(
108  int a_Size,
109  NOISE_DATATYPE a_Start, NOISE_DATATYPE a_End,
110  int * a_Floor, NOISE_DATATYPE * a_Frac,
111  int * a_Same, int & a_NumSame
112  ) const;
113 } ;
114 
115 
116 
117 
118 
122 {
123 public:
126  cImprovedNoise(int a_Seed);
127 
128 
130  void Generate2D(
131  NOISE_DATATYPE * a_Array,
132  int a_SizeX, int a_SizeY,
133  NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX,
134  NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY
135  ) const;
136 
137 
139  void Generate3D(
140  NOISE_DATATYPE * a_Array,
141  int a_SizeX, int a_SizeY, int a_SizeZ,
142  NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX,
143  NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY,
144  NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ
145  ) const;
146 
148  NOISE_DATATYPE GetValueAt(int a_X, int a_Y, int a_Z);
149 
150 protected:
151 
153  int m_Perm[512];
154 
155 
157  inline static NOISE_DATATYPE Fade(NOISE_DATATYPE a_T)
158  {
159  return a_T * a_T * a_T * (a_T * (a_T * 6 - 15) + 10);
160  }
161 
163  inline static NOISE_DATATYPE Grad(int a_Hash, NOISE_DATATYPE a_X, NOISE_DATATYPE a_Y, NOISE_DATATYPE a_Z)
164  {
165  int hash = a_Hash % 16;
166  NOISE_DATATYPE u = (hash < 8) ? a_X : a_Y;
167  NOISE_DATATYPE v = (hash < 4) ? a_Y : (((hash == 12) || (hash == 14)) ? a_X : a_Z);
168  return (((hash & 1) == 0) ? u : -u) + (((hash & 2) == 0) ? v : -v);
169  }
170 };
171 
172 
173 
174 
175 
178 
179 
180 
181 
182 
184 // Inline function definitions:
185 // These need to be in the header, otherwise linker error occur in MSVC
186 
188 {
189  int x = ((a_X * m_Seed) << 13) ^ a_X;
190  return (1 - static_cast<NOISE_DATATYPE>((x * (x * x * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824);
191  // returns a float number in the range of [-1, 1]
192 }
193 
194 
195 
196 
197 
198 NOISE_DATATYPE cNoise::IntNoise2D(int a_X, int a_Y) const
199 {
200  int n = a_X + a_Y * 57 + m_Seed * 57 * 57;
201  n = (n << 13) ^ n;
202  return (1 - static_cast<NOISE_DATATYPE>((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824);
203  // returns a float number in the range of [-1, 1]
204 }
205 
206 
207 
208 
209 
210 NOISE_DATATYPE cNoise::IntNoise3D(int a_X, int a_Y, int a_Z) const
211 {
212  int n = a_X + a_Y * 57 + a_Z * 57 * 57 + m_Seed * 57 * 57 * 57;
213  n = (n << 13) ^ n;
214  return (static_cast<NOISE_DATATYPE>(1) -
215  static_cast<NOISE_DATATYPE>((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0f
216  );
217  // returns a float number in the range of [-1, 1]
218 }
219 
220 
221 
222 
223 
225 {
226  return IntNoise3D(a_Pos.x, a_Pos.y, a_Pos.z);
227 }
228 
229 
230 
231 
232 
233 int cNoise::IntNoise1DInt(int a_X) const
234 {
235  int x = ((a_X * m_Seed) << 13) ^ a_X;
236  return ((x * (x * x * 15731 + 789221) + 1376312589) & 0x7fffffff);
237 }
238 
239 
240 
241 
242 
243 int cNoise::IntNoise2DInt(int a_X, int a_Y) const
244 {
245  int n = a_X + a_Y * 57 + m_Seed * 57 * 57;
246  n = (n << 13) ^ n;
247  return ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff);
248 }
249 
250 
251 
252 
253 
254 int cNoise::IntNoise3DInt(int a_X, int a_Y, int a_Z) const
255 {
256  int n = a_X + a_Y * 57 + a_Z * 57 * 57 + m_Seed * 57 * 57 * 57;
257  n = (n << 13) ^ n;
258  return ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff);
259 }
260 
261 
262 
263 
264 
266 {
267  return IntNoise3DInt(a_Pos.x, a_Pos.y, a_Pos.z);
268 }
269 
270 
271 
272 
273 
275 {
276  NOISE_DATATYPE P = (a_D - a_C) - (a_A - a_B);
277  NOISE_DATATYPE Q = (a_A - a_B) - P;
278  NOISE_DATATYPE R = a_C - a_A;
279  NOISE_DATATYPE S = a_B;
280 
281  return ((P * a_Pct + Q) * a_Pct + R) * a_Pct + S;
282 }
283 
284 
285 
286 
287 
289 {
290  const NOISE_DATATYPE ft = a_Pct * static_cast<NOISE_DATATYPE>(3.1415927);
291  const NOISE_DATATYPE f = static_cast<NOISE_DATATYPE>(static_cast<NOISE_DATATYPE>(1 - cos(ft)) * static_cast<NOISE_DATATYPE>(0.5));
292  return a_A * (1 - f) + a_B * f;
293 }
294 
295 
296 
297 
298 
300 {
301  return a_A * (1 - a_Pct) + a_B * a_Pct;
302 }
303 
304 
305 
306 
307 
309 // Global functions:
310 
313 extern void Debug2DNoise(const NOISE_DATATYPE * a_Array, size_t a_SizeX, size_t a_SizeY, const AString & a_FileNameBase, NOISE_DATATYPE a_Coeff = 32);
314 
317 extern void Debug3DNoise(const NOISE_DATATYPE * a_Array, size_t a_SizeX, size_t a_SizeY, size_t a_SizeZ, const AString & a_FileNameBase, NOISE_DATATYPE a_Coeff = 32);
318 
319 
320 
321 
325 {
326  return a_Val1 + (a_Val2 - a_Val1) * a_Ratio;
327 }
328 
329 
330 
331 
332 
335 {
336  if (a_Ratio < 0)
337  {
338  return a_Val1;
339  }
340  if (a_Ratio > 1)
341  {
342  return a_Val2;
343  }
344  return Lerp(a_Val1, a_Val2, a_Ratio);
345 }
cOctavedNoise< cRidgedNoise< cCubicNoise > > cRidgedMultiNoise
Definition: Noise.h:177
NOISE_DATATYPE ClampedLerp(NOISE_DATATYPE a_Val1, NOISE_DATATYPE a_Val2, NOISE_DATATYPE a_Ratio)
Linearly interpolates between two values, clamping the ratio to [0, 1] first.
Definition: Noise.h:334
void Debug2DNoise(const NOISE_DATATYPE *a_Array, size_t a_SizeX, size_t a_SizeY, const AString &a_FileNameBase, NOISE_DATATYPE a_Coeff=32)
Exports the noise array into a file.
Definition: Noise.cpp:168
NOISE_DATATYPE Lerp(NOISE_DATATYPE a_Val1, NOISE_DATATYPE a_Val2, NOISE_DATATYPE a_Ratio)
Linearly interpolates between two values.
Definition: Noise.h:324
float NOISE_DATATYPE
The datatype used by all the noise generators.
Definition: Noise.h:9
cOctavedNoise< cCubicNoise > cPerlinNoise
Definition: Noise.h:176
void Debug3DNoise(const NOISE_DATATYPE *a_Array, size_t a_SizeX, size_t a_SizeY, size_t a_SizeZ, const AString &a_FileNameBase, NOISE_DATATYPE a_Coeff=32)
Exports the noise array into a set of files, ordered by XY and XZ.
Definition: Noise.cpp:115
std::string AString
Definition: StringUtils.h:11
Definition: Noise.h:20
static NOISE_DATATYPE CubicInterpolate(NOISE_DATATYPE a_A, NOISE_DATATYPE a_B, NOISE_DATATYPE a_C, NOISE_DATATYPE a_D, NOISE_DATATYPE a_Pct)
Definition: Noise.h:274
int IntNoise1DInt(int a_X) const
Definition: Noise.h:233
static NOISE_DATATYPE CosineInterpolate(NOISE_DATATYPE a_A, NOISE_DATATYPE a_B, NOISE_DATATYPE a_Pct)
Definition: Noise.h:288
NOISE_DATATYPE CosineNoise1D(NOISE_DATATYPE a_X) const
Definition: Noise.cpp:562
cNoise(int a_Seed)
Definition: Noise.cpp:533
NOISE_DATATYPE CubicNoise2D(NOISE_DATATYPE a_X, NOISE_DATATYPE a_Y) const
Definition: Noise.cpp:593
NOISE_DATATYPE IntNoise2D(int a_X, int a_Y) const
Definition: Noise.h:198
NOISE_DATATYPE CubicNoise3D(NOISE_DATATYPE a_X, NOISE_DATATYPE a_Y, NOISE_DATATYPE a_Z) const
Definition: Noise.cpp:621
int GetSeed(void) const
Definition: Noise.h:53
int IntNoise3DInt(int a_X, int a_Y, int a_Z) const
Definition: Noise.h:254
void SetSeed(int a_Seed)
Definition: Noise.h:52
int IntNoise2DInt(int a_X, int a_Y) const
Definition: Noise.h:243
NOISE_DATATYPE SmoothNoise1D(int a_X) const
Definition: Noise.cpp:584
static NOISE_DATATYPE LinearInterpolate(NOISE_DATATYPE a_A, NOISE_DATATYPE a_B, NOISE_DATATYPE a_Pct)
Definition: Noise.h:299
NOISE_DATATYPE LinearNoise1D(NOISE_DATATYPE a_X) const
Definition: Noise.cpp:551
NOISE_DATATYPE IntNoise3D(int a_X, int a_Y, int a_Z) const
Definition: Noise.h:210
NOISE_DATATYPE IntNoise2DInRange(int a_X, int a_Y, float a_Min, float a_Max) const
Definition: Noise.h:32
int m_Seed
Definition: Noise.h:60
NOISE_DATATYPE IntNoise1D(int a_X) const
Definition: Noise.h:187
NOISE_DATATYPE CubicNoise1D(NOISE_DATATYPE a_X) const
Definition: Noise.cpp:573
void Generate3D(NOISE_DATATYPE *a_Array, int a_SizeX, int a_SizeY, int a_SizeZ, NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ) const
Fills a 3D array with the values of the noise.
Definition: Noise.cpp:758
cNoise m_Noise
Noise used for integral random values.
Definition: Noise.h:99
cCubicNoise(int a_Seed)
Creates a new instance with the specified seed.
Definition: Noise.cpp:697
void CalcFloorFrac(int a_Size, NOISE_DATATYPE a_Start, NOISE_DATATYPE a_End, int *a_Floor, NOISE_DATATYPE *a_Frac, int *a_Same, int &a_NumSame) const
Calculates the integral and fractional parts along one axis.
Definition: Noise.cpp:827
void Generate2D(NOISE_DATATYPE *a_Array, int a_SizeX, int a_SizeY, NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY) const
Fills a 2D array with the values of the noise.
Definition: Noise.cpp:706
static const int MAX_SIZE
Maximum size of each dimension of the query arrays.
Definition: Noise.h:71
Improved noise, as described by Ken Perlin: https://mrl.nyu.edu/~perlin/paper445.pdf Implementation a...
Definition: Noise.h:122
void Generate3D(NOISE_DATATYPE *a_Array, int a_SizeX, int a_SizeY, int a_SizeZ, NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ) const
Fills a 3D array with the values of the noise.
Definition: Noise.cpp:947
cImprovedNoise(int a_Seed)
Constructs a new instance of the noise obbject.
Definition: Noise.cpp:873
NOISE_DATATYPE GetValueAt(int a_X, int a_Y, int a_Z)
Returns the value at the specified integral coords.
Definition: Noise.cpp:1013
static NOISE_DATATYPE Fade(NOISE_DATATYPE a_T)
Calculates the fade curve, 6 * t^5 - 15 * t^4 + 10 * t^3.
Definition: Noise.h:157
int m_Perm[512]
The permutation table used by the noise function.
Definition: Noise.h:153
void Generate2D(NOISE_DATATYPE *a_Array, int a_SizeX, int a_SizeY, NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY) const
Fills a 2D array with the values of the noise.
Definition: Noise.cpp:900
static NOISE_DATATYPE Grad(int a_Hash, NOISE_DATATYPE a_X, NOISE_DATATYPE a_Y, NOISE_DATATYPE a_Z)
Returns the gradient value based on the hash.
Definition: Noise.h:163
T x
Definition: Vector3.h:17
T y
Definition: Vector3.h:17
T z
Definition: Vector3.h:17