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
|
#pragma once
#include "../../Common/Sizes.hpp"
#include "../Chunk.hpp"
#include "../BiomeType.hpp"
#include "../../Math/Perlin.hpp"
#include "../../Math/Tensor.hpp"
#include "Decoration.hpp"
namespace MC::World::Generation {
class Generator {
public:
Generator() = default;
Chunk generate(I64 chunk_x, I64 chunk_y);
private:
template <typename V> using Map2D = Matrix<Chunk::Width, Chunk::Width, V>;
template <typename V> using Map3D = Tensor<3, V, Chunk::Width, Chunk::Height, Chunk::Width>;
Map2D<Real> generate_landmass_map(I64 chunk_x, I64 chunk_y);
Map2D<Real> generate_hill_map(I64 chunk_x, I64 chunk_y);
Map2D<Real> generate_height_map(Map2D<Real>& landmass_map, Map2D<Real>& hill_map);
Map2D<Real> generate_temperature_map(I64 chunk_x, I64 chunk_y);
Map2D<Real> generate_humidity_map(I64 chunk_x, I64 chunk_y);
Map2D<BiomeType> generate_biome_map(
Map2D<Real>& landmass_map, Map2D<Real>& hill_map,
Map2D<Real>& temperature_map, Map2D<Real>& humidity_map
);
Map3D<Bool> generate_terrain(Map2D<Real>& height_map, I64 chunk_x, I64 chunk_y);
void decorate_soil(Chunk& chunk, Map2D<BiomeType>& biome_map, Map3D<Bool>& terrain_map);
[[nodiscard]] Real get_landmass(Vector<2> pos) const;
[[nodiscard]] Real get_hill(Vector<2> pos) const;
[[nodiscard]] Real get_humidity(Vector<2> pos) const;
[[nodiscard]] Real get_temperature(Vector<2> pos) const;
[[nodiscard]] Real get_density(Vector<3> pos) const;
static Vector<2> chunk_position_to_world_vector(I64 chunk_x, I64 chunk_y, UInt x, UInt y);
static inline std::vector<Decorator*> s_decorators = {
new TreeDecorator(),
};
Math::Perlin::Noise<2> m_landmass_noise{.scale=800.0f, .octaves=4, .persistence=0.3f, .lacunarity=3.5f};
Math::Perlin::Noise<2> m_hill_noise{.scale=400.0f, .octaves=3, .persistence=0.5f, .lacunarity=2.0f};
Math::Perlin::Noise<2> m_temperature_noise{.scale=700.0f, .octaves=4, .persistence=0.4f, .lacunarity=3.0f};
Math::Perlin::Noise<2> m_humidity_noise{.scale=400.0f, .octaves=2, .persistence=0.4f, .lacunarity=3.0f};
Math::Perlin::Noise<3> m_density_noise{.scale=30.0f, .octaves=2, .persistence=0.7f, .lacunarity=2.0f};
enum class HillSlice { Mountain, Middle, Valley };
enum class LandmassSlice { Land, Beach, Ocean };
enum class TemperatureZone { Hot, Fair, Cold };
enum class HumidityZone { Wet, Lush, Temperate, Dry };
static constexpr UInt HillSliceSize = (UInt)HillSlice::Valley + 1;
static constexpr UInt LandmassSliceSize = (UInt)LandmassSlice::Ocean + 1;
static constexpr UInt TemperatureZoneSize = (UInt)TemperatureZone::Cold + 1;
static constexpr UInt HumidityZoneSize = (UInt)HumidityZone::Dry + 1;
static constexpr USize biome_lookup_table_size = (USize)HillSliceSize * (USize)LandmassSliceSize * (USize)TemperatureZoneSize * (USize)HumidityZoneSize;
static std::array<BiomeType, biome_lookup_table_size> create_biome_lookup_table();
static USize biome_lookup_table_index(HillSlice hill_slice, LandmassSlice landmass_slice, TemperatureZone temperature_zone, HumidityZone humidity_zone);
static BiomeType lookup_biome(HillSlice hill_slice, LandmassSlice landmass_slice, TemperatureZone temperature_zone, HumidityZone humidity_zone);
static inline std::array<BiomeType, biome_lookup_table_size> biome_lookup_table = create_biome_lookup_table();
};
}
|