DeerithEngine/deerith_client/src/world/cluster_generation.cpp
2026-11-04 01:05:25 +01:00

123 lines
3.1 KiB
C++

#include <deerith/client/world.h>
#include <deerith/world/environment.h>
#include <deerith/client/internals/cluster_generation.h>
#include <deerith/client/graphics/mesh.h>
#include <deerith/client/cluster.h>
#include <vector>
#include <memory>
namespace deerith
{
std::mutex cluster_workers_mutex;
std::vector<std::unique_ptr<cluster_generator_t>> cluster_workers;
}
void deerith::generate_cluster(voxel_cluster_t *cluster)
{
std::lock_guard<std::mutex> lock(cluster_workers_mutex);
cluster_workers.push_back(std::make_unique<cluster_generator_t>());
cluster_generator_t *generator = cluster_workers.back().get();
generator->generate_cluster(cluster);
}
void deerith::cluster_generator_t::generate_cluster(voxel_cluster_t *_cluster)
{
cluster = _cluster;
if (cluster == nullptr)
{
deerith_error("cluster is null generate_cluster");
return;
}
for (int x = 0; x < CLUSTER_SIZE; x++)
{
for (int y = 0; y < CLUSTER_SIZE; y++)
{
for (int z = 0; z < CLUSTER_SIZE; z++)
{
generate_voxel(x, y, z);
}
}
}
}
void deerith::cluster_generator_t::generate_voxel(int x, int y, int z)
{
voxel_type_id_t cur_type_id = cluster->__data[x][y][z];
const voxel_type_t &cur_type = get_voxel_type(cur_type_id);
if (!cur_type.is_solid)
{
// nothing to build
return;
}
glm::vec3 voxel_position = glm::vec3(x, y, z) * VOXEL_SIZE;
for (int i = 0; i < 6; i++)
{
const int check_x = x + voxel_direction_order[i].x;
const int check_y = y + voxel_direction_order[i].y;
const int check_z = z + voxel_direction_order[i].z;
voxel_type_id_t check_voxel_id = get_cluster_voxel(check_x, check_y, check_z);
const voxel_type_t &check_voxel_type = get_voxel_type(check_voxel_id);
if (check_voxel_type.is_solid)
{
continue;
}
uint32_t starting_index = build_data.vertices.size();
// HEY BUILD FACE
for (int v = 0; v < 4; v++)
{
vertex_3d_t vertex = {
.position = voxel_position + voxel_direction_vertices[i][v],
.normal = voxel_direction_order[i],
};
build_data.vertices.push_back(vertex);
}
for (int index = 0; index < 6; index++)
{
build_data.indices.push_back(starting_index + face_indices_order[index]);
}
}
}
deerith::voxel_type_id_t deerith::cluster_generator_t::get_cluster_voxel(int x, int y, int z)
{
bool in_bounds_check = true;
if (x < 0 || x >= CLUSTER_SIZE)
{
in_bounds_check = false;
}
if (y < 0 || y >= CLUSTER_SIZE)
{
in_bounds_check = false;
}
if (z < 0 || z >= CLUSTER_SIZE)
{
in_bounds_check = false;
}
if (in_bounds_check)
{
return cluster->__data[x][y][z];
}
return 0;
glm::ivec3 coords;
coords.x = x + CLUSTER_SIZE * cluster->surface_id.x;
coords.y = y + CLUSTER_SIZE * cluster->layer;
coords.z = z + CLUSTER_SIZE * cluster->surface_id.y;
return get_voxel_id(coords);
}