summary refs log tree commit diff
path: root/src/World/Generator.cpp
diff options
context:
space:
mode:
authorMel <einebeere@gmail.com>2023-07-07 21:39:42 +0200
committerMel <einebeere@gmail.com>2023-07-07 21:39:42 +0200
commitf1fc192ddc4c739fa8b4b376c759b7d3218a34eb (patch)
tree9e9afb9a21ba3ca27d1f25d46230aa9d27f8be39 /src/World/Generator.cpp
parent24b8124469350d1c80d0553cf3f4bf58cdb1489b (diff)
downloadmeowcraft-f1fc192ddc4c739fa8b4b376c759b7d3218a34eb.tar.zst
meowcraft-f1fc192ddc4c739fa8b4b376c759b7d3218a34eb.zip
Chunk-bound tree decoration
Diffstat (limited to 'src/World/Generator.cpp')
-rw-r--r--src/World/Generator.cpp321
1 files changed, 0 insertions, 321 deletions
diff --git a/src/World/Generator.cpp b/src/World/Generator.cpp
deleted file mode 100644
index ada2b7b..0000000
--- a/src/World/Generator.cpp
+++ /dev/null
@@ -1,321 +0,0 @@
-#include "Generator.hpp"
-#include "../Math/Interpolation.hpp"
-#include "../Math/Sigmoid.hpp"
-
-namespace MC::World {
-
-Chunk Generator::generate(int64_t chunk_x, int64_t chunk_y) {
-    Chunk chunk(chunk_x, chunk_y);
-
-    auto landmass_map = generate_landmass_map(chunk_x, chunk_y);
-    auto hill_map = generate_hill_map(chunk_x, chunk_y);
-    auto height_map = generate_height_map(landmass_map, hill_map, chunk_x, chunk_y);
-
-    auto biome_map = generate_biome_map(landmass_map, hill_map, height_map, chunk_x, chunk_y);
-    auto terrain_map = generate_terrain(height_map, chunk_x, chunk_y);
-
-    decorate_soil(chunk, biome_map, terrain_map);
-
-    chunk.set_details({{landmass_map}, {hill_map}, {biome_map}});
-
-    return chunk;
-}
-
-Generator::Map2D<float> Generator::generate_landmass_map(int64_t chunk_x, int64_t chunk_y) {
-    Matrix<Chunk::Width, Chunk::Width> landmass_map{};
-
-    for (uint x = 0; x < Chunk::Width; x++) {
-        for (uint y = 0; y < Chunk::Width; y++) {
-            auto world_pos = chunk_position_to_world_vector(chunk_x, chunk_y, x, y);
-            landmass_map(x, y) = get_landmass(world_pos);
-        }
-    }
-
-    return landmass_map;
-}
-
-Generator::Map2D<float> Generator::generate_hill_map(int64_t chunk_x, int64_t chunk_y) {
-    Map2D<float> hill_map{};
-
-    for (uint x = 0; x < Chunk::Width; x++) {
-        for (uint y = 0; y < Chunk::Width; y++) {
-            hill_map(x, y) = get_hill(chunk_position_to_world_vector(chunk_x, chunk_y, x, y));
-        }
-    }
-
-    return hill_map;
-}
-
-Generator::Map2D<float> Generator::generate_height_map(Map2D<float>& landmass_map, Map2D<float>& hill_map, int64_t chunk_x, int64_t chunk_y) {
-    Map2D<float> height_map{};
-
-    for (uint x = 0; x < Chunk::Width; x++) {
-        for (uint y = 0; y < Chunk::Width; y++) {
-            auto landmass_effect = landmass_map(x, y);
-            auto hill_effect = hill_map(x, y);
-
-            auto hill = hill_effect * landmass_effect * 1.4 - 0.4;
-            auto landmass = landmass_effect * 0.6 + 0.4;
-
-            auto height = (hill + landmass) / 2.0f;
-
-            height_map(x, y) = height;
-        }
-    }
-
-    return height_map;
-}
-
-Generator::Map2D<BiomeType> Generator::generate_biome_map(Map2D<float>& landmass_map, Map2D<float>& hill_map, Map2D<float>& height_map, int64_t chunk_x, int64_t chunk_y) {
-    Map2D<BiomeType> biome_map{};
-
-    for (uint x = 0; x < Chunk::Width; x++) {
-        for (uint y = 0; y < Chunk::Width; y++) {
-            float landmass = landmass_map(x, y);
-            float hill = hill_map(x, y);
-
-            auto world_pos = chunk_position_to_world_vector(chunk_x, chunk_y, x, y);
-            float temperature = get_temperature(world_pos);
-            float humidity = get_humidity(world_pos);
-
-            HillSlice hill_slice;
-            if (hill > 0.9) { hill_slice = HillSlice::Mountain; }
-            else if (hill > 0.33) { hill_slice = HillSlice::Middle; }
-            else { hill_slice = HillSlice::Valley; }
-
-            LandmassSlice landmass_slice;
-            if (landmass > 0.8) { landmass_slice = LandmassSlice::Land; }
-            else if (landmass > 0.45) { landmass_slice = LandmassSlice::Beach; }
-            else { landmass_slice = LandmassSlice::Ocean; }
-
-            TemperatureZone temparature_zone;
-            if (temperature > 0.66) { temparature_zone = TemperatureZone::Hot; }
-            else if (temperature > 0.33) { temparature_zone = TemperatureZone::Fair; }
-            else { temparature_zone = TemperatureZone::Cold; }
-
-            HumidityZone humidity_zone;
-            if (humidity > 0.66) { humidity_zone = HumidityZone::Wet; }
-            else if (humidity > 0.33) { humidity_zone = HumidityZone::Temperate; }
-            else { humidity_zone = HumidityZone::Dry; }
-
-            auto biome = lookup_biome(hill_slice, landmass_slice, temparature_zone, humidity_zone);
-            biome_map(x, y) = biome;
-        }
-    }
-
-    return biome_map;
-}
-
-Generator::Map3D<bool> Generator::generate_terrain(Map2D<float>& height_map, int64_t chunk_x, int64_t chunk_y) {
-    float jaggedness = 0.10f;
-
-    Map3D<bool> terrain_map{};
-    for (uint x = 0; x < Chunk::Width; x++) {
-        for (uint z = 0; z < Chunk::Width; z++) {
-            auto height = height_map(x, z);
-
-            for (uint y = 0; y < Chunk::Height; y++) {
-                float density = get_density({Chunk::Width * chunk_x + (float)x, (float)y, Chunk::Width * chunk_y + (float)z});
-                float threshold = Math::sigmoid(((float)y / (Chunk::Height * height * 2) - 0.5f) / jaggedness);
-
-                if (density > threshold) {
-                    terrain_map(x, y, z) = true;
-                }
-            }
-        }
-    }
-
-    return terrain_map;
-}
-
-void Generator::decorate_soil(Chunk& chunk, Map2D<BiomeType>& biome_map, Map3D<bool>& terrain_map) {
-    constexpr uint dirt_depth = 4;
-    constexpr uint water_height = 39;
-
-    for (uint x = 0; x < Chunk::Width; x++) {
-        for (uint z = 0; z < Chunk::Width; z++) {
-            auto biome = biome_map(x, z);
-
-            BlockType top_block{};
-            BlockType soil_block{};
-            switch (biome) {
-            case BiomeType::Beach:
-            case BiomeType::Desert:
-                top_block = BlockType::Sand;
-                soil_block = BlockType::Sand;
-                break;
-            case BiomeType::Jungle:
-            case BiomeType::Forest:
-            case BiomeType::Plains:
-            case BiomeType::River:
-            case BiomeType::Ocean:
-                top_block = BlockType::Grass;
-                soil_block = BlockType::Dirt;
-                break;
-            case BiomeType::Alpine:
-                top_block = BlockType::Snow;
-                soil_block = BlockType::Dirt;
-                break;
-            }
-
-            auto column_depth = 0;
-            for (uint y = Chunk::Height - 1; y > 0; y--) {
-                auto block = terrain_map(x, y, z);
-                if (block) {
-                    if (column_depth == 0 && y >= water_height - 1) {
-                        chunk.set(x, y, z, {top_block});
-                    } else if (column_depth < dirt_depth) {
-                        chunk.set(x, y, z, {soil_block});
-                    } else {
-                        chunk.set(x, y, z, {BlockType::Stone});
-                    }
-                    column_depth++;
-                } else {
-                    if (y < water_height) {
-                        chunk.set(x, y, z, {BlockType::Water});
-                    }
-                    column_depth = 0;
-                }
-            }
-        }
-    }
-}
-
-#define CURVE_START(y) constexpr auto lerp = Math::linear_interpolation; float _py = y; float _px = 0.0f;
-#define CURVE_POINT(x, y) if (v < x) return lerp({_py, y}, _px, x, v); _py = y; _px = x
-#define CURVE_END(y) return lerp({_py, y}, _px, 1.0f, v);
-
-float Generator::get_landmass(Vector<2> pos) const {
-    auto v = m_landmass_noise.at(pos);
-
-    CURVE_START(1.0f);
-    CURVE_POINT(0.1f, 0.8f);
-    CURVE_POINT(0.3f, 0.8f);
-    CURVE_POINT(0.37f, 0.125f);
-    CURVE_POINT(0.4f, 0.4f);
-    CURVE_POINT(0.46f, 0.45f);
-    CURVE_POINT(0.47f, 0.875f);
-    CURVE_POINT(0.48f, 0.9f);
-    CURVE_POINT(0.55f, 0.95f);
-    CURVE_END(1.0f);
-}
-
-float Generator::get_hill(Vector<2> pos) const {
-    auto v = m_hill_noise.at(pos);
-
-    CURVE_START(0.33f);
-    CURVE_POINT(0.25f, 1.0f);
-
-    CURVE_POINT(0.49f, 0.1f);
-    CURVE_POINT(0.5f, 0.0f);
-    CURVE_POINT(0.51f, 0.1f);
-
-    CURVE_POINT(0.75f, 1.0f);
-    CURVE_END(0.33f);
-}
-
-float Generator::get_humidity(Vector<2> pos) const {
-    auto v = m_humidity_noise.at(pos);
-    return v;
-}
-
-float Generator::get_temperature(Vector<2> pos) const {
-    auto v = m_temperature_noise.at(pos);
-    return v;
-}
-
-float Generator::get_density(Vector<3> pos) const {
-    auto v = m_density_noise.at(pos);
-    return v;
-}
-
-Vector<2> Generator::chunk_position_to_world_vector(int64_t chunk_x, int64_t chunk_y, uint x, uint y) {
-    return {(float)x + chunk_x * Chunk::Width, (float)y + chunk_y * Chunk::Width};
-}
-
-std::array<BiomeType, Generator::biome_lookup_table_size> Generator::create_biome_lookup_table() {
-    std::array<BiomeType, biome_lookup_table_size> table{};
-
-    auto inc = [](auto& x) { x = (std::remove_reference_t<decltype(x)>)((uint)x + 1); };
-    auto cmp = [](auto x, auto s) { return (uint)x < (uint)s; };
-
-    for (HillSlice hill_slice{}; cmp(hill_slice, HillSliceSize); inc(hill_slice)) {
-        for (LandmassSlice landmass_slice{}; cmp(landmass_slice, LandmassSliceSize); inc(landmass_slice)) {
-            for (TemperatureZone temperature_zone{}; cmp(temperature_zone, TemperatureZoneSize); inc(temperature_zone)) {
-                for (HumidityZone humidity_zone{}; cmp(humidity_zone, HumidityZoneSize); inc(humidity_zone)) {
-                    BiomeType biome{};
-                    if (landmass_slice == LandmassSlice::Ocean) {
-                        biome = BiomeType::Ocean;
-                        goto set;
-                    }
-                    if (landmass_slice == LandmassSlice::Beach) {
-                        biome = BiomeType::Beach;
-                        goto set;
-                    }
-
-                    if (hill_slice == HillSlice::Valley) {
-                        biome = BiomeType::River;
-                        goto set;
-                    }
-                    if (hill_slice == HillSlice::Mountain) {
-                        if (temperature_zone == TemperatureZone::Hot) {
-                            biome = BiomeType::Desert;
-                        } else {
-                            biome = BiomeType::Alpine;
-                        }
-                        goto set;
-                    }
-
-                    switch (temperature_zone) {
-                    case TemperatureZone::Hot:
-                        biome = BiomeType::Desert;
-                        break;
-                    case TemperatureZone::Fair:
-                        switch (humidity_zone) {
-                        case HumidityZone::Wet:
-                            biome = BiomeType::Jungle;
-                            break;
-                        case HumidityZone::Lush:
-                            biome = BiomeType::Forest;
-                            break;
-                        case HumidityZone::Temperate:
-                        case HumidityZone::Dry:
-                            biome = BiomeType::Plains;
-                            break;
-                        }
-                        break;
-                    case TemperatureZone::Cold:
-                        switch (humidity_zone) {
-                        case HumidityZone::Wet:
-                        case HumidityZone::Lush:
-                            biome = BiomeType::Alpine;
-                            break;
-                        case HumidityZone::Temperate:
-                        case HumidityZone::Dry:
-                            biome = BiomeType::Plains;
-                            break;
-                        }
-                        break;
-                    }
-
-                    set:
-                    table[biome_lookup_table_index(hill_slice, landmass_slice, temperature_zone, humidity_zone)] = biome;
-                }
-            }
-        }
-    }
-
-    return table;
-}
-
-size_t Generator::biome_lookup_table_index(HillSlice hill_slice, LandmassSlice landmass_slice, TemperatureZone temperature_zone, HumidityZone humidity_zone) {
-    auto hs = (uint8_t)hill_slice; auto ls = (uint8_t)landmass_slice; auto tz = (uint8_t)temperature_zone; auto hz = (uint8_t)humidity_zone;
-    auto LS_S = (uint8_t)LandmassSliceSize; auto TZ_S = (uint8_t)TemperatureZoneSize; auto HZ_S = (uint8_t)HumidityZoneSize;
-    return (hs * LS_S * TZ_S * HZ_S) + (ls * TZ_S * HZ_S) + (tz * HZ_S) + hz;
-}
-
-BiomeType Generator::lookup_biome(HillSlice hill_slice, LandmassSlice landmass_slice, TemperatureZone temperature_zone, HumidityZone humidity_zone) {
-    return biome_lookup_table.at(biome_lookup_table_index(hill_slice, landmass_slice, temperature_zone, humidity_zone));
-}
-
-}