summary refs log tree commit diff
path: root/src/World/World.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/World/World.cpp')
-rw-r--r--src/World/World.cpp67
1 files changed, 67 insertions, 0 deletions
diff --git a/src/World/World.cpp b/src/World/World.cpp
new file mode 100644
index 0000000..5a0d729
--- /dev/null
+++ b/src/World/World.cpp
@@ -0,0 +1,67 @@
+#include "World.hpp"
+
+namespace MC::World {
+
+std::vector<World::ChunkData> World::get_visible_chunks(Vector<3> position) {
+    auto visible_chunks = get_visible_chunk_indices(position);
+
+    auto difference = visible_chunks;
+    for (auto index : m_visible_chunks) {
+        difference.erase(index);
+    }
+
+    if (!difference.empty()) {
+        for (auto new_index: difference) {
+            auto& data = get_or_generate(new_index);
+            if (!data.mesh.has_value()) {
+                auto mesh = data.chunk->mesh();
+                data.mesh = GFX::Binder::load(mesh);
+            }
+        }
+        m_visible_chunks = visible_chunks;
+    }
+
+    std::vector<World::ChunkData> chunks{};
+    chunks.reserve(visible_chunks.size());
+    for (auto index : visible_chunks) {
+        chunks.push_back(get_or_generate(index));
+    }
+
+    return chunks;
+}
+
+std::unordered_set<ChunkIndex> World::get_visible_chunk_indices(Vector<3> position) const {
+    int64_t center_x = std::round(position.x() / CHUNK_WIDTH);
+    int64_t center_y = std::round(position.z() / CHUNK_HEIGHT);
+
+    auto upper_x_bound = center_x + m_view_distance_radius;
+    auto lower_x_bound = center_x - m_view_distance_radius;
+    auto upper_y_bound = center_y + m_view_distance_radius;
+    auto lower_y_bound = center_y - m_view_distance_radius;
+
+    std::unordered_set<ChunkIndex> indices{};
+    indices.reserve(m_view_distance_radius * m_view_distance_radius * 4);
+    for (int64_t x = lower_x_bound; x < upper_x_bound; x++) {
+        for (int64_t y = lower_y_bound; y < upper_y_bound; y++) {
+            indices.emplace(x, y);
+        }
+    }
+
+    return indices;
+}
+
+World::ChunkData& World::get_or_generate(ChunkIndex index) {
+    auto entry = m_chunks.find(index);
+    if (entry == m_chunks.end()) {
+        auto chunk = m_generator.generate(index.x, index.y);
+        ChunkData data{index, std::make_shared<Chunk>(chunk)};
+
+        m_chunks.insert({index, data});
+        return m_chunks.at(index);
+    }
+
+    return entry->second;
+}
+
+
+}
\ No newline at end of file