DeerithEngine/deerith_client/src/world/cluster_generation.cpp
2026-11-03 18:56:57 +01:00

134 lines
3.4 KiB
C++

#include <deerith/client/world.h>
#include <deerith/world/environment.h>
#include <deerith/client/internals/cluster_generation.h>
#include <vector>
#include <memory>
#include <deerith/client/graphics/mesh.h>
namespace deerith
{
cluster_voxel_type_id_data_t *cluster_data = nullptr;
glm::ivec2 cluster_id;
size_t cluster_height_id;
void generate_voxel(int x, int y, int z);
voxel_type_id_t get_cluster_voxel(int x, int y, int z);
std::unique_ptr<mesh_3d_t> test_mesh;
std::unique_ptr<mesh_3d_data_t> build_data;
}
void deerith::load_clusters_to_gpu()
{
if (build_data)
{
test_mesh = std::make_unique<mesh_3d_t>(*build_data);
build_data.reset();
}
}
void deerith::generate_cluster(glm::ivec2 _cluster_id, size_t _cluster_height_id)
{
if (build_data)
{
return;
}
build_data = std::make_unique<mesh_3d_data_t>();
cluster_data = get_cluster_voxel_type_id_raw_ponter(_cluster_id, _cluster_height_id);
cluster_id = _cluster_id;
cluster_height_id = _cluster_height_id;
if (cluster_data == nullptr)
{
deerith_error("cluster data is null and it should not 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::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] * VOXEL_SIZE,
.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::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];
}
glm::ivec3 coords(x + CLUSTER_SIZE * cluster_id.x,
y + (cluster_height_id - STARTING_CLUSTER_HEIGHT) * CLUSTER_SIZE,
z + cluster_id.y * CLUSTER_SIZE);
return get_voxel_id(coords);
}