diff --git a/CMakeLists.txt b/CMakeLists.txt index faa26af..0b7ab7d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -123,14 +123,14 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug") message(STATUS "Building with AddressSanitizer enabled for target: ${PROJECT_NAME}") target_compile_options(${PROJECT_NAME} PRIVATE - -fsanitize=address + #-fsanitize=address #-fsanitize=thread -fno-omit-frame-pointer -g ) target_link_options(${PROJECT_NAME} PRIVATE - -fsanitize=address + #-fsanitize=address #-fsanitize=thread ) diff --git a/include/Cubed/constants.hpp b/include/Cubed/constants.hpp index 14bc3fc..b091f9c 100644 --- a/include/Cubed/constants.hpp +++ b/include/Cubed/constants.hpp @@ -1,4 +1,6 @@ #pragma once +#include "Cubed/gameplay/chunk_pos.hpp" + #include namespace Cubed { @@ -26,6 +28,9 @@ static constexpr int SIZE_X = CHUCK_SIZE; static constexpr int SIZE_Y = WORLD_SIZE_Y; static constexpr int SIZE_Z = CHUCK_SIZE; +constexpr ChunkPos CHUNK_DIR[]{{1, 0}, {-1, 0}, {0, 1}, {0, -1}, + {1, 1}, {-1, 1}, {1, -1}, {-1, -1}}; + using HeightMapArray = std::array, CHUCK_SIZE>; } // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/gameplay/builders/biome_builder.hpp b/include/Cubed/gameplay/builders/biome_builder.hpp index 694572f..7df2309 100644 --- a/include/Cubed/gameplay/builders/biome_builder.hpp +++ b/include/Cubed/gameplay/builders/biome_builder.hpp @@ -12,5 +12,6 @@ public: protected: void build_bottom(); + void fill_water(); }; } // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/gameplay/chunk.hpp b/include/Cubed/gameplay/chunk.hpp index b3cd713..e6a9994 100644 --- a/include/Cubed/gameplay/chunk.hpp +++ b/include/Cubed/gameplay/chunk.hpp @@ -59,12 +59,13 @@ public: // Determine biome from temperature and humidity noise void gen_phase_one(); // Resolve biome adjacency conflicts with neighbor chunks - void gen_phase_two(const std::array& adj_chunks); + void gen_phase_two(const std::array& adj_chunks); // Generate heightmap using biome-specific noise void gen_phase_three(); // Blend heightmap with neighbors for smooth transitions void gen_phase_four( - const std::array, 4>& neighbor_heightmap); + const std::array, 8>& neighbor_heightmap, + const std::array& neighbor_biome); // Generate terrain blocks from heightmap and biome void gen_phase_five(); // Blend surface blocks at chunk borders with neighbors diff --git a/include/Cubed/gameplay/chunk_generator.hpp b/include/Cubed/gameplay/chunk_generator.hpp index c9f33c1..6562c45 100644 --- a/include/Cubed/gameplay/chunk_generator.hpp +++ b/include/Cubed/gameplay/chunk_generator.hpp @@ -25,12 +25,13 @@ public: void assign_chunk_biome(); // Adjust Biome void resolve_biome_adjacency_conflict( - const std::array& adj_chunks); + const std::array& adj_chunks); // Generate Heightmap void generate_heightmap(); // Adjust Height void blend_heightmap_boundaries( - const std::array, 4>& neighbor_heightmap); + const std::array, 8>& neighbor_heightmap, + const std::array& neighbor_biome); // Generate Block void generate_terrain_blocks(); // Adjust Block; @@ -39,10 +40,11 @@ public: neighbor_block); // Generate Structure void generate_vegetation(); - + BiomeType get_biome_at(float world_x, float world_z); Chunk& chunk(); Random& random(); bool neighbor_river() const; + const std::array& neighbor_biome() const; private: static inline std::atomic is_init{false}; @@ -50,11 +52,10 @@ private: static inline std::atomic is_seed_change{false}; Chunk& m_chunk; Random m_random; - std::array neighbor_biome{BiomeType::NONE, BiomeType::NONE, - BiomeType::NONE, BiomeType::NONE}; std::unique_ptr m_biome_builder{nullptr}; bool is_neighbor_river = false; - + bool is_cur_chunk_ins = false; + std::array m_neighbor_biome; void make_biome_builder(); }; diff --git a/include/Cubed/gameplay/world.hpp b/include/Cubed/gameplay/world.hpp index 5fef3e0..0434faa 100644 --- a/include/Cubed/gameplay/world.hpp +++ b/include/Cubed/gameplay/world.hpp @@ -28,9 +28,9 @@ private: using ConstChunkMap = std::unordered_map; using ChunkPosSet = std::unordered_set; - + using ChunkHashMap = std::unordered_map; glm::vec3 m_gen_player_pos{0.0f, 0.0f, 0.0f}; - std::unordered_map m_chunks; + ChunkHashMap m_chunks; std::unordered_map m_players; std::vector m_planes; diff --git a/src/gameplay/builders/biome_builder.cpp b/src/gameplay/builders/biome_builder.cpp index 3314569..b7ddf53 100644 --- a/src/gameplay/builders/biome_builder.cpp +++ b/src/gameplay/builders/biome_builder.cpp @@ -15,4 +15,27 @@ void BiomeBuilder::build_bottom() { } } } +void BiomeBuilder::fill_water() { + ChunkGenerator& chunk_generator = get_chunk_generator(); + Chunk& chunk = chunk_generator.chunk(); + auto& m_blocks = chunk.blocks(); + auto& neighbor = chunk_generator.neighbor_biome(); + auto& heightmap = chunk.heightmap(); + for (int i = 0; i < 8; i++) { + if (neighbor[i] == BiomeType::RIVER) { + for (int x = 0; x < SIZE_X; x++) { + for (int z = 0; z < SIZE_Z; z++) { + if (heightmap[x][z] >= SEA_LEVEL) { + continue; + } + int height = heightmap[x][z]; + for (int y = height; y < SEA_LEVEL; y++) { + m_blocks[Chunk::get_index(x, y, z)] = 7; + } + } + } + return; + } + } +} } // namespace Cubed \ No newline at end of file diff --git a/src/gameplay/builders/desert_builder.cpp b/src/gameplay/builders/desert_builder.cpp index bc1a511..4e06ff3 100644 --- a/src/gameplay/builders/desert_builder.cpp +++ b/src/gameplay/builders/desert_builder.cpp @@ -29,24 +29,7 @@ void DesertBuilder::build_blocks() { } } -void DesertBuilder::build_vegetation() { - auto& m_chunk = m_chunk_generator.chunk(); - auto& m_blocks = m_chunk.blocks(); - auto& m_heightmap = m_chunk.heightmap(); - if (m_chunk_generator.neighbor_river()) { - for (int x = 0; x < SIZE_X; x++) { - for (int z = 0; z < SIZE_Z; z++) { - int height = static_cast(m_heightmap[x][z]); - if (height >= SEA_LEVEL) { - continue; - } - for (int y = height + 1; y < SEA_LEVEL; y++) { - m_blocks[Chunk::get_index(x, y, z)] = 7; - } - } - } - } -} +void DesertBuilder::build_vegetation() { fill_water(); } ChunkGenerator& DesertBuilder::get_chunk_generator() { return m_chunk_generator; diff --git a/src/gameplay/builders/forest_builder.cpp b/src/gameplay/builders/forest_builder.cpp index 5cdf9a7..9d9b25c 100644 --- a/src/gameplay/builders/forest_builder.cpp +++ b/src/gameplay/builders/forest_builder.cpp @@ -49,20 +49,7 @@ void ForestBuilder::build_vegetation() { } } } - auto& m_blocks = m_chunk.blocks(); - if (m_chunk_generator.neighbor_river()) { - for (int x = 0; x < SIZE_X; x++) { - for (int z = 0; z < SIZE_Z; z++) { - int height = static_cast(m_heightmap[x][z]); - if (height >= SEA_LEVEL) { - continue; - } - for (int y = height + 1; y < SEA_LEVEL; y++) { - m_blocks[Chunk::get_index(x, y, z)] = 7; - } - } - } - } + fill_water(); } ChunkGenerator& ForestBuilder::get_chunk_generator() { diff --git a/src/gameplay/builders/mountain_builder.cpp b/src/gameplay/builders/mountain_builder.cpp index 68ba103..be7d358 100644 --- a/src/gameplay/builders/mountain_builder.cpp +++ b/src/gameplay/builders/mountain_builder.cpp @@ -37,24 +37,7 @@ void MountainBuilder::build_blocks() { } } -void MountainBuilder::build_vegetation() { - auto& m_chunk = m_chunk_generator.chunk(); - auto& m_blocks = m_chunk.blocks(); - auto& m_heightmap = m_chunk.heightmap(); - if (m_chunk_generator.neighbor_river()) { - for (int x = 0; x < SIZE_X; x++) { - for (int z = 0; z < SIZE_Z; z++) { - int height = static_cast(m_heightmap[x][z]); - if (height >= SEA_LEVEL) { - continue; - } - for (int y = height + 1; y < SEA_LEVEL; y++) { - m_blocks[Chunk::get_index(x, y, z)] = 7; - } - } - } - } -} +void MountainBuilder::build_vegetation() { fill_water(); } ChunkGenerator& MountainBuilder::get_chunk_generator() { return m_chunk_generator; diff --git a/src/gameplay/builders/plain_builder.cpp b/src/gameplay/builders/plain_builder.cpp index 147980d..52de883 100644 --- a/src/gameplay/builders/plain_builder.cpp +++ b/src/gameplay/builders/plain_builder.cpp @@ -29,24 +29,7 @@ void PlainBuilder::build_blocks() { } } -void PlainBuilder::build_vegetation() { - auto& m_chunk = m_chunk_generator.chunk(); - auto& m_blocks = m_chunk.blocks(); - auto& m_heightmap = m_chunk.heightmap(); - if (m_chunk_generator.neighbor_river()) { - for (int x = 0; x < SIZE_X; x++) { - for (int z = 0; z < SIZE_Z; z++) { - int height = static_cast(m_heightmap[x][z]); - if (height >= SEA_LEVEL) { - continue; - } - for (int y = height + 1; y < SEA_LEVEL; y++) { - m_blocks[Chunk::get_index(x, y, z)] = 7; - } - } - } - } -} +void PlainBuilder::build_vegetation() { fill_water(); } ChunkGenerator& PlainBuilder::get_chunk_generator() { return m_chunk_generator; diff --git a/src/gameplay/chunk.cpp b/src/gameplay/chunk.cpp index 8da69d9..58c9d20 100644 --- a/src/gameplay/chunk.cpp +++ b/src/gameplay/chunk.cpp @@ -215,7 +215,7 @@ void Chunk::gen_phase_one() { m_generator->assign_chunk_biome(); } -void Chunk::gen_phase_two(const std::array& adj_chunks) { +void Chunk::gen_phase_two(const std::array& adj_chunks) { if (!m_generator) { Logger::error("ChunkGenerator is Nullptr"); return; @@ -232,12 +232,13 @@ void Chunk::gen_phase_three() { } void Chunk::gen_phase_four( - const std::array, 4>& neighbor_heightmap) { + const std::array, 8>& neighbor_heightmap, + const std::array& neighbor_biome) { if (!m_generator) { Logger::error("ChunkGenerator is Nullptr"); return; } - m_generator->blend_heightmap_boundaries(neighbor_heightmap); + m_generator->blend_heightmap_boundaries(neighbor_heightmap, neighbor_biome); } void Chunk::gen_phase_five() { diff --git a/src/gameplay/chunk_generator.cpp b/src/gameplay/chunk_generator.cpp index c9bc822..e26c9e2 100644 --- a/src/gameplay/chunk_generator.cpp +++ b/src/gameplay/chunk_generator.cpp @@ -57,15 +57,14 @@ void ChunkGenerator::assign_chunk_biome() { } void ChunkGenerator::resolve_biome_adjacency_conflict( - const std::array& adj_chunks) { + const std::array& adj_chunks) { auto m_biome = m_chunk.biome(); - for (int i = 0; i < 4; i++) { + for (int i = 0; i < 8; i++) { auto& chunk = adj_chunks[i]; if (chunk == nullptr) { continue; } BiomeType biome = chunk->get_biome(); - neighbor_biome[i] = biome; if (biome == BiomeType::RIVER) { is_neighbor_river = true; } @@ -114,14 +113,16 @@ void ChunkGenerator::generate_heightmap() { } void ChunkGenerator::blend_heightmap_boundaries( - const std::array, 4>& neighbor_heightmap) { + const std::array, 8>& neighbor_heightmap, + const std::array& neighbor_biome) { auto& m_heightmap = m_chunk.heightmap(); auto m_biome = m_chunk.biome(); - + m_neighbor_biome = neighbor_biome; // --- Right neighbor neighbor[0]: (1, 0) --- for (int z = 0; z < SIZE_Z; z++) { if (neighbor_heightmap[0] != std::nullopt && neighbor_biome[0] != m_biome) { + is_cur_chunk_ins = true; int edge_x = CHUCK_SIZE - 1; int h = m_heightmap[edge_x][z]; int neighbor_h = (*neighbor_heightmap[0])[0][z]; @@ -144,6 +145,7 @@ void ChunkGenerator::blend_heightmap_boundaries( for (int z = 0; z < SIZE_Z; z++) { if (neighbor_heightmap[1] != std::nullopt && neighbor_biome[1] != m_biome) { + is_cur_chunk_ins = true; int edge_x = 0; int h = m_heightmap[edge_x][z]; int neighbor_h = (*neighbor_heightmap[1])[CHUCK_SIZE - 1][z]; @@ -167,6 +169,7 @@ void ChunkGenerator::blend_heightmap_boundaries( for (int x = 0; x < SIZE_X; x++) { if (neighbor_heightmap[2] != std::nullopt && neighbor_biome[2] != m_biome) { + is_cur_chunk_ins = true; int edge_z = CHUCK_SIZE - 1; int h = m_heightmap[x][edge_z]; int neighbor_h = (*neighbor_heightmap[2])[x][0]; @@ -190,17 +193,14 @@ void ChunkGenerator::blend_heightmap_boundaries( for (int x = 0; x < SIZE_X; x++) { if (neighbor_heightmap[3] != std::nullopt && neighbor_biome[3] != m_biome) { + is_cur_chunk_ins = true; int edge_z = 0; int h = m_heightmap[x][edge_z]; int neighbor_h = (*neighbor_heightmap[3])[x][CHUCK_SIZE - 1]; if (h <= neighbor_h) { continue; } - int delta_h = h - neighbor_h; - int step = delta_h / BLEND_RADIUS; - if (step < 1) { - continue; - } + const int DIR = (edge_z == 0) ? 1 : -1; for (int i = 0; i < BLEND_RADIUS; i++) { int z = edge_z + DIR * i; @@ -213,6 +213,141 @@ void ChunkGenerator::blend_heightmap_boundaries( } } } + if (is_cur_chunk_ins) { + return; + } + // --- Right-Front corner neighbor[4]: (1, 1) --- + if (neighbor_heightmap[4] != std::nullopt && neighbor_biome[4] != m_biome) { + for (int i = 0; i < BLEND_RADIUS; i++) { + for (int j = 0; j < BLEND_RADIUS; j++) { + int x = (CHUCK_SIZE - 1) - i; + int z = (CHUCK_SIZE - 1) - j; + int h = m_heightmap[x][z]; + + int h_right = (neighbor_heightmap[0] != std::nullopt) + ? (*neighbor_heightmap[0])[0][z] + : h; + + int h_front = (neighbor_heightmap[2] != std::nullopt) + ? (*neighbor_heightmap[2])[x][0] + : h; + + int h_corner = (*neighbor_heightmap[4])[0][0]; + + float tx = static_cast(i) / BLEND_RADIUS; + float tz = static_cast(j) / BLEND_RADIUS; + + float target_h = h_corner * (1 - tx) * (1 - tz) + + h_front * tx * (1 - tz) + + h_right * (1 - tx) * tz + h * tx * tz; + + if (h <= static_cast(std::round(target_h))) + continue; + + float t = static_cast(std::max(i, j)) / BLEND_RADIUS; + float smooth_t = t * t * t * (t * (t * 6.0f - 15.0f) + 10.0f); + m_heightmap[x][z] = static_cast( + std::round(target_h + (h - target_h) * smooth_t)); + } + } + } + + // --- Left-Front corner neighbor[5]: (-1, 1) --- + if (neighbor_heightmap[5] != std::nullopt && neighbor_biome[5] != m_biome) { + for (int i = 0; i < BLEND_RADIUS; i++) { + for (int j = 0; j < BLEND_RADIUS; j++) { + int x = i; + int z = (CHUCK_SIZE - 1) - j; + int h = m_heightmap[x][z]; + int h_left = (neighbor_heightmap[1] != std::nullopt) + ? (*neighbor_heightmap[1])[CHUCK_SIZE - 1][z] + : h; + int h_front = (neighbor_heightmap[2] != std::nullopt) + ? (*neighbor_heightmap[2])[x][0] + : h; + int h_corner = (*neighbor_heightmap[5])[CHUCK_SIZE - 1][0]; + + float tx = static_cast(i) / BLEND_RADIUS; + float tz = static_cast(j) / BLEND_RADIUS; + float target_h = h_corner * (1 - tx) * (1 - tz) + + h_front * tx * (1 - tz) + + h_left * (1 - tx) * tz + h * tx * tz; + + if (h <= static_cast(std::round(target_h))) + continue; + + float t = static_cast(std::max(i, j)) / BLEND_RADIUS; + float smooth_t = t * t * t * (t * (t * 6.0f - 15.0f) + 10.0f); + m_heightmap[x][z] = static_cast( + std::round(target_h + (h - target_h) * smooth_t)); + } + } + } + + // --- Right-Back corner neighbor[6]: (1, -1) --- + if (neighbor_heightmap[6] != std::nullopt && neighbor_biome[6] != m_biome) { + for (int i = 0; i < BLEND_RADIUS; i++) { + for (int j = 0; j < BLEND_RADIUS; j++) { + int x = (CHUCK_SIZE - 1) - i; + int z = j; + int h = m_heightmap[x][z]; + int h_right = (neighbor_heightmap[0] != std::nullopt) + ? (*neighbor_heightmap[0])[0][z] + : h; + int h_back = (neighbor_heightmap[3] != std::nullopt) + ? (*neighbor_heightmap[3])[x][CHUCK_SIZE - 1] + : h; + int h_corner = (*neighbor_heightmap[6])[0][CHUCK_SIZE - 1]; + + float tx = static_cast(i) / BLEND_RADIUS; + float tz = static_cast(j) / BLEND_RADIUS; + float target_h = h_corner * (1 - tx) * (1 - tz) + + h_back * tx * (1 - tz) + + h_right * (1 - tx) * tz + h * tx * tz; + + if (h <= static_cast(std::round(target_h))) + continue; + + float t = static_cast(std::max(i, j)) / BLEND_RADIUS; + float smooth_t = t * t * t * (t * (t * 6.0f - 15.0f) + 10.0f); + m_heightmap[x][z] = static_cast( + std::round(target_h + (h - target_h) * smooth_t)); + } + } + } + + // --- Left-Back corner neighbor[7]: (-1, -1) --- + if (neighbor_heightmap[7] != std::nullopt && neighbor_biome[7] != m_biome) { + for (int i = 0; i < BLEND_RADIUS; i++) { + for (int j = 0; j < BLEND_RADIUS; j++) { + int x = i; + int z = j; + int h = m_heightmap[x][z]; + int h_left = (neighbor_heightmap[1] != std::nullopt) + ? (*neighbor_heightmap[1])[CHUCK_SIZE - 1][z] + : h; + int h_back = (neighbor_heightmap[3] != std::nullopt) + ? (*neighbor_heightmap[3])[x][CHUCK_SIZE - 1] + : h; + int h_corner = + (*neighbor_heightmap[7])[CHUCK_SIZE - 1][CHUCK_SIZE - 1]; + + float tx = static_cast(i) / BLEND_RADIUS; + float tz = static_cast(j) / BLEND_RADIUS; + float target_h = h_corner * (1 - tx) * (1 - tz) + + h_back * tx * (1 - tz) + + h_left * (1 - tx) * tz + h * tx * tz; + + if (h <= static_cast(std::round(target_h))) + continue; + + float t = static_cast(std::max(i, j)) / BLEND_RADIUS; + float smooth_t = t * t * t * (t * (t * 6.0f - 15.0f) + 10.0f); + m_heightmap[x][z] = static_cast( + std::round(target_h + (h - target_h) * smooth_t)); + } + } + } } void ChunkGenerator::generate_terrain_blocks() { @@ -388,5 +523,7 @@ Chunk& ChunkGenerator::chunk() { return m_chunk; } Random& ChunkGenerator::random() { return m_random; } bool ChunkGenerator::neighbor_river() const { return is_neighbor_river; } - +const std::array& ChunkGenerator::neighbor_biome() const { + return m_neighbor_biome; +} } // namespace Cubed \ No newline at end of file diff --git a/src/gameplay/world.cpp b/src/gameplay/world.cpp index 62a8ecc..01a18ec 100644 --- a/src/gameplay/world.cpp +++ b/src/gameplay/world.cpp @@ -11,8 +11,6 @@ namespace Cubed { -static constexpr ChunkPos CHUNK_DIR[]{{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; - struct ChunkRenderData { std::array*, 4> neighbor_block; Chunk* chunk; @@ -67,18 +65,8 @@ Player& World::get_player(const std::string& name) { } void World::init_world() { - m_chunks.reserve(MAX_DISTANCE * MAX_DISTANCE); + m_chunks.reserve(MAX_DISTANCE * MAX_DISTANCE * 4); auto t1 = std::chrono::system_clock::now(); - for (int s = 0; s < PRE_LOAD_DISTANCE; s++) { - for (int t = 0; t < PRE_LOAD_DISTANCE; t++) { - int ns = s - PRE_LOAD_DISTANCE / 2; - int nt = t - PRE_LOAD_DISTANCE / 2; - - ChunkPos pos{ns, nt}; - - m_chunks.emplace(pos, Chunk(*this, pos)); - } - } Logger::info("Max Support Thread is {}", std::thread::hardware_concurrency()); @@ -138,59 +126,172 @@ pending_gen_data.end(), [](ChunkRenderData& data){ if(!data.chunk) { return ; */ void World::init_chunks() { - for (auto& [pos, chunks] : m_chunks) { - chunks.gen_phase_one(); - } - std::array neighbor_chunks; - for (auto& [pos, chunks] : m_chunks) { - for (int i = 0; i < 4; i++) { - auto neighbor_pos = pos + CHUNK_DIR[i]; - auto it = m_chunks.find(neighbor_pos); - if (it == m_chunks.end()) { - neighbor_chunks[i] = nullptr; - continue; + + for (int i = 1; i <= PRE_LOAD_DISTANCE; i++) { + int dis_x = 0 + i; + int dis_z = 0 + i; + for (int x = 0; x < dis_x; x++) { + for (int z = 0; z < dis_z; z++) { + int nx = x - dis_x / 2; + int nz = z - dis_z / 2; + ChunkPos pos{nx, nz}; + auto it = m_chunks.find(pos); + if (it == m_chunks.end()) { + m_chunks.emplace(pos, Chunk(*this, pos)); + } } - neighbor_chunks[i] = &it->second; } - chunks.gen_phase_two(neighbor_chunks); + ChunkHashMap temp_neighbor; + for (int x = 0; x < dis_x + 2; x++) { + for (int z = 0; z < dis_z + 2; z++) { + int nx = x - (dis_x + 2) / 2; + int nz = z - (dis_z + 2) / 2; + ChunkPos pos{nx, nz}; + auto it = m_chunks.find(pos); + if (it == m_chunks.end()) { + auto it = temp_neighbor.find(pos); + if (it == temp_neighbor.end()) { + temp_neighbor.emplace(pos, Chunk(*this, pos)); + } + } + } + } + for (auto& [pos, chunks] : m_chunks) { + chunks.gen_phase_one(); + } + for (auto& [pos, chunks] : temp_neighbor) { + chunks.gen_phase_one(); + } + + std::array neighbor_chunks; + for (auto& [pos, chunks] : m_chunks) { + for (int i = 0; i < 8; i++) { + auto neighbor_pos = pos + CHUNK_DIR[i]; + auto it = m_chunks.find(neighbor_pos); + if (it == m_chunks.end()) { + auto it = temp_neighbor.find(neighbor_pos); + if (it == temp_neighbor.end()) { + neighbor_chunks[i] = nullptr; + ASSERT_MSG(false, "Neighbor Chunk is nullptr"); + } else { + neighbor_chunks[i] = &it->second; + } + continue; + } + neighbor_chunks[i] = &it->second; + } + chunks.gen_phase_two(neighbor_chunks); + } + for (auto& [pos, chunks] : temp_neighbor) { + for (int i = 0; i < 4; i++) { + auto neighbor_pos = pos + CHUNK_DIR[i]; + auto it = m_chunks.find(neighbor_pos); + if (it == m_chunks.end()) { + auto it = temp_neighbor.find(neighbor_pos); + if (it == temp_neighbor.end()) { + neighbor_chunks[i] = nullptr; + } else { + neighbor_chunks[i] = &it->second; + } + continue; + } + neighbor_chunks[i] = &it->second; + } + chunks.gen_phase_two(neighbor_chunks); + } + for (auto& [pos, chunks] : m_chunks) { + chunks.gen_phase_three(); + } + for (auto& [pos, chunks] : temp_neighbor) { + chunks.gen_phase_three(); + } + + for (int i = 0; i < 4; i++) { + for (auto& [pos, chunks] : m_chunks) { + std::array, 8> + neighbor_chunk_heightmap; + std::array neighbor_biome; + for (int i = 0; i < 8; i++) { + + auto neighbor_pos = pos + CHUNK_DIR[i]; + auto it = m_chunks.find(neighbor_pos); + if (it == m_chunks.end()) { + auto it = temp_neighbor.find(neighbor_pos); + if (it == temp_neighbor.end()) { + neighbor_chunk_heightmap[i] = std::nullopt; + neighbor_biome[i] = BiomeType::NONE; + ASSERT_MSG(false, "Neighbor Chunk is nullptr"); + } else { + neighbor_chunk_heightmap[i] = + it->second.get_heightmap(); + neighbor_biome[i] = it->second.biome(); + } + + continue; + } + neighbor_chunk_heightmap[i] = it->second.get_heightmap(); + neighbor_biome[i] = it->second.biome(); + } + chunks.gen_phase_four(neighbor_chunk_heightmap, neighbor_biome); + } + for (auto& [pos, chunks] : temp_neighbor) { + std::array, 8> + neighbor_chunk_heightmap; + std::array neighbor_biome; + for (int i = 0; i < 4; i++) { + auto neighbor_pos = pos + CHUNK_DIR[i]; + auto it = m_chunks.find(neighbor_pos); + if (it == m_chunks.end()) { + auto it = temp_neighbor.find(neighbor_pos); + if (it == temp_neighbor.end()) { + neighbor_chunk_heightmap[i] = std::nullopt; + neighbor_biome[i] = BiomeType::NONE; + } else { + neighbor_chunk_heightmap[i] = + it->second.get_heightmap(); + neighbor_biome[i] = it->second.biome(); + } + + continue; + } + neighbor_chunk_heightmap[i] = it->second.get_heightmap(); + neighbor_biome[i] = it->second.biome(); + } + chunks.gen_phase_four(neighbor_chunk_heightmap, neighbor_biome); + } + } + + for (auto& [pos, chunks] : m_chunks) { + chunks.gen_phase_five(); + } + for (auto& [pos, chunks] : temp_neighbor) { + chunks.gen_phase_five(); + } + std::array>, 4> neighbor_block; + for (auto& [pos, chunks] : m_chunks) { + for (int i = 0; i < 4; i++) { + auto neighbor_pos = pos + CHUNK_DIR[i]; + auto it = m_chunks.find(neighbor_pos); + if (it == m_chunks.end()) { + auto it = temp_neighbor.find(neighbor_pos); + if (it == temp_neighbor.end()) { + neighbor_block[i] = std::nullopt; + ASSERT_MSG(false, "Neighbor Chunk is nullptr"); + } else { + neighbor_block[i] = it->second.get_chunk_blocks(); + } + + continue; + } + neighbor_block[i] = it->second.get_chunk_blocks(); + } + chunks.gen_phase_six(neighbor_block); + } + for (auto& [pos, chunks] : m_chunks) { + chunks.gen_phase_seven(); + } } - for (auto& [pos, chunks] : m_chunks) { - chunks.gen_phase_three(); - } - std::array, 4> neighbor_chunk_heightmap; - for (auto& [pos, chunks] : m_chunks) { - for (int i = 0; i < 4; i++) { - auto neighbor_pos = pos + CHUNK_DIR[i]; - auto it = m_chunks.find(neighbor_pos); - if (it == m_chunks.end()) { - neighbor_chunk_heightmap[i] = std::nullopt; - continue; - } - neighbor_chunk_heightmap[i] = it->second.get_heightmap(); - } - chunks.gen_phase_four(neighbor_chunk_heightmap); - } - - for (auto& [pos, chunks] : m_chunks) { - chunks.gen_phase_five(); - } - std::array>, 4> neighbor_block; - for (auto& [pos, chunks] : m_chunks) { - for (int i = 0; i < 4; i++) { - auto neighbor_pos = pos + CHUNK_DIR[i]; - auto it = m_chunks.find(neighbor_pos); - if (it == m_chunks.end()) { - neighbor_block[i] = std::nullopt; - continue; - } - neighbor_block[i] = it->second.get_chunk_blocks(); - } - chunks.gen_phase_six(neighbor_block); - } - for (auto& [pos, chunks] : m_chunks) { - chunks.gen_phase_seven(); - } std::atomic sync{0}; sync.store(1, std::memory_order_release); sync.load(std::memory_order_acquire); @@ -266,7 +367,7 @@ ChunkPos World::chunk_pos(int world_x, int world_z) { } return {chunk_x, chunk_z}; } - +/* void World::gen_chunks_internal() { m_chunk_gen_fraction = 0.0f; ChunkPosSet required_chunks; @@ -396,7 +497,7 @@ void World::gen_chunks_internal() { } m_chunk_gen_fraction = 1.0f; } - +*/ void World::sync_player_pos(glm::vec3& player_pos) { std::lock_guard lk(m_gen_player_pos_mutex); player_pos = m_gen_player_pos; @@ -488,7 +589,7 @@ void World::start_gen_thread() { m_need_gen_chunk = false; lk.unlock(); - gen_chunks_internal(); + // gen_chunks_internal(); } }); }