diff --git a/include/Cubed/config.hpp b/include/Cubed/config.hpp index 66620a3..8ac1c29 100644 --- a/include/Cubed/config.hpp +++ b/include/Cubed/config.hpp @@ -1,6 +1,4 @@ #pragma once -constexpr int WORLD_SIZE_X = 32; -constexpr int WORLD_SIZE_Z = 32; constexpr int WORLD_SIZE_Y = 256; constexpr int MAX_BLOCK_NUM = 2; constexpr int MAX_UI_NUM = 1; diff --git a/include/Cubed/gameplay/world.hpp b/include/Cubed/gameplay/world.hpp index 1e7ac5f..6f1ef0b 100644 --- a/include/Cubed/gameplay/world.hpp +++ b/include/Cubed/gameplay/world.hpp @@ -9,10 +9,18 @@ class Player; class World { private: + bool need_gen_chunk = false; + BlockRenderData m_block_render_data; std::unordered_map m_chunks; std::unordered_map m_players; std::vector m_planes; + + std::pair chunk_pos(int world_x, int world_z); + void gen_chunks(); + + + public: World(); @@ -24,8 +32,10 @@ public: void init_world(); bool is_aabb_in_frustum(const glm::vec3& center, const glm::vec3& half_extents); bool is_block(const glm::ivec3& block_pos) const; - + + void need_gen(); void render(const glm::mat4& mvp_matrix); + void set_block(const glm::ivec3& pos, unsigned id); void update(float delta_time); diff --git a/src/app.cpp b/src/app.cpp index 900f5bd..7b08cb9 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -66,11 +66,17 @@ void App::key_callback(GLFWwindow* window, int key, int scancode, int action, in if (action == GLFW_PRESS) { glfwSetWindowShouldClose(window, GLFW_TRUE); } + break; case GLFW_KEY_F11: if (action == GLFW_PRESS) { app->m_window.toggle_fullscreen(); } break; + case GLFW_KEY_R: + if (action == GLFW_PRESS) { + app->m_world.need_gen(); + } + break; } diff --git a/src/gameplay/world.cpp b/src/gameplay/world.cpp index 94d2c24..766e05e 100644 --- a/src/gameplay/world.cpp +++ b/src/gameplay/world.cpp @@ -4,6 +4,9 @@ #include #include #include + +#include + World::World() { } @@ -20,19 +23,7 @@ bool World::can_move(const AABB& player_box) const{ } const BlockRenderData& World::get_block_render_data(int world_x, int world_y ,int world_z) { - int chunk_x, chunk_z; - if (world_x < 0) { - chunk_x = (world_x + 1) / CHUCK_SIZE - 1; - } - if (world_x >= 0) { - chunk_x = world_x / CHUCK_SIZE; - } - if (world_z < 0) { - chunk_z = (world_z + 1) / CHUCK_SIZE - 1; - } - if (world_z >= 0) { - chunk_z = world_z / CHUCK_SIZE; - } + auto [chunk_x, chunk_z] = chunk_pos(world_x, world_z); //Logger::info("Chunk PosX : {} Chuch PosZ : {}", chunk_x, chunk_z); auto it = m_chunks.find(ChunkPos{chunk_x, chunk_z}); CUBED_ASSERT_MSG(it != m_chunks.end(), "Chunk not find"); @@ -145,6 +136,84 @@ void World::render(const glm::mat4& mvp_matrix) { } } + +std::pair World::chunk_pos(int world_x, int world_z) { + int chunk_x, chunk_z; + if (world_x < 0) { + chunk_x = (world_x + 1) / CHUCK_SIZE - 1; + } + if (world_x >= 0) { + chunk_x = world_x / CHUCK_SIZE; + } + if (world_z < 0) { + chunk_z = (world_z + 1) / CHUCK_SIZE - 1; + } + if (world_z >= 0) { + chunk_z = world_z / CHUCK_SIZE; + } + return {chunk_x, chunk_z}; +} + +void World::gen_chunks() { + Logger::info("start gen chunks"); + const auto& player = get_player("TestPlayer"); + const auto& player_pos = player.get_player_pos(); + + int x = std::floor(player_pos.x); + int z = std::floor(player_pos.z); + auto [chunk_x, chunk_z] = chunk_pos(x, z); + std::unordered_set cur_chunks; + std::vector pre_gen_chunks; + cur_chunks.reserve(DISTANCE * DISTANCE); + int half = DISTANCE / 2; + for (int u = chunk_x - half; u <= chunk_x + half; ++u) { + for (int v = chunk_z - half; v <= chunk_z + half; ++v) { + cur_chunks.emplace(u, v); + } + } + CUBED_ASSERT_MSG(!cur_chunks.empty(), "cur chunks is empty!!"); + Logger::info("Cur Chunk pos gen finish, size {}", cur_chunks.size()); + + for (auto it = m_chunks.begin(); it != m_chunks.end(); ) { + if (cur_chunks.find(it->first) == cur_chunks.end()) { + it = m_chunks.erase(it); + } else { + ++it; + } + } + + for (auto pos: cur_chunks) { + auto it = m_chunks.find(pos); + if (it == m_chunks.end()) { + m_chunks.emplace(pos, Chunk(*this, pos)); + pre_gen_chunks.push_back(pos); + } + } + + Logger::info("start to init new chunk"); + + for (const auto& pos : pre_gen_chunks) { + auto it = m_chunks.find(pos); + CUBED_ASSERT_MSG(it != m_chunks.end(), "Chunk Don't find"); + //Logger::info("Init Chunk {} {}", pos.x, pos.z); + it->second.init_chunk(); + + } + + // After block gen fininshed + for (auto& chunk_map : m_chunks) { + auto& [chunk_pos, chunk] = chunk_map; + + chunk.gen_vertex_data(); + + } + Logger::info("gen chunks finish"); +} + +void World::need_gen() { + need_gen_chunk = true; +} + bool World::is_aabb_in_frustum(const glm::vec3& center, const glm::vec3& half_extents) { for (const auto& plane : m_planes) { // distance @@ -334,4 +403,8 @@ void World::update(float delta_time) { for (auto& player : m_players) { player.second.update(delta_time); } + if (need_gen_chunk) { + gen_chunks(); + need_gen_chunk = false; + } } \ No newline at end of file