Cuberite
A lightweight, fast and extensible game server for Minecraft
OctavedNoise.h
Go to the documentation of this file.
1 
2 // OctavedNoise.h
3 
4 // Implements the cOctavedNoise class template representing a noise generator that layers several octaves of another noise
5 
6 
7 
8 
9 
10 #pragma once
11 
12 
13 
14 
15 
16 template <typename N>
18 {
19 public:
20  cOctavedNoise(int a_Seed = 0):
21  m_Seed(a_Seed)
22  {
23  }
24 
25 
27  void SetSeed(int a_Seed)
28  {
29  m_Seed = a_Seed;
30  for (auto oct: m_Octaves)
31  {
32  oct->SetSeed(a_Seed);
33  }
34  }
35 
36 
38  void AddOctave(NOISE_DATATYPE a_Frequency, NOISE_DATATYPE a_Amplitude)
39  {
40  m_Octaves.emplace_back(m_Seed, a_Frequency, a_Amplitude);
41  }
42 
43 
45  void Generate2D(
46  NOISE_DATATYPE * a_Array,
47  int a_SizeX, int a_SizeY,
48  NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX,
49  NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY,
50  NOISE_DATATYPE * a_Workspace = nullptr
51  ) const
52  {
53  // Check that state is alright:
54  if (m_Octaves.empty())
55  {
56  ASSERT(!"cOctavedNoise: No octaves to generate!");
57  return;
58  }
59 
60  // Allocate the workspace on the heap, if it wasn't given:
61  std::unique_ptr<NOISE_DATATYPE[]> workspaceHeap;
62  if (a_Workspace == nullptr)
63  {
64  workspaceHeap.reset(new NOISE_DATATYPE[ToUnsigned(a_SizeX * a_SizeY)]);
65  a_Workspace = workspaceHeap.get();
66  }
67 
68  // Generate the first octave directly into array:
69  int ArrayCount = a_SizeX * a_SizeY;
70  {
71  const cOctave & FirstOctave = m_Octaves.front();
72  FirstOctave.m_Noise.Generate2D(
73  a_Workspace, a_SizeX, a_SizeY,
74  a_StartX * FirstOctave.m_Frequency, a_EndX * FirstOctave.m_Frequency,
75  a_StartY * FirstOctave.m_Frequency, a_EndY * FirstOctave.m_Frequency
76  );
77  NOISE_DATATYPE Amplitude = FirstOctave.m_Amplitude;
78  for (int i = 0; i < ArrayCount; i++)
79  {
80  a_Array[i] = a_Workspace[i] * Amplitude;
81  }
82  }
83 
84  // Add each octave:
85  for (auto itr = m_Octaves.cbegin() + 1, end = m_Octaves.cend(); itr != end; ++itr)
86  {
87  // Generate the noise for the octave:
88  itr->m_Noise.Generate2D(
89  a_Workspace, a_SizeX, a_SizeY,
90  a_StartX * itr->m_Frequency, a_EndX * itr->m_Frequency,
91  a_StartY * itr->m_Frequency, a_EndY * itr->m_Frequency
92  );
93  // Add it into the output:
94  NOISE_DATATYPE Amplitude = itr->m_Amplitude;
95  for (int i = 0; i < ArrayCount; i++)
96  {
97  a_Array[i] += a_Workspace[i] * Amplitude;
98  }
99  } // for itr - m_Octaves[]
100  }
101 
102 
105  NOISE_DATATYPE * a_Array,
106  int a_SizeX, int a_SizeY, int a_SizeZ,
107  NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX,
108  NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY,
109  NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ,
110  NOISE_DATATYPE * a_Workspace = nullptr
111  ) const
112  {
113  // Check that state is alright:
114  if (m_Octaves.empty())
115  {
116  ASSERT(!"cOctavedNoise: No octaves to generate!");
117  return;
118  }
119 
120  // Allocate the workspace on the heap, if it wasn't given:
121  std::unique_ptr<NOISE_DATATYPE[]> workspaceHeap;
122  if (a_Workspace == nullptr)
123  {
124  workspaceHeap.reset(new NOISE_DATATYPE[ToUnsigned(a_SizeX * a_SizeY * a_SizeZ)]);
125  a_Workspace = workspaceHeap.get();
126  }
127 
128  // Generate the first octave directly into array:
129  int ArrayCount = a_SizeX * a_SizeY * a_SizeZ;
130  {
131  const cOctave & FirstOctave = m_Octaves.front();
132  FirstOctave.m_Noise.Generate3D(
133  a_Workspace, a_SizeX, a_SizeY, a_SizeZ,
134  a_StartX * FirstOctave.m_Frequency, a_EndX * FirstOctave.m_Frequency,
135  a_StartY * FirstOctave.m_Frequency, a_EndY * FirstOctave.m_Frequency,
136  a_StartZ * FirstOctave.m_Frequency, a_EndZ * FirstOctave.m_Frequency
137  );
138  NOISE_DATATYPE Amplitude = FirstOctave.m_Amplitude;
139  for (int i = 0; i < ArrayCount; i++)
140  {
141  a_Array[i] = a_Workspace[i] * Amplitude;
142  }
143  }
144 
145  // Add each octave:
146  for (auto itr = m_Octaves.cbegin() + 1, end = m_Octaves.cend(); itr != end; ++itr)
147  {
148  // Generate the noise for the octave:
149  itr->m_Noise.Generate3D(
150  a_Workspace, a_SizeX, a_SizeY, a_SizeZ,
151  a_StartX * itr->m_Frequency, a_EndX * itr->m_Frequency,
152  a_StartY * itr->m_Frequency, a_EndY * itr->m_Frequency,
153  a_StartZ * itr->m_Frequency, a_EndZ * itr->m_Frequency
154  );
155  // Add it into the output:
156  NOISE_DATATYPE Amplitude = itr->m_Amplitude;
157  for (int i = 0; i < ArrayCount; i++)
158  {
159  a_Array[i] += a_Workspace[i] * Amplitude;
160  }
161  } // for itr - m_Octaves[]
162  }
163 
164 protected:
166  class cOctave
167  {
168  public:
170 
173 
176 
177  cOctave(int a_Seed, NOISE_DATATYPE a_Frequency, NOISE_DATATYPE a_Amplitude) :
178  m_Noise(a_Seed),
179  m_Frequency(a_Frequency),
180  m_Amplitude(a_Amplitude)
181  {
182  }
183  } ;
184  typedef std::vector<cOctave> cOctaves;
185 
186 
188  int m_Seed;
189 
192 };
193 
194 
195 
196 
auto ToUnsigned(T a_Val)
Definition: Globals.h:387
#define ASSERT(x)
Definition: Globals.h:276
float NOISE_DATATYPE
The datatype used by all the noise generators.
Definition: Noise.h:9
int m_Seed
The seed used by the underlying generators.
Definition: OctavedNoise.h:188
cOctavedNoise(int a_Seed=0)
Definition: OctavedNoise.h:20
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, NOISE_DATATYPE *a_Workspace=nullptr) const
Fills a 3D array with the values of the noise.
Definition: OctavedNoise.h:104
void AddOctave(NOISE_DATATYPE a_Frequency, NOISE_DATATYPE a_Amplitude)
Adds a new octave to the list of octaves that compose this noise.
Definition: OctavedNoise.h:38
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, NOISE_DATATYPE *a_Workspace=nullptr) const
Fills a 2D array with the values of the noise.
Definition: OctavedNoise.h:45
cOctaves m_Octaves
The octaves that compose this noise.
Definition: OctavedNoise.h:191
void SetSeed(int a_Seed)
Sets a new seed for the generators.
Definition: OctavedNoise.h:27
std::vector< cOctave > cOctaves
Definition: OctavedNoise.h:184
Stores information and state for one octave of the noise.
Definition: OctavedNoise.h:167
NOISE_DATATYPE m_Frequency
Coord multiplier.
Definition: OctavedNoise.h:172
NOISE_DATATYPE m_Amplitude
Value multiplier.
Definition: OctavedNoise.h:175
cOctave(int a_Seed, NOISE_DATATYPE a_Frequency, NOISE_DATATYPE a_Amplitude)
Definition: OctavedNoise.h:177