summaryrefslogtreecommitdiffstats
path: root/src/Generating/Noise3DGenerator.h
blob: ba541fbcc8ad738e12893fb9c718ab948d220ed1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226

// Noise3DGenerator.h

// Declares cNoise3DGenerator and cNoise3DComposable classes, representing 3D-noise-based generators.
// They generate terrain shape by combining a lerp of two 3D noises with a vertical linear gradient
// cNoise3DGenerator is obsolete and unmaintained.
// cNoise3DComposable is used to test parameter combinations for single-biome worlds.





#pragma once

#include "ComposableGenerator.h"
#include "../Noise.h"





class cNoise3DGenerator :
	public cChunkGenerator::cGenerator
{
	typedef cChunkGenerator::cGenerator super;
	
public:
	cNoise3DGenerator(cChunkGenerator & a_ChunkGenerator);
	virtual ~cNoise3DGenerator();
	
	virtual void Initialize(cIniFile & a_IniFile) override;
	virtual void GenerateBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override;
	virtual void DoGenerate(int a_ChunkX, int a_ChunkZ, cChunkDesc & a_ChunkDesc) override;
	
protected:
	// Linear interpolation step sizes, must be divisors of cChunkDef::Width and cChunkDef::Height, respectively:
	static const int UPSCALE_X = 8;
	static const int UPSCALE_Y = 4;
	static const int UPSCALE_Z = 8;
	
	// Linear interpolation buffer dimensions, calculated from the step sizes:
	static const int DIM_X = 1 + cChunkDef::Width  / UPSCALE_X;
	static const int DIM_Y = 1 + cChunkDef::Height / UPSCALE_Y;
	static const int DIM_Z = 1 + cChunkDef::Width  / UPSCALE_Z;

	cPerlinNoise m_Perlin;   // The base 3D noise source for the actual composition
	cCubicNoise  m_Cubic;    // The noise used for heightmap directing
	
	int            m_SeaLevel;
	NOISE_DATATYPE m_HeightAmplification;
	NOISE_DATATYPE m_MidPoint;  // Where the vertical "center" of the noise should be
	NOISE_DATATYPE m_FrequencyX;
	NOISE_DATATYPE m_FrequencyY;
	NOISE_DATATYPE m_FrequencyZ;
	NOISE_DATATYPE m_AirThreshold;
	
	/// Generates the 3D noise array used for terrain generation; a_Noise is of ChunkData-size
	void GenerateNoiseArray(int a_ChunkX, int a_ChunkZ, NOISE_DATATYPE * a_Noise);
	
	/// Updates heightmap based on the chunk's contents
	void UpdateHeightmap(cChunkDesc & a_ChunkDesc);
	
	/// Composes terrain - adds dirt, grass and sand
	void ComposeTerrain(cChunkDesc & a_ChunkDesc);
} ;





class cNoise3DComposable :
	public cTerrainHeightGen,
	public cTerrainCompositionGen
{
public:
	cNoise3DComposable(int a_Seed);

	void Initialize(cIniFile & a_IniFile);

protected:
	/** The noise that is used to choose between density noise A and B. */
	cPerlinNoise m_ChoiceNoise;

	/** Density 3D noise, variant A. */
	cPerlinNoise m_DensityNoiseA;

	/** Density 3D noise, variant B. */
	cPerlinNoise m_DensityNoiseB;

	/** Heightmap-like noise used to provide variance for low-amplitude biomes. */
	cPerlinNoise m_BaseNoise;
	
	/** Block height of the sealevel, used for composing the terrain. */
	int m_SeaLevel;

	/** The main parameter of the generator, specifies the slope of the vertical linear gradient.
	A higher value means a steeper slope and a smaller total amplitude of the generated terrain. */
	NOISE_DATATYPE m_HeightAmplification;

	/** Where the vertical "center" of the noise should be, as block height. */
	NOISE_DATATYPE m_MidPoint;

	// Frequency of the 3D noise's first octave:
	NOISE_DATATYPE m_FrequencyX;
	NOISE_DATATYPE m_FrequencyY;
	NOISE_DATATYPE m_FrequencyZ;

	// Frequency of the base terrain noise:
	NOISE_DATATYPE m_BaseFrequencyX;
	NOISE_DATATYPE m_BaseFrequencyZ;

	// Frequency of the choice noise:
	NOISE_DATATYPE m_ChoiceFrequencyX;
	NOISE_DATATYPE m_ChoiceFrequencyY;
	NOISE_DATATYPE m_ChoiceFrequencyZ;

	// Threshold for when the values are considered air:
	NOISE_DATATYPE m_AirThreshold;
	
	// Cache for the last calculated chunk (reused between heightmap and composition queries):
	int m_LastChunkX;
	int m_LastChunkZ;
	NOISE_DATATYPE m_NoiseArray[17 * 17 * 257];  // x + 17 * z + 17 * 17 * y
	
	
	/** Generates the 3D noise array used for terrain generation (m_NoiseArray), unless the LastChunk coords are equal to coords given */
	void GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_ChunkZ);
	
	// cTerrainHeightGen overrides:
	virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override;
	virtual void InitializeHeightGen(cIniFile & a_IniFile) override { Initialize(a_IniFile); }

	// cTerrainCompositionGen overrides:
	virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc) override;
	virtual void InitializeCompoGen(cIniFile & a_IniFile) override { Initialize(a_IniFile); }
} ;





