chore: add clang-format and pre-commit configuration

This commit is contained in:
2026-04-28 09:22:55 +08:00
parent dc3be5a4bc
commit 611a795481
62 changed files with 2166 additions and 2134 deletions

View File

@@ -1,29 +1,24 @@
#include <Cubed/gameplay/world.hpp>
#include "Cubed/gameplay/world.hpp"
#include <Cubed/debug_collector.hpp>
#include <Cubed/gameplay/player.hpp>
#include <Cubed/map_table.hpp>
#include <Cubed/tools/cubed_assert.hpp>
#include <Cubed/tools/cubed_hash.hpp>
#include <Cubed/tools/math_tools.hpp>
#include <Cubed/tools/perlin_noise.hpp>
#include "Cubed/config.hpp"
#include "Cubed/debug_collector.hpp"
#include "Cubed/gameplay/player.hpp"
#include "Cubed/tools/cubed_assert.hpp"
#include "Cubed/tools/cubed_hash.hpp"
#include "Cubed/tools/math_tools.hpp"
#include <execution>
namespace Cubed {
static constexpr ChunkPos CHUNK_DIR[] {
{1, 0}, {-1, 0}, {0, 1}, {0, -1}
};
static constexpr ChunkPos CHUNK_DIR[]{{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
struct ChunkRenderData {
std::array<const std::vector<uint8_t>*, 4> neighbor_block;
Chunk* chunk;
};
World::World() {
}
World::World() {}
World::~World() {
stop_gen_thread();
@@ -37,12 +32,10 @@ World::~World() {
}
}
bool World::can_move(const AABB& player_box) const{
bool World::can_move(const AABB& player_box) const { return true; }
return true;
}
const std::optional<LookBlock>& World::get_look_block_pos(const std::string& name) const{
const std::optional<LookBlock>&
World::get_look_block_pos(const std::string& name) const {
static std::optional<LookBlock> null_look_block = std::nullopt;
auto it = m_players.find(HASH::str(name));
if (it == m_players.end()) {
@@ -52,7 +45,6 @@ const std::optional<LookBlock>& World::get_look_block_pos(const std::string& nam
}
return it->second.get_look_block_pos();
}
const Chunk* World::get_chunk(const ChunkPos& pos) const {
@@ -64,13 +56,13 @@ const Chunk* World::get_chunk(const ChunkPos& pos) const {
return &it->second;
}
Player& World::get_player(const std::string& name){
Player& World::get_player(const std::string& name) {
auto it = m_players.find(HASH::str(name));
if (it == m_players.end()) {
Logger::error("Can't find player {}", name);
ASSERT(0);
}
return it->second;
}
@@ -84,11 +76,12 @@ void World::init_world() {
ChunkPos pos{ns, nt};
m_chunks.emplace(pos, Chunk(*this, pos));
m_chunks.emplace(pos, Chunk(*this, pos));
}
}
Logger::info("Max Support Thread is {}", std::thread::hardware_concurrency());
Logger::info("Max Support Thread is {}",
std::thread::hardware_concurrency());
init_chunks();
auto t2 = std::chrono::system_clock::now();
auto d = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1);
@@ -108,20 +101,20 @@ void World::init_chunks() {
chunk_ptrs.push_back(&chunk);
}
std::for_each(std::execution::par, chunk_ptrs.begin(), chunk_ptrs.end(), [](auto& chunk){
chunk->init_chunk();
std::for_each(std::execution::par, chunk_ptrs.begin(), chunk_ptrs.end(),
[](auto& chunk){ chunk->init_chunk();
});
std::atomic<int> sync{0};
sync.store(1, std::memory_order_release);
sync.load(std::memory_order_acquire);
std::vector<ChunkRenderData> pending_gen_data;
pending_gen_data.reserve(m_chunks.size());
for (auto& [pos, chunk] : m_chunks) {
ChunkRenderData data;
data.chunk = &chunk;
for (int i = 0; i < 4; i++) {
for (int i = 0; i < 4; i++) {
auto it = m_chunks.find(pos + CHUNK_DIR[i]);
if (it != m_chunks.end()) {
data.neighbor_block[i] = &(it->second.get_chunk_blocks());
@@ -131,16 +124,15 @@ void World::init_chunks() {
}
pending_gen_data.emplace_back(std::move(data));
}
std::for_each(std::execution::par, pending_gen_data.begin(), pending_gen_data.end(), [](ChunkRenderData& data){
if(!data.chunk) {
return ;
std::for_each(std::execution::par, pending_gen_data.begin(),
pending_gen_data.end(), [](ChunkRenderData& data){ if(!data.chunk) { return ;
}
data.chunk->gen_vertex_data(data.neighbor_block);
});
for (auto& chunk_map : m_chunks) {
auto& [chunk_pos, chunk] = chunk_map;
chunk.upload_to_gpu();
}
}
*/
@@ -159,7 +151,6 @@ void World::init_chunks() {
continue;
}
neighbor_chunks[i] = &it->second;
}
chunks.gen_phase_two(neighbor_chunks);
}
@@ -177,13 +168,12 @@ void World::init_chunks() {
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();
chunks.gen_phase_five();
}
std::array<std::optional<std::vector<uint8_t>>, 4> neighbor_block;
for (auto& [pos, chunks] : m_chunks) {
@@ -195,23 +185,22 @@ void World::init_chunks() {
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();
chunks.gen_phase_seven();
}
std::atomic<int> sync{0};
sync.store(1, std::memory_order_release);
sync.load(std::memory_order_acquire);
std::vector<ChunkRenderData> pending_gen_data;
pending_gen_data.reserve(m_chunks.size());
for (auto& [pos, chunk] : m_chunks) {
ChunkRenderData data;
data.chunk = &chunk;
for (int i = 0; i < 4; i++) {
for (int i = 0; i < 4; i++) {
auto it = m_chunks.find(pos + CHUNK_DIR[i]);
if (it != m_chunks.end()) {
data.neighbor_block[i] = &(it->second.get_chunk_blocks());
@@ -221,30 +210,32 @@ void World::init_chunks() {
}
pending_gen_data.emplace_back(std::move(data));
}
std::for_each(std::execution::par, pending_gen_data.begin(), pending_gen_data.end(), [](ChunkRenderData& data){
if(!data.chunk) {
return ;
}
data.chunk->gen_vertex_data(data.neighbor_block);
});
std::for_each(std::execution::par, pending_gen_data.begin(),
pending_gen_data.end(), [](ChunkRenderData& data) {
if (!data.chunk) {
return;
}
data.chunk->gen_vertex_data(data.neighbor_block);
});
for (auto& chunk_map : m_chunks) {
auto& [chunk_pos, chunk] = chunk_map;
chunk.upload_to_gpu();
}
}
void World::render(const glm::mat4& mvp_matrix) {
Math::extract_frustum_planes(mvp_matrix, m_planes);
int rendered_sum = 0;
for (const auto& snapshot : m_render_snapshots) {
if (is_aabb_in_frustum(snapshot.center, snapshot.half_extents)) {
glBindBuffer(GL_ARRAY_BUFFER, snapshot.vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, s));
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, layer));
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
(void*)0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex),
(void*)offsetof(Vertex, s));
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex),
(void*)offsetof(Vertex, layer));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
@@ -253,13 +244,10 @@ void World::render(const glm::mat4& mvp_matrix) {
glDrawArrays(GL_TRIANGLES, 0, snapshot.vertex_count);
glBindBuffer(GL_ARRAY_BUFFER, 0);
rendered_sum++;
}
}
DebugCollector::get().report("rendered_chunk", "Rendered Chunk: " + std::to_string(rendered_sum));
DebugCollector::get().report(
"rendered_chunk", "Rendered Chunk: " + std::to_string(rendered_sum));
}
ChunkPos World::chunk_pos(int world_x, int world_z) {
@@ -285,10 +273,10 @@ void World::gen_chunks_internal() {
compute_required_chunks(required_chunks);
ASSERT_MSG(!required_chunks.empty(), "required chunks is empty!!");
std::vector<ChunkPos> need_gen_chunks_pos;
sync_and_collect_missing_chunks(need_gen_chunks_pos, required_chunks);
Logger::info("New Gen Chunks Sum: {}", need_gen_chunks_pos.size());
if (need_gen_chunks_pos.empty()) {
m_could_gen = true;
@@ -300,12 +288,13 @@ void World::gen_chunks_internal() {
for (auto& pos : need_gen_chunks_pos) {
new_chunks.push_back({pos, Chunk(*this, pos)});
}
ConstChunkMap new_chunks_neighbor;
// affected neighbor
ChunkPtrUpdateList affected_neighbor;
build_neighbor_context_for_new_chunks(new_chunks_neighbor, affected_neighbor,new_chunks);
build_neighbor_context_for_new_chunks(new_chunks_neighbor,
affected_neighbor, new_chunks);
std::array<const std::vector<uint8_t>*, 4> neighbor_block;
// build new chunk, but the neighbor in m_chunks also need to re-build
@@ -323,7 +312,6 @@ void World::gen_chunks_internal() {
continue;
}
neighbor_chunks[i] = it->second;
}
chunks.gen_phase_two(neighbor_chunks);
}
@@ -335,7 +323,7 @@ void World::gen_chunks_internal() {
std::array<std::optional<HeightMapArray>, 4> neighbor_chunk_heightmap;
for (auto& [pos, chunks] : new_chunks) {
{
//std::lock_guard lk(m_chunks_mutex);
// std::lock_guard lk(m_chunks_mutex);
for (int i = 0; i < 4; i++) {
auto neighbor_pos = pos + CHUNK_DIR[i];
auto it = new_chunks_neighbor.find(neighbor_pos);
@@ -355,7 +343,7 @@ void World::gen_chunks_internal() {
std::array<std::optional<std::vector<uint8_t>>, 4> neighbor_blocks_data;
for (auto& [pos, chunks] : new_chunks) {
{
//std::lock_guard lk(m_chunks_mutex);
// std::lock_guard lk(m_chunks_mutex);
for (int i = 0; i < 4; i++) {
auto neighbor_pos = pos + CHUNK_DIR[i];
auto it = new_chunks_neighbor.find(neighbor_pos);
@@ -384,7 +372,8 @@ void World::gen_chunks_internal() {
chunk.gen_vertex_data(neighbor_block);
}
m_chunk_gen_fraction = 0.7f;
build_neighbor_context_for_affected_neighbors(affected_neighbor, new_chunks_neighbor);
build_neighbor_context_for_affected_neighbors(affected_neighbor,
new_chunks_neighbor);
m_chunk_gen_fraction = 0.8f;
for (auto& [pos, chunk] : affected_neighbor) {
for (int i = 0; i < 4; i++) {
@@ -397,14 +386,13 @@ void World::gen_chunks_internal() {
}
chunk->gen_vertex_data(neighbor_block);
chunk->need_upload();
}
}
m_chunk_gen_fraction = 0.9f;
{
std::lock_guard lk(m_new_chunk_queue_mutex);
for (auto& x : new_chunks) {
m_new_chunk_queue.emplace_back(std::move(x));
}
}
m_chunk_gen_fraction = 1.0f;
}
@@ -417,11 +405,10 @@ void World::sync_player_pos(glm::vec3& player_pos) {
void World::compute_required_chunks(ChunkPosSet& required_chunks) {
glm::vec3 player_pos;
sync_player_pos(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);
required_chunks.reserve(m_rendering_distance * m_rendering_distance);
int half = m_rendering_distance / 2;
@@ -432,17 +419,19 @@ void World::compute_required_chunks(ChunkPosSet& required_chunks) {
}
}
void World::sync_and_collect_missing_chunks(std::vector<ChunkPos>& need_gen_chunks_pos, const ChunkPosSet& required_chunks) {
void World::sync_and_collect_missing_chunks(
std::vector<ChunkPos>& need_gen_chunks_pos,
const ChunkPosSet& required_chunks) {
std::lock_guard lk(m_chunks_mutex);
for (auto it = m_chunks.begin(); it != m_chunks.end(); ) {
for (auto it = m_chunks.begin(); it != m_chunks.end();) {
if (required_chunks.find(it->first) == required_chunks.end()) {
it = m_chunks.erase(it);
} else {
++it;
}
}
for (auto pos: required_chunks) {
for (auto pos : required_chunks) {
auto it = m_chunks.find(pos);
if (it == m_chunks.end()) {
need_gen_chunks_pos.push_back(pos);
@@ -450,7 +439,9 @@ void World::sync_and_collect_missing_chunks(std::vector<ChunkPos>& need_gen_chun
}
}
void World::build_neighbor_context_for_new_chunks(ConstChunkMap& new_chunks_neighbor, ChunkPtrUpdateList& affected_neighbor,const ChunkUpdateList& new_chunks) {
void World::build_neighbor_context_for_new_chunks(
ConstChunkMap& new_chunks_neighbor, ChunkPtrUpdateList& affected_neighbor,
const ChunkUpdateList& new_chunks) {
{
std::lock_guard lk(m_chunks_mutex);
for (auto& [pos, chunk] : new_chunks) {
@@ -468,7 +459,8 @@ void World::build_neighbor_context_for_new_chunks(ConstChunkMap& new_chunks_neig
}
}
void World::build_neighbor_context_for_affected_neighbors(ChunkPtrUpdateList& affected_neighbor, ConstChunkMap& new_chunks_neighbor) {
void World::build_neighbor_context_for_affected_neighbors(
ChunkPtrUpdateList& affected_neighbor, ConstChunkMap& new_chunks_neighbor) {
std::lock_guard lk(m_chunks_mutex);
for (auto& [pos, chunk] : affected_neighbor) {
for (auto& dir : CHUNK_DIR) {
@@ -483,11 +475,11 @@ void World::build_neighbor_context_for_affected_neighbors(ChunkPtrUpdateList& af
void World::start_gen_thread() {
m_gen_running = true;
Logger::info("Gen Thread Started");
m_gen_thread = std::thread([this](){
m_gen_thread = std::thread([this]() {
while (m_gen_running) {
std::unique_lock<std::mutex> lk(m_gen_signal_mutex);
m_gen_cv.wait(lk, [this](){
m_gen_cv.wait(lk, [this]() {
return m_need_gen_chunk.load() || !m_gen_running;
});
if (!m_gen_running) {
@@ -520,12 +512,13 @@ void World::need_gen() {
std::lock_guard lk(m_gen_player_pos_mutex);
m_gen_player_pos = get_player("TestPlayer").get_player_pos();
}
m_need_gen_chunk = true;
m_gen_cv.notify_one();
}
bool World::is_aabb_in_frustum(const glm::vec3& center, const glm::vec3& half_extents) {
bool World::is_aabb_in_frustum(const glm::vec3& center,
const glm::vec3& half_extents) {
for (const auto& plane : m_planes) {
// distance
float d = glm::dot(glm::vec3(plane), center) + plane.w;
@@ -553,14 +546,14 @@ int World::get_block(const glm::ivec3& block_pos) const {
y = block_pos.y;
x = block_pos.x - chunk_x * CHUCK_SIZE;
z = block_pos.z - chunk_z * CHUCK_SIZE;
if (x < 0 || y < 0 || z < 0 || x >= CHUCK_SIZE || y >= WORLD_SIZE_Y || z >= CHUCK_SIZE) {
if (x < 0 || y < 0 || z < 0 || x >= CHUCK_SIZE || y >= WORLD_SIZE_Y ||
z >= CHUCK_SIZE) {
return 0;
}
return chunk_blocks[Chunk::get_index(x, y, z)];
}
bool World::is_block(const glm::ivec3& block_pos) const{
bool World::is_block(const glm::ivec3& block_pos) const {
auto [chunk_x, chunk_z] = chunk_pos(block_pos.x, block_pos.z);
std::lock_guard lk(m_chunks_mutex);
auto it = m_chunks.find(ChunkPos{chunk_x, chunk_z});
@@ -573,7 +566,8 @@ bool World::is_block(const glm::ivec3& block_pos) const{
y = block_pos.y;
x = block_pos.x - chunk_x * CHUCK_SIZE;
z = block_pos.z - chunk_z * CHUCK_SIZE;
if (x < 0 || y < 0 || z < 0 || x >= CHUCK_SIZE || y >= WORLD_SIZE_Y || z >= CHUCK_SIZE) {
if (x < 0 || y < 0 || z < 0 || x >= CHUCK_SIZE || y >= WORLD_SIZE_Y ||
z >= CHUCK_SIZE) {
return false;
}
auto id = chunk_blocks[Chunk::get_index(x, y, z)];
@@ -596,22 +590,22 @@ void World::set_block(const glm::ivec3& block_pos, unsigned id) {
auto it = m_chunks.find(ChunkPos{chunk_x, chunk_z});
if (it == m_chunks.end()) {
return ;
return;
}
int x, y, z;
y = world_y;
x = world_x - chunk_x * CHUCK_SIZE;
z = world_z - chunk_z * CHUCK_SIZE;
if (x < 0 || y < 0 || z < 0 || x >= CHUCK_SIZE || y >= WORLD_SIZE_Y || z >= CHUCK_SIZE) {
return ;
if (x < 0 || y < 0 || z < 0 || x >= CHUCK_SIZE || y >= WORLD_SIZE_Y ||
z >= CHUCK_SIZE) {
return;
}
it->second.set_chunk_block(Chunk::get_index(x, y, z), id);
static const glm::ivec3 NEIGHBOR_DIRS[] = {
{1, 0, 0}, {-1, 0, 0}, {0, 0, -1}, {0, 0, 1}
};
{1, 0, 0}, {-1, 0, 0}, {0, 0, -1}, {0, 0, 1}};
for (const auto& dir : NEIGHBOR_DIRS) {
glm::ivec3 neighbor = block_pos + dir;
@@ -620,17 +614,14 @@ void World::set_block(const glm::ivec3& block_pos, unsigned id) {
auto it = m_chunks.find({cx, cz});
if (it != m_chunks.end()) {
it->second.mark_dirty();
}
}
}
void World::update(float delta_time) {
for (auto& player : m_players) {
player.second.update(delta_time);
}
}
{
std::lock_guard lk(m_delete_vbo_mutex);
for (auto x : m_pending_delete_vbo) {
@@ -652,10 +643,10 @@ void World::update(float delta_time) {
}
// unified compute vertex data before rendering
{
{
std::lock_guard lk(m_chunks_mutex);
bool consumed = false;
for (auto& x : m_new_chunk) {
m_chunks.insert_or_assign(x.first, std::move(x.second));
consumed = true;
@@ -663,7 +654,7 @@ void World::update(float delta_time) {
if (consumed) {
m_could_gen = true;
}
m_render_snapshots.clear();
for (auto& [pos, chunk] : m_chunks) {
if (chunk.is_dirty()) {
@@ -684,15 +675,17 @@ void World::update(float delta_time) {
if (chunk.is_need_upload()) {
chunk.upload_to_gpu();
}
m_render_snapshots.push_back({
chunk.get_vbo(),
chunk.get_vertex_sum(),
glm::vec3(static_cast<float>(pos.x * CHUCK_SIZE) + static_cast<float>(CHUCK_SIZE / 2), static_cast<float>(WORLD_SIZE_Y/ 2), static_cast<float>(pos.z * CHUCK_SIZE) + static_cast<float>(CHUCK_SIZE / 2)),
glm::vec3(static_cast<float>(CHUCK_SIZE / 2), static_cast<float>(WORLD_SIZE_Y / 2), static_cast<float>(CHUCK_SIZE / 2))
}
);
m_render_snapshots.push_back(
{chunk.get_vbo(), chunk.get_vertex_sum(),
glm::vec3(static_cast<float>(pos.x * CHUCK_SIZE) +
static_cast<float>(CHUCK_SIZE / 2),
static_cast<float>(WORLD_SIZE_Y / 2),
static_cast<float>(pos.z * CHUCK_SIZE) +
static_cast<float>(CHUCK_SIZE / 2)),
glm::vec3(static_cast<float>(CHUCK_SIZE / 2),
static_cast<float>(WORLD_SIZE_Y / 2),
static_cast<float>(CHUCK_SIZE / 2))});
}
}
}
}
@@ -703,7 +696,7 @@ void World::push_delete_vbo(GLuint vbo) {
}
void World::hot_reload() {
auto & config = Config::get();
auto& config = Config::get();
int dist = config.get<int>("world.rendering_distance");
m_rendering_distance = dist <= MAX_DISTANCE ? dist : MAX_DISTANCE;
need_gen();
@@ -715,7 +708,7 @@ void World::rebuild_world() {
}
m_is_rebuilding = true;
stop_gen_thread();
{
std::scoped_lock lk(m_chunks_mutex, m_new_chunk_queue_mutex);
m_chunks.clear();
@@ -725,21 +718,16 @@ void World::rebuild_world() {
ChunkGenerator::reload();
start_gen_thread();
need_gen();
m_is_rebuilding = false;
}
float World::chunk_gen_fraction() const {
return m_chunk_gen_fraction.load();
}
float World::chunk_gen_fraction() const { return m_chunk_gen_fraction.load(); }
int World::rendering_distance() const {
return m_rendering_distance.load();
}
int World::rendering_distance() const { return m_rendering_distance.load(); }
void World::rendering_distance(int rendering_distance) {
m_rendering_distance = rendering_distance;
}
}
} // namespace Cubed