diff options
Diffstat (limited to 'src/World/World.cpp')
| -rw-r--r-- | src/World/World.cpp | 67 |
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 |
