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, 46 insertions, 21 deletions
diff --git a/src/World/World.cpp b/src/World/World.cpp
index 03ce60e..af70766 100644
--- a/src/World/World.cpp
+++ b/src/World/World.cpp
@@ -1,8 +1,9 @@
 #include "World.hpp"
+#include "ChunkMeshing.hpp"
 
 namespace MC::World {
 
-std::vector<World::ChunkData> World::get_visible_chunks(Vector<3> position) {
+std::vector<World::ChunkData*> World::get_visible_chunks(Vector<3> position) {
     auto finished_chunks = load_finished_chunks_from_queue();
     auto visible_chunks = get_visible_chunk_indices(position);
 
@@ -19,19 +20,22 @@ std::vector<World::ChunkData> World::get_visible_chunks(Vector<3> position) {
         m_visible_chunks = visible_chunks;
     }
 
-    std::vector<ChunkData> chunks{};
+    std::vector<ChunkData*> chunks{};
     chunks.reserve(visible_chunks.size());
     for (auto index : visible_chunks) {
         auto& data = get(index);
+        if (data.status == ChunkStatus::NeedsMesh) {
+            try_to_create_mesh_for_chunk(data);
+        }
         if (data.status == ChunkStatus::Done) {
-            chunks.push_back(data);
+            chunks.push_back(&data);
         }
     }
 
     return chunks;
 }
 
-Chunk* World::get_chunk_for_positon(Vector<3> position) {
+Chunk* World::get_chunk_for_position(Vector<3> position) {
     int32_t x = std::round(position.x() / Chunk::Width);
     int32_t y = std::round(position.z() / Chunk::Width);
     auto& data = get({x, y});
@@ -44,17 +48,9 @@ Chunk* World::get_chunk_for_positon(Vector<3> position) {
 void World::process_chunk_visibility_updates(std::unordered_set<ChunkIndex>& new_chunks, Vector<3> player) {
     for (auto new_index: new_chunks) {
         auto& data = get(new_index);
-        switch (data.status) {
-            case ChunkStatus::Empty:
-                request_generation(new_index, player.distance(new_index.middle()));
-                data.status = ChunkStatus::WaitingForGeneration;
-                break;
-            case ChunkStatus::Done:
-                data.mesh = GFX::Binder::load(data.chunk.value().mesh());
-                data.status = ChunkStatus::Done;
-                break;
-            case ChunkStatus::WaitingForGeneration:
-                break;
+        if (data.status == ChunkStatus::Empty) {
+            request_generation(new_index, player.distance(new_index.middle()));
+            data.status = ChunkStatus::WaitingForGeneration;
         }
     }
 }
@@ -79,11 +75,9 @@ std::unordered_set<ChunkIndex> World::get_visible_chunk_indices(Vector<3> positi
 std::unordered_set<ChunkIndex> World::load_finished_chunks_from_queue() {
     std::unordered_set<ChunkIndex> indices;
     auto results = m_queue.done();
-    for (auto& result : results) {
-        auto& data = get(result.id);
-        data.chunk = {result.res};
-        data.status = ChunkStatus::Done;
-        indices.insert(result.id);
+    for (auto& [id, res] : results) {
+        get(id) = {id, ChunkStatus::NeedsMesh, {res}};
+        indices.insert(id);
     }
 
     return indices;
@@ -100,11 +94,42 @@ World::ChunkData& World::get(ChunkIndex index) {
     if (entry == m_chunks.end()) {
         ChunkData data{index, ChunkStatus::Empty};
 
-        m_chunks.insert({index, data});
+        m_chunks.insert({index, std::move(data)});
         return m_chunks.at(index);
     }
 
     return entry->second;
 }
 
+void World::try_to_create_mesh_for_chunk(World::ChunkData& data) {
+//    Chunk empty{0, 0};
+//    data.mesh_data = ChunkMeshing::create_mesh_for_chunk(data.chunk.value(), {
+//            empty, empty, empty, empty,
+//    });
+//    data.mesh = GFX::Binder::load(data.mesh_data.value());
+//    data.status = ChunkStatus::Done;
+
+    auto index = data.index;
+
+    auto north = get({index.x, index.y - 1});
+    auto east = get({index.x + 1, index.y});
+    auto south = get({index.x, index.y + 1});
+    auto west = get({index.x - 1, index.y});
+
+    auto no_terrain = [](ChunkData& data){
+        return !data.chunk.has_value();
+    };
+
+    if (no_terrain(north) || no_terrain(east) || no_terrain(south) || no_terrain(west)) {
+        return;
+    }
+
+    data.mesh_data = ChunkMeshing::create_mesh_for_chunk(
+        data.chunk.value(),
+        {north.chunk.value(), east.chunk.value(), south.chunk.value(), west.chunk.value()}
+    );
+    data.mesh = GFX::Binder::load(data.mesh_data.value());
+    data.status = ChunkStatus::Done;
+}
+
 }
\ No newline at end of file