class cBiomalNoise3DComposable :
	public cTerrainHeightGen,
	public cTerrainCompositionGen
{
public:
	cBiomalNoise3DComposable(int a_Seed, cBiomeGenPtr a_BiomeGen);

	void Initialize(cIniFile & a_IniFile);

protected:
	/** Number of columns around the pixel to query for biomes for averaging. */
	static const int AVERAGING_SIZE = 5;

	/** Type used for a single parameter across the entire (downscaled) chunk. */
	typedef NOISE_DATATYPE ChunkParam[5 * 5];


	/** The noise that is used to choose between density noise A and B. */
	cPerlinNoise m_ChoiceNoise;

	/** Density 3D noise, variant A. */
	cPerlinNoise m_DensityNoiseA;

	/** Density 3D noise, variant B. */
	cPerlinNoise m_DensityNoiseB;

	/** Heightmap-like noise used to provide variance for low-amplitude biomes. */
	cPerlinNoise m_BaseNoise;

	/** The underlying biome generator. */
	cBiomeGenPtr m_BiomeGen;
	
	/** Block height of the sealevel, used for composing the terrain. */
	int m_SeaLevel;

	// Frequency of the 3D noise's first octave:
	NOISE_DATATYPE m_FrequencyX;
	NOISE_DATATYPE m_FrequencyY;
	NOISE_DATATYPE m_FrequencyZ;

	// Frequency of the base terrain noise:
	NOISE_DATATYPE m_BaseFrequencyX;
	NOISE_DATATYPE m_BaseFrequencyZ;

	// Frequency of the choice noise:
	NOISE_DATATYPE m_ChoiceFrequencyX;
	NOISE_DATATYPE m_ChoiceFrequencyY;
	NOISE_DATATYPE m_ChoiceFrequencyZ;

	// Threshold for when the values are considered air:
	NOISE_DATATYPE m_AirThreshold;
	
	// Cache for the last calculated chunk (reused between heightmap and composition queries):
	int m_LastChunkX;
	int m_LastChunkZ;
	NOISE_DATATYPE m_NoiseArray[17 * 17 * 257];  // x + 17 * z + 17 * 17 * y

	/** Weights for summing up neighboring biomes. */
	NOISE_DATATYPE m_Weight[AVERAGING_SIZE * 2 + 1][AVERAGING_SIZE * 2 + 1];

	/** The sum of m_Weight[]. */
	NOISE_DATATYPE m_WeightSum;
	
	
	/** Generates the 3D noise array used for terrain generation (m_NoiseArray), unless the LastChunk coords are equal to coords given */
	void GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_ChunkZ);

	/** Calculates the biome-related parameters for the chunk. */
	void CalcBiomeParamArrays(int a_ChunkX, int a_ChunkZ, ChunkParam & a_HeightAmp, ChunkParam & a_MidPoint);

	/** Returns the parameters for the specified biome. */
	void GetBiomeParams(EMCSBiome a_Biome, NOISE_DATATYPE & a_HeightAmp, NOISE_DATATYPE & a_MidPoint);
	
	// cTerrainHeightGen overrides:
	virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override;
	virtual void InitializeHeightGen(cIniFile & a_IniFile) override { Initialize(a_IniFile); }

	// cTerrainCompositionGen overrides:
	virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc) override;
	virtual void InitializeCompoGen(cIniFile & a_IniFile) override { Initialize(a_IniFile); }
} ;