Cuberite
A lightweight, fast and extensible game server for Minecraft
TwoHeights.cpp
Go to the documentation of this file.
1 
2 // TwoHeights.cpp
3 
4 // Implements the cTwoHeights class representing the terrain shape generator using two switched heightmaps
5 
6 #include "Globals.h"
7 #include "TwoHeights.h"
8 #include "../Noise/InterpolNoise.h"
9 #include "HeiGen.h"
10 #include "../LinearUpscale.h"
11 #include "../IniFile.h"
12 
13 
14 
15 
16 
18  public cTerrainShapeGen
19 {
21 
22 public:
23 
24  cTwoHeights(int a_Seed, cBiomeGen & a_BiomeGen):
25  m_Seed(a_Seed),
26  m_Choice(a_Seed),
27  m_HeightA(a_Seed + 1, a_BiomeGen),
28  m_HeightB(a_Seed + 2, a_BiomeGen)
29  {
30  }
31 
32 
33  // cTerrainShapeGen override:
34  virtual void GenShape(cChunkCoords a_ChunkCoords, cChunkDesc::Shape & a_Shape) override
35  {
36  // Generate the two heightmaps:
37  cChunkDef::HeightMap heightsA;
38  cChunkDef::HeightMap heightsB;
39  m_HeightA.GenHeightMap(a_ChunkCoords, heightsA);
40  m_HeightB.GenHeightMap(a_ChunkCoords, heightsB);
41 
42  // Generate the choice noise:
43  NOISE_DATATYPE smallChoice[33 * 5 * 5];
44  NOISE_DATATYPE workspace[33 * 5 * 5];
45  NOISE_DATATYPE startX = 0;
46  NOISE_DATATYPE endX = 256 * m_FrequencyY;
47  NOISE_DATATYPE startY = a_ChunkCoords.m_ChunkX * cChunkDef::Width * m_FrequencyX;
48  NOISE_DATATYPE endY = (a_ChunkCoords.m_ChunkX * cChunkDef::Width + cChunkDef::Width + 1) * m_FrequencyX;
49  NOISE_DATATYPE startZ = a_ChunkCoords.m_ChunkZ * cChunkDef::Width * m_FrequencyZ;
50  NOISE_DATATYPE endZ = (a_ChunkCoords.m_ChunkZ * cChunkDef::Width + cChunkDef::Width + 1) * m_FrequencyZ;
51  m_Choice.Generate3D(smallChoice, 33, 5, 5, startX, endX, startY, endY, startZ, endZ, workspace);
52  NOISE_DATATYPE choice[257 * 17 * 17];
53  LinearUpscale3DArray(smallChoice, 33, 5, 5, choice, 8, 4, 4);
54 
55  // Generate the shape:
56  int idxShape = 0;
57  for (int z = 0; z < cChunkDef::Width; z++)
58  {
59  for (int x = 0; x < cChunkDef::Width; x++)
60  {
61  int idxChoice = 257 * 17 * z + 257 * x;
62  NOISE_DATATYPE heightA = static_cast<NOISE_DATATYPE>(cChunkDef::GetHeight(heightsA, x, z));
63  NOISE_DATATYPE heightB = static_cast<NOISE_DATATYPE>(cChunkDef::GetHeight(heightsB, x, z));
64  for (int y = 0; y < cChunkDef::Height; y++)
65  {
66  int height = static_cast<int>(ClampedLerp(heightA, heightB, choice[idxChoice++]));
67  a_Shape[idxShape++] = (y < height) ? 1 : 0;
68  }
69  } // for x
70  } // for z
71  }
72 
73 
74  virtual void InitializeShapeGen(cIniFile & a_IniFile) override
75  {
76  m_FrequencyX = static_cast<NOISE_DATATYPE>(a_IniFile.GetValueSetF("Generator", "TwoHeightsFrequencyX", 40));
77  m_FrequencyY = static_cast<NOISE_DATATYPE>(a_IniFile.GetValueSetF("Generator", "TwoHeightsFrequencyY", 40));
78  m_FrequencyZ = static_cast<NOISE_DATATYPE>(a_IniFile.GetValueSetF("Generator", "TwoHeightsFrequencyZ", 40));
79 
80  // Initialize the two underlying height generators from an empty INI file:
81  cIniFile empty;
84 
85  // Add the choice octaves:
86  NOISE_DATATYPE freq = 0.001f;
87  NOISE_DATATYPE ampl = 1;
88  for (int i = 0; i < 4; i++)
89  {
90  m_Choice.AddOctave(freq, ampl);
91  freq = freq * 2;
92  ampl = ampl / 2;
93  }
94  }
95 
96 protected:
97  int m_Seed;
98 
101 
104 
107 
110 };
111 
112 
113 
114 
115 
116 std::unique_ptr<cTerrainShapeGen> CreateShapeGenTwoHeights(int a_Seed, cBiomeGen & a_BiomeGen)
117 {
118  return std::make_unique<cTwoHeights>(a_Seed, a_BiomeGen);
119 }
std::unique_ptr< cTerrainShapeGen > CreateShapeGenTwoHeights(int a_Seed, cBiomeGen &a_BiomeGen)
Creates and returns a new instance of the cTwoHeights terrain shape generator.
Definition: TwoHeights.cpp:116
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).
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
float NOISE_DATATYPE
The datatype used by all the noise generators.
Definition: Noise.h:9
Wraps the chunk coords into a single structure.
Definition: ChunkDef.h:57
int m_ChunkZ
Definition: ChunkDef.h:60
int m_ChunkX
Definition: ChunkDef.h:59
HEIGHTTYPE HeightMap[Width *Width]
The type used for any heightmap operations and storage; idx = x + Width * z; Height points to the hig...
Definition: ChunkDef.h:132
static const int Width
Definition: ChunkDef.h:124
static const int Height
Definition: ChunkDef.h:125
static HEIGHTTYPE GetHeight(const HeightMap &a_HeightMap, int a_X, int a_Z)
Definition: ChunkDef.h:303
Byte Shape[256 *16 *16]
The datatype used to represent the entire chunk worth of shape.
Definition: ChunkDesc.h:36
The interface that a biome generator must implement A biome generator takes chunk coords on input and...
The interface that a terrain shape generator must implement A terrain shape generator takes chunk coo...
virtual void InitializeHeightGen(cIniFile &a_IniFile) override
Initializes the generator, reading its parameters from the INI file.
Definition: HeiGen.cpp:553
virtual void GenHeightMap(cChunkCoords a_ChunkCoords, cChunkDef::HeightMap &a_HeightMap) override
Retrieves the heightmap for the specified chunk.
Definition: HeiGen.cpp:513
cOctavedNoise< cInterpolNoise< Interp5Deg > > m_Choice
The noise used to decide between the two heightmaps.
Definition: TwoHeights.cpp:100
virtual void GenShape(cChunkCoords a_ChunkCoords, cChunkDesc::Shape &a_Shape) override
Generates the shape for the given chunk.
Definition: TwoHeights.cpp:34
cHeiGenBiomal m_HeightA
The first height generator.
Definition: TwoHeights.cpp:103
NOISE_DATATYPE m_FrequencyY
Definition: TwoHeights.cpp:109
cHeiGenBiomal m_HeightB
The second height generator.
Definition: TwoHeights.cpp:106
virtual void InitializeShapeGen(cIniFile &a_IniFile) override
Reads parameters from the ini file, prepares generator for use.
Definition: TwoHeights.cpp:74
NOISE_DATATYPE m_FrequencyX
The base frequencies for m_Choice in each of the world axis directions.
Definition: TwoHeights.cpp:109
cTwoHeights(int a_Seed, cBiomeGen &a_BiomeGen)
Definition: TwoHeights.cpp:24
NOISE_DATATYPE m_FrequencyZ
Definition: TwoHeights.cpp:109
double GetValueSetF(const AString &keyname, const AString &valuename, const double defValue=0.0)
Definition: IniFile.cpp:549
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