#include #include #include #include #include #include #include namespace deerith { std::mutex cluster_workers_mutex; std::vector> cluster_workers; } void deerith::generate_cluster(voxel_cluster_t *cluster) { std::lock_guard lock(cluster_workers_mutex); cluster_workers.push_back(std::make_unique()); 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); }