134 lines
3.4 KiB
C++
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);
|
|
} |