summary refs log tree commit diff
path: root/src/World/Generator.cpp
diff options
context:
space:
mode:
authorMel <einebeere@gmail.com>2023-06-12 17:09:55 +0200
committerMel <einebeere@gmail.com>2023-06-12 17:14:03 +0200
commitd0de60dc33df75fbcacb53a09568b14d0fd48cb9 (patch)
tree7aefdbb81f114552881834bd5b0d842bc2bdb691 /src/World/Generator.cpp
parent23b0bc4d1ddc9fad3c32e8257497ddd13ac6a155 (diff)
downloadmeowcraft-d0de60dc33df75fbcacb53a09568b14d0fd48cb9.tar.zst
meowcraft-d0de60dc33df75fbcacb53a09568b14d0fd48cb9.zip
Multithreaded world generation with Perlin
Diffstat (limited to 'src/World/Generator.cpp')
-rw-r--r--src/World/Generator.cpp184
1 files changed, 12 insertions, 172 deletions
diff --git a/src/World/Generator.cpp b/src/World/Generator.cpp
index 875a79b..e8b3bbd 100644
--- a/src/World/Generator.cpp
+++ b/src/World/Generator.cpp
@@ -1,190 +1,30 @@
 #include "Generator.hpp"
-#include "../Math/Noise.hpp"
+#include "../Math/Perlin.hpp"
 
 namespace MC::World {
 
 Chunk Generator::generate(int64_t chunk_x, int64_t chunk_y) {
     Chunk chunk(chunk_x, chunk_y);
 
-    auto ocean_weights = ocean_weights_pass(chunk_x, chunk_y);
-    auto biome_weights = biome_weights_pass(chunk_x, chunk_y, ocean_weights);
-    auto heights = height_pass(chunk_x, chunk_y, biome_weights);
-    auto biomes = flat_biome_pass(biome_weights);
+    Math::Perlin::Noise<3> noise{.scale=20.0f, .octaves=2};
 
-    float extent = 60.0f;
-    float base = 4.0f;
-
-    for (int x = 0; x < Chunk::Width; x++) {
-        for (int z = 0; z < Chunk::Width; z++) {
-            uint32_t height = std::round(heights(x, z) * extent + base);
-
-            auto biome = biomes(x, z);
-
-            BlockType top_block{};
-            BlockType fill_block{};
-            switch (biome) {
-                case BiomeType::Forest:
-                case BiomeType::Plains:
-                    top_block = BlockType::Grass;
-                    fill_block = BlockType::Dirt;
-                    break;
-                case BiomeType::Desert:
-                    top_block = BlockType::Sand;
-                    fill_block = BlockType::Sand;
-                    break;
-                case BiomeType::Ocean:
-                    top_block = BlockType::Water;
-                    fill_block = BlockType::Dirt;
-                    break;
-            }
-
-            for (int y = 0; y < Chunk::Height; y++) {
-                BlockType type = BlockType::Air;
-                if (y < (int32_t)height - 10) {
-                    type = BlockType::Stone;
-                } else if (y < height) {
-                    type = fill_block;
-                } else if (y == height) {
-                    type = top_block;
-                }
-
-                chunk.set(x, y, z, type);
-            }
-        }
-    }
-
-    return chunk;
-}
-
-Matrix<Chunk::Width, Chunk::Width> Generator::ocean_weights_pass(int64_t chunk_x, int64_t chunk_y) {
-    auto ocean_offset = 1125.0f;
-    auto ocean_scale = 0.05f;
-
-    Matrix<Chunk::Width, Chunk::Width> ocean_weights{};
-    for (int x = 0; x < Chunk::Width; x++) {
-        for (int y = 0; y < Chunk::Width; y++) {
-            float ocean_weight = Math::noise2d({
-                (chunk_x * Chunk::Width + x) * ocean_scale + ocean_offset,
-                (chunk_y * Chunk::Width + y) * ocean_scale + ocean_offset
-            });
-
-            ocean_weights(x, y) = ocean_weight;
-        }
-    }
-
-    return ocean_weights;
-}
-
-Matrix<Chunk::Width, Chunk::Width, Vector<BiomeType::Size>> Generator::biome_weights_pass(
-    int64_t chunk_x,
-    int64_t chunk_y,
-    Matrix<Chunk::Width, Chunk::Width, float> ocean_weights
-) {
-    auto ocean_threshold = 0.4f;
-
-    std::vector<float> biome_offsets = {110.0f, 2450.0f, 5042.0f};
-    auto biome_scale = 0.15f;
-
-    Matrix<Chunk::Width, Chunk::Width, Vector<BiomeType::Size>> biome_weights{};
-    for (int x = 0; x < Chunk::Width; x++) {
-        for (int y = 0; y < Chunk::Width; y++) {
-            Vector<BiomeType::Size> weights{};
-            for (auto biome : MC::World::BiomeType::all_ground()) {
-                float biome_noise = Math::noise2d({
-                    (chunk_x * Chunk::Width + x) * biome_scale + biome_offsets[biome],
-                    (chunk_y * Chunk::Width + y) * biome_scale + biome_offsets[biome]
+    for (uint x = 0; x < Chunk::Width; x++) {
+        for (uint z = 0; z < Chunk::Width; z++) {
+            for (uint y = 0; y < Chunk::Height; y++) {
+                auto value = noise.at({
+                    (float)(chunk_x * Chunk::Width + x),
+                    (float)y,
+                    (float)(chunk_y * Chunk::Width + z),
                 });
 
-                weights[biome] = biome_noise;
-            }
-
-            bool ocean_weight = ocean_weights(x, y) < ocean_threshold;
-            weights[MC::World::BiomeType::Ocean] = ocean_weight;
-
-            biome_weights(x,y) = weights;
-        }
-    }
-
-    return biome_weights;
-}
-
-Matrix<Chunk::Width, Chunk::Width> Generator::height_pass(
-    int64_t chunk_x,
-    int64_t chunk_y,
-    Matrix<Chunk::Width, Chunk::Width, Vector<BiomeType::Size>> biome_weights
-) {
-    auto height_offset = 6050.0f;
-    auto height_scale = 0.7f;
-
-    Matrix<Chunk::Width, Chunk::Width> heights{};
-    for (int x = 0; x < Chunk::Width; x++) {
-        for (int y = 0; y < Chunk::Width; y++) {
-            auto weights = biome_weights(x, y);
-
-            auto total_weight = 0.0f;
-            for (auto biome : MC::World::BiomeType::all()) {
-                total_weight += weights[biome];
-            }
-
-            std::pair<float, float> total_effect{};
-            for (auto biome : MC::World::BiomeType::all()) {
-                auto weight = weights[biome];
-
-                std::pair<float, float> effect{};
-                switch (biome) {
-                    case MC::World::BiomeType::Forest:
-                        effect = {0.5f, 0.45f};
-                        break;
-                    case MC::World::BiomeType::Plains:
-                        effect = {0.4f, 0.4f};
-                        break;
-                    case MC::World::BiomeType::Desert:
-                        effect = {0.6f, 0.35f};
-                        break;
-                    case MC::World::BiomeType::Ocean:
-                        effect = {0.0f, 0.0f};
-                        break;
-                }
-
-                total_effect = {
-                    total_effect.first + effect.first * (weight / total_weight),
-                    total_effect.second + effect.second * (weight / total_weight),
-                };
-            }
-
-            float height = Math::noise2d({
-                (chunk_x * Chunk::Width + x) * height_scale + height_offset,
-                (chunk_y * Chunk::Width + y) * height_scale + height_offset
-            }) * total_effect.first + total_effect.second;
-
-            heights(x, y) = height;
-        }
-    }
-
-    return heights;
-}
-
-Matrix<Chunk::Width, Chunk::Width, BiomeType> Generator::flat_biome_pass(
-    Matrix<Chunk::Width, Chunk::Width, Vector<BiomeType::Size>> biome_weights
-) {
-    Matrix<Chunk::Width, Chunk::Width, BiomeType>  biomes{};
-    for (int x = 0; x < Chunk::Width; x++) {
-        for (int y = 0; y < Chunk::Width; y++) {
-            auto weights = biome_weights(x, y);
-
-            std::pair<MC::World::BiomeType, float> max_biome{MC::World::BiomeType::Plains, 0.0f};
-            for (auto biome : MC::World::BiomeType::all()) {
-                auto weight = weights[biome];
-                if (weight > max_biome.second) {
-                    max_biome = {biome, weight};
+                if (value > 0.6f && value < 0.7f) {
+                    chunk.set(x, y, z, {BlockType::Stone});
                 }
             }
-
-            biomes(x, y) = max_biome.first;
         }
     }
 
-    return biomes;
+    return chunk;
 }
 
 }
\ No newline at end of file