Cuberite
A lightweight, fast and extensible game server for Minecraft
EndGen.cpp
Go to the documentation of this file.
1 
2 // EndGen.cpp
3 
4 // Implements the cEndGen class representing the generator for the End, both as a HeightGen and CompositionGen
5 
6 #include "Globals.h"
7 #include "EndGen.h"
8 #include "../IniFile.h"
9 #include "../LinearUpscale.h"
10 
11 
12 
13 
14 
15 enum
16 {
17  // Interpolation cell size:
21 
22  // Size of chunk data, downscaled before interpolation:
23  DIM_X = 16 / INTERPOL_X + 1,
24  DIM_Y = 256 / INTERPOL_Y + 1,
25  DIM_Z = 16 / INTERPOL_Z + 1,
26 } ;
27 
28 
29 
30 
31 
33 // cEndGen:
34 
35 cEndGen::cEndGen(int a_Seed) :
36  m_Seed(a_Seed),
37  m_IslandSizeX(256),
38  m_IslandSizeY(96),
39  m_IslandSizeZ(256),
40  m_FrequencyX(80),
41  m_FrequencyY(80),
42  m_FrequencyZ(80),
43  m_MinChunkX(0),
44  m_MaxChunkX(0),
45  m_MinChunkZ(0),
46  m_MaxChunkZ(0),
47  m_LastChunkCoords(0x7fffffff, 0x7fffffff) // Use dummy coords that won't ever be used by real chunks
48 {
49  m_Perlin.AddOctave(1, 1);
50  m_Perlin.AddOctave(2, 0.5);
51  m_Perlin.AddOctave(4, 0.25);
52 }
53 
54 
55 
56 
57 
59 {
60  m_IslandSizeX = a_IniFile.GetValueSetI("Generator", "EndGenIslandSizeX", m_IslandSizeX);
61  m_IslandSizeY = a_IniFile.GetValueSetI("Generator", "EndGenIslandSizeY", m_IslandSizeY);
62  m_IslandSizeZ = a_IniFile.GetValueSetI("Generator", "EndGenIslandSizeZ", m_IslandSizeZ);
63 
64  m_FrequencyX = static_cast<NOISE_DATATYPE>(a_IniFile.GetValueSetF("Generator", "EndGenFrequencyX", m_FrequencyX));
65  m_FrequencyY = static_cast<NOISE_DATATYPE>(a_IniFile.GetValueSetF("Generator", "EndGenFrequencyY", m_FrequencyY));
66  m_FrequencyZ = static_cast<NOISE_DATATYPE>(a_IniFile.GetValueSetF("Generator", "EndGenFrequencyZ", m_FrequencyZ));
67 
68  // Recalculate the min and max chunk coords of the island
73 }
74 
75 
76 
77 
78 
80 {
81  ASSERT(!IsChunkOutsideRange(a_ChunkCoords)); // Should be filtered before calling this function
82 
83  if (m_LastChunkCoords == a_ChunkCoords)
84  {
85  return;
86  }
87 
88  m_LastChunkCoords = a_ChunkCoords;
89 
91 }
92 
93 
94 
95 
96 
98 {
99  NOISE_DATATYPE NoiseData[DIM_X * DIM_Y * DIM_Z]; // [x + DIM_X * z + DIM_X * DIM_Z * y]
100  NOISE_DATATYPE Workspace[DIM_X * DIM_Y * DIM_Z]; // [x + DIM_X * z + DIM_X * DIM_Z * y]
101 
102  // Generate the downscaled noise:
107  NOISE_DATATYPE StartY = 0;
108  NOISE_DATATYPE EndY = static_cast<NOISE_DATATYPE>(257) / m_FrequencyY;
109  m_Perlin.Generate3D(NoiseData, DIM_X, DIM_Z, DIM_Y, StartX, EndX, StartZ, EndZ, StartY, EndY, Workspace);
110 
111  // Add distance:
112  int idx = 0;
113  for (int y = 0; y < DIM_Y; y++)
114  {
115  NOISE_DATATYPE ValY = static_cast<NOISE_DATATYPE>(2 * INTERPOL_Y * y - m_IslandSizeY) / m_IslandSizeY;
116  ValY = ValY * ValY;
117  for (int z = 0; z < DIM_Z; z++)
118  {
120  ValZ = ValZ * ValZ;
121  for (int x = 0; x < DIM_X; x++)
122  {
123  // NOISE_DATATYPE ValX = StartX + (EndX - StartX) * x / (DIM_X - 1);
125  ValX = ValX * ValX;
126  NoiseData[idx++] += ValX + ValZ + ValY;
127  } // for x
128  } // for z
129  } // for y
130 
131  // Upscale into real chunk size:
133 }
134 
135 
136 
137 
138 
140 {
141  return (
142  (a_ChunkCoords.m_ChunkX < m_MinChunkX) || (a_ChunkCoords.m_ChunkX > m_MaxChunkX) ||
143  (a_ChunkCoords.m_ChunkZ < m_MinChunkZ) || (a_ChunkCoords.m_ChunkZ > m_MaxChunkZ)
144  );
145 }
146 
147 
148 
149 
150 
151 void cEndGen::GenShape(cChunkCoords a_ChunkCoords, cChunkDesc::Shape & a_Shape)
152 {
153  // If the chunk is outside out range, fill the shape with zeroes:
154  if (IsChunkOutsideRange(a_ChunkCoords))
155  {
156  for (size_t i = 0; i < ARRAYCOUNT(a_Shape); i++)
157  {
158  a_Shape[i] = 0;
159  }
160  return;
161  }
162 
163  PrepareState(a_ChunkCoords);
164 
165  int MaxY = std::min(static_cast<int>(1.75 * m_IslandSizeY + 1), cChunkDef::Height - 1);
166  for (int z = 0; z < cChunkDef::Width; z++)
167  {
168  for (int x = 0; x < cChunkDef::Width; x++)
169  {
170  for (int y = 0; y < MaxY; y++)
171  {
172  a_Shape[(x + 16 * z) * 256 + y] = (m_NoiseArray[y * 17 * 17 + z * 17 + z] > 0) ? 1 : 0;
173  }
174  for (int y = MaxY; y < cChunkDef::Height; y++)
175  {
176  a_Shape[(x + 16 * z) * 256 + y] = 0;
177  }
178  } // for x
179  } // for z
180 }
181 
182 
183 
184 
185 
186 void cEndGen::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape)
187 {
188  a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0);
189  for (int z = 0; z < cChunkDef::Width; z++)
190  {
191  for (int x = 0; x < cChunkDef::Width; x++)
192  {
193  for (int y = 0; y < cChunkDef::Height; y++)
194  {
195  if (a_Shape[(x + 16 * z) * 256 + y] != 0)
196  {
197  a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_END_STONE);
198  }
199  } // for y
200  } // for x
201  } // for z
202 }
203 
204 
205 
206 
NOISE_DATATYPE m_NoiseArray[17 *17 *257]
Definition: EndGen.h:50
bool IsChunkOutsideRange(cChunkCoords a_ChunkCoords)
Returns true if the chunk is outside of the island&#39;s dimensions.
Definition: EndGen.cpp:139
Byte Shape[256 *16 *16]
The datatype used to represent the entire chunk worth of shape.
Definition: ChunkDesc.h:36
void SetBlockType(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType)
Definition: ChunkDesc.cpp:81
double GetValueSetF(const AString &keyname, const AString &valuename, const double defValue=0.0)
Definition: IniFile.cpp:547
void PrepareState(cChunkCoords a_ChunkCoords)
Unless the LastChunk coords are equal to coords given, prepares the internal state (noise array) ...
Definition: EndGen.cpp:79
static const int Width
Definition: ChunkDef.h:134
virtual void InitializeCompoGen(cIniFile &a_IniFile) override
Reads parameters from the ini file, prepares generator for use.
Definition: EndGen.cpp:58
Definition: EndGen.cpp:25
cChunkCoords m_LastChunkCoords
Definition: EndGen.h:49
static const int Height
Definition: ChunkDef.h:135
void GenerateNoiseArray(void)
Generates the m_NoiseArray array for the current chunk.
Definition: EndGen.cpp:97
cEndGen(int a_Seed)
Definition: EndGen.cpp:35
Definition: EndGen.cpp:23
int m_IslandSizeX
Definition: EndGen.h:35
float NOISE_DATATYPE
The datatype used by all the noise generators.
Definition: Noise.h:9
#define ASSERT(x)
Definition: Globals.h:335
int m_IslandSizeY
Definition: EndGen.h:36
int m_ChunkZ
Definition: ChunkDef.h:60
virtual void GenShape(cChunkCoords a_ChunkCoords, cChunkDesc::Shape &a_Shape) override
Generates the shape for the given chunk.
Definition: EndGen.cpp:151
cPerlinNoise m_Perlin
The Perlin noise used for generating.
Definition: EndGen.h:32
int m_MinChunkZ
Definition: EndGen.h:46
int m_ChunkX
Definition: ChunkDef.h:59
NOISE_DATATYPE m_FrequencyY
Definition: EndGen.h:41
int m_MaxChunkX
Definition: EndGen.h:45
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
int m_MaxChunkZ
Definition: EndGen.h:46
virtual void ComposeTerrain(cChunkDesc &a_ChunkDesc, const cChunkDesc::Shape &a_Shape) override
Generates the chunk&#39;s composition into a_ChunkDesc, using the terrain shape provided in a_Shape...
Definition: EndGen.cpp:186
int GetValueSetI(const AString &keyname, const AString &valuename, const int defValue=0) override
Definition: IniFile.cpp:558
NOISE_DATATYPE m_FrequencyX
Definition: EndGen.h:40
Definition: EndGen.cpp:24
int m_MinChunkX
Definition: EndGen.h:45
NOISE_DATATYPE m_FrequencyZ
Definition: EndGen.h:42
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 FillBlocks(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
Definition: ChunkDesc.cpp:54
int m_IslandSizeZ
Definition: EndGen.h:37
void LinearUpscale3DArray(TYPE *a_Src, int a_SrcSizeX, int a_SrcSizeY, int a_SrcSizeZ, TYPE *a_Dst, int a_UpscaleX, int a_UpscaleY, int a_UpscaleZ)
Linearly interpolates values in the array between the equidistant anchor points (upscales).
#define ARRAYCOUNT(X)
Evaluates to the number of elements in an array (compile-time!)
Definition: Globals.h:290