overal meshing code cleanup
This commit is contained in:
parent
22ccf33e4a
commit
1ca49626d5
src/game/engine
@ -28,78 +28,6 @@ SOFTWARE.
|
|||||||
|
|
||||||
namespace polygun::engine {
|
namespace polygun::engine {
|
||||||
|
|
||||||
static bool is_face_obstructed(world::Chunk& chunk, int slice_axis_A_start, int slice_axis_A_end, int slice_axis_B_start, int slice_axis_B_end, int slice_axis_C, int face_axis_idx) {
|
|
||||||
// check if face is covered with any voxels
|
|
||||||
|
|
||||||
// bottom/top face check (y axis)
|
|
||||||
if (face_axis_idx == 0) {
|
|
||||||
for (int z = slice_axis_B_start; z < slice_axis_B_end; z++) {
|
|
||||||
for (int x = slice_axis_A_start; x < slice_axis_A_end; x++) {
|
|
||||||
if (chunk.get_node(glm::vec3(z, slice_axis_C, x)) == 0) { // if air, face is not fully covered, stop checking
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// left/right face check (x axis)
|
|
||||||
else if (face_axis_idx == 1) {
|
|
||||||
for (int z = slice_axis_B_start; z < slice_axis_B_end; z++) {
|
|
||||||
for (int y = slice_axis_A_start; y < slice_axis_A_end; y++) {
|
|
||||||
if (chunk.get_node(glm::vec3(z, y, slice_axis_C)) == 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// back/front face check (z axis
|
|
||||||
else {
|
|
||||||
for (int y = slice_axis_B_start; y < slice_axis_B_end; y++) {
|
|
||||||
for (int x = slice_axis_A_start; x < slice_axis_A_end; x++) {
|
|
||||||
if (chunk.get_node(glm::vec3(slice_axis_C, y, x)) == 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// none of returns were called, face is NOT visible
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int get_cuboid_axis(cuboid cuboid_sus, int index) {
|
|
||||||
switch(index) {
|
|
||||||
case 0:
|
|
||||||
return cuboid_sus.x1;
|
|
||||||
case 1:
|
|
||||||
return cuboid_sus.y1;
|
|
||||||
case 2:
|
|
||||||
return cuboid_sus.z1;
|
|
||||||
case 3:
|
|
||||||
return cuboid_sus.x2;
|
|
||||||
case 4:
|
|
||||||
return cuboid_sus.y2;
|
|
||||||
case 5:
|
|
||||||
return cuboid_sus.z2;
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int find_vec3(const std::vector<glm::vec3>& vec, const glm::vec3& target) {
|
|
||||||
for (size_t i = 0; i < vec.size(); i++) {
|
|
||||||
if (vec[i] == target) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1; // target not found
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
cuboid_list greedy_meshing::merge(world::Chunk& chunk) {
|
cuboid_list greedy_meshing::merge(world::Chunk& chunk) {
|
||||||
// create copy of chunk
|
// create copy of chunk
|
||||||
world::Chunk chunk_copy = chunk;
|
world::Chunk chunk_copy = chunk;
|
||||||
@ -107,11 +35,11 @@ namespace polygun::engine {
|
|||||||
cuboid_list cuboids;
|
cuboid_list cuboids;
|
||||||
cuboid cuboid_to_append;
|
cuboid cuboid_to_append;
|
||||||
|
|
||||||
for (m_y = 0; m_y < m_voxel_count; m_y++) {
|
for (unsigned int m_y = 0; m_y < m_voxel_count; m_y++) {
|
||||||
for (m_z = 0; m_z < m_voxel_count; m_z++) {
|
for (unsigned int m_z = 0; m_z < m_voxel_count; m_z++) {
|
||||||
m_last_material = 0;
|
m_last_material = 0;
|
||||||
|
|
||||||
for (m_x = 0; m_x < m_voxel_count; m_x++) {
|
for (unsigned int m_x = 0; m_x < m_voxel_count; m_x++) {
|
||||||
m_cuboid_ended = false;
|
m_cuboid_ended = false;
|
||||||
|
|
||||||
// if material changed
|
// if material changed
|
||||||
@ -150,7 +78,7 @@ namespace polygun::engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check if all materials in row are the same as the cuboid's material
|
// check if all materials in row are the same as the cuboid's material
|
||||||
for (m_x_s = m_cuboid_start_x; m_x_s < m_cuboid_end_x; m_x_s++) {
|
for (unsigned int m_x_s = m_cuboid_start_x; m_x_s < m_cuboid_end_x; m_x_s++) {
|
||||||
if (chunk_copy.get_node(glm::vec3(m_cuboid_end_z, m_y, m_x_s)) != m_last_material) {
|
if (chunk_copy.get_node(glm::vec3(m_cuboid_end_z, m_y, m_x_s)) != m_last_material) {
|
||||||
m_invalid_row = true;
|
m_invalid_row = true;
|
||||||
break;
|
break;
|
||||||
@ -162,7 +90,7 @@ namespace polygun::engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// set all values of next row that will be added to the cuboid to 0 to prevent them from being treated as a new cuboid in the next z loop iteration
|
// set all values of next row that will be added to the cuboid to 0 to prevent them from being treated as a new cuboid in the next z loop iteration
|
||||||
for (m_x_s = m_cuboid_start_x; m_x_s < m_cuboid_end_x; m_x_s++) {
|
for (unsigned int m_x_s = m_cuboid_start_x; m_x_s < m_cuboid_end_x; m_x_s++) {
|
||||||
chunk_copy.add_node(0, glm::vec3(m_cuboid_end_z, m_y, m_x_s));
|
chunk_copy.add_node(0, glm::vec3(m_cuboid_end_z, m_y, m_x_s));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -179,8 +107,8 @@ namespace polygun::engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check if all materials in a "plane" under the current cuboid are the same as the cuboid's material
|
// check if all materials in a "plane" under the current cuboid are the same as the cuboid's material
|
||||||
for (m_z_s = m_z; m_z_s < m_cuboid_end_z; m_z_s++) {
|
for (unsigned int m_z_s = m_z; m_z_s < m_cuboid_end_z; m_z_s++) {
|
||||||
for (m_x_s = m_cuboid_start_x; m_x_s < m_cuboid_end_x; m_x_s++) {
|
for (unsigned int m_x_s = m_cuboid_start_x; m_x_s < m_cuboid_end_x; m_x_s++) {
|
||||||
if (chunk_copy.get_node(glm::vec3(m_z_s, m_cuboid_end_y, m_x_s)) != m_last_material) {
|
if (chunk_copy.get_node(glm::vec3(m_z_s, m_cuboid_end_y, m_x_s)) != m_last_material) {
|
||||||
m_invalid_plane = true;
|
m_invalid_plane = true;
|
||||||
break;
|
break;
|
||||||
@ -193,17 +121,18 @@ namespace polygun::engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// set all values of next plane that will be added to the cuboid to 0 to prevent them from being treated as a new cuboid in the next y loop iteration
|
// set all values of next plane that will be added to the cuboid to 0 to prevent them from being treated as a new cuboid in the next y loop iteration
|
||||||
for (m_z_s = m_z; m_z_s < m_cuboid_end_z; m_z_s++) {
|
for (unsigned int m_z_s = m_z; m_z_s < m_cuboid_end_z; m_z_s++) {
|
||||||
for (m_x_s = m_cuboid_start_x; m_x_s < m_cuboid_end_x; m_x_s++) {
|
for (unsigned int m_x_s = m_cuboid_start_x; m_x_s < m_cuboid_end_x; m_x_s++) {
|
||||||
chunk_copy.add_node(0, glm::vec3(m_z_s, m_cuboid_end_y, m_x_s));
|
chunk_copy.add_node(0, glm::vec3(m_z_s, m_cuboid_end_y, m_x_s));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add cuboid to cuboids list
|
// add cuboid to cuboids
|
||||||
cuboid_to_append = {
|
cuboid_to_append = {{
|
||||||
m_cuboid_start_x, m_y, m_z,
|
m_cuboid_start_x, m_y, m_z,
|
||||||
m_cuboid_end_x, m_cuboid_end_y, m_cuboid_end_z,
|
m_cuboid_end_x, m_cuboid_end_y, m_cuboid_end_z,
|
||||||
|
},
|
||||||
m_last_material
|
m_last_material
|
||||||
};
|
};
|
||||||
cuboids.push_back(cuboid_to_append);
|
cuboids.push_back(cuboid_to_append);
|
||||||
@ -225,6 +154,50 @@ namespace polygun::engine {
|
|||||||
return cuboids;
|
return cuboids;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool is_face_obstructed(world::Chunk& chunk, unsigned int slice_axis_A_start, unsigned int slice_axis_A_end, unsigned int slice_axis_B_start, unsigned int slice_axis_B_end, unsigned int slice_axis_C, unsigned int face_axis_idx) {
|
||||||
|
// check if face is covered with any voxels
|
||||||
|
|
||||||
|
// bottom/top face check (y axis)
|
||||||
|
if (face_axis_idx == 0) {
|
||||||
|
for (unsigned int z = slice_axis_B_start; z < slice_axis_B_end; z++) {
|
||||||
|
for (unsigned int x = slice_axis_A_start; x < slice_axis_A_end; x++) {
|
||||||
|
if (chunk.get_node(glm::vec3(z, slice_axis_C, x)) == 0) { // if air, face is not fully covered, stop checking
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// left/right face check (x axis)
|
||||||
|
else if (face_axis_idx == 1) {
|
||||||
|
for (unsigned int z = slice_axis_B_start; z < slice_axis_B_end; z++) {
|
||||||
|
for (unsigned int y = slice_axis_A_start; y < slice_axis_A_end; y++) {
|
||||||
|
if (chunk.get_node(glm::vec3(z, y, slice_axis_C)) == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// back/front face check (z axis
|
||||||
|
else {
|
||||||
|
for (unsigned int y = slice_axis_B_start; y < slice_axis_B_end; y++) {
|
||||||
|
for (unsigned int x = slice_axis_A_start; x < slice_axis_A_end; x++) {
|
||||||
|
if (chunk.get_node(glm::vec3(slice_axis_C, y, x)) == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// none of returns were called, face is NOT visible
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static unsigned int faces_indices[6][6] = {
|
static unsigned int faces_indices[6][6] = {
|
||||||
{0, 1, 3, 0, 3, 2}, // bottom
|
{0, 1, 3, 0, 3, 2}, // bottom
|
||||||
{0, 2, 6, 0, 6, 4}, // left
|
{0, 2, 6, 0, 6, 4}, // left
|
||||||
@ -240,75 +213,72 @@ namespace polygun::engine {
|
|||||||
{0, 3, 1, 4, 2, 5}, // back/front face check
|
{0, 3, 1, 4, 2, 5}, // back/front face check
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
verticies_indices greedy_meshing::generate_mesh(cuboid_list cuboids, world::Chunk& chunk) {
|
verticies_indices greedy_meshing::generate_mesh(cuboid_list cuboids, world::Chunk& chunk) {
|
||||||
|
|
||||||
// WORK IN PROGRESS !
|
|
||||||
// STILL NOT WORKING AT ALL !
|
|
||||||
|
|
||||||
// Looki2000: I'm going to burn your eyes with my horrible C++ noob-ish code.
|
std::vector<glm::vec3> m_vertices;
|
||||||
|
std::vector<unsigned int> m_indices;
|
||||||
std::vector<glm::vec3> vertices;
|
std::vector<unsigned int> m_cuboid_vertices_indices;
|
||||||
std::vector<unsigned int> indices;
|
|
||||||
|
|
||||||
for(const cuboid& cur_cuboid : cuboids) {
|
for(const cuboid& cur_cuboid : cuboids) {
|
||||||
|
|
||||||
// calculate vertices
|
// calculate vertices
|
||||||
|
|
||||||
// positions of every vertex of the cuboid (each corner)
|
// positions of every vertex of the cuboid (each corner)
|
||||||
int m_cuboid_vertices[8][3] = {
|
unsigned int m_cuboid_vertices[8][3] = {
|
||||||
{cur_cuboid.x1, cur_cuboid.y1, cur_cuboid.z1},
|
{cur_cuboid.coords[0], cur_cuboid.coords[1], cur_cuboid.coords[2]},
|
||||||
{cur_cuboid.x2, cur_cuboid.y1, cur_cuboid.z1},
|
{cur_cuboid.coords[3], cur_cuboid.coords[1], cur_cuboid.coords[2]},
|
||||||
{cur_cuboid.x1, cur_cuboid.y1, cur_cuboid.z2},
|
{cur_cuboid.coords[0], cur_cuboid.coords[1], cur_cuboid.coords[5]},
|
||||||
{cur_cuboid.x2, cur_cuboid.y1, cur_cuboid.z2},
|
{cur_cuboid.coords[3], cur_cuboid.coords[1], cur_cuboid.coords[5]},
|
||||||
{cur_cuboid.x1, cur_cuboid.y2, cur_cuboid.z1},
|
{cur_cuboid.coords[0], cur_cuboid.coords[4], cur_cuboid.coords[2]},
|
||||||
{cur_cuboid.x2, cur_cuboid.y2, cur_cuboid.z1},
|
{cur_cuboid.coords[3], cur_cuboid.coords[4], cur_cuboid.coords[2]},
|
||||||
{cur_cuboid.x1, cur_cuboid.y2, cur_cuboid.z2},
|
{cur_cuboid.coords[0], cur_cuboid.coords[4], cur_cuboid.coords[5]},
|
||||||
{cur_cuboid.x2, cur_cuboid.y2, cur_cuboid.z2},
|
{cur_cuboid.coords[3], cur_cuboid.coords[4], cur_cuboid.coords[5]},
|
||||||
};
|
};
|
||||||
|
|
||||||
m_cuboid_vertices_indices = {};
|
|
||||||
|
|
||||||
// iterate over cuboid vertices
|
// iterate over cuboid vertices
|
||||||
for (const auto& vertex : m_cuboid_vertices) {
|
for (const auto& m_vertex : m_cuboid_vertices) {
|
||||||
|
|
||||||
|
int m_vertex_idx = -1;
|
||||||
|
|
||||||
// check if vertex is already in vertices list
|
// check if vertex is already in vertices list
|
||||||
//std::vector<glm::vec3>::iterator vertex_it = std::find(vertices.begin(), vertices.end(), vertex);
|
for (unsigned int i = 0; i < m_vertices.size(); i++) {
|
||||||
int vertex_it = find_vec3(vertices, glm::vec3(vertex[0], vertex[1], vertex[2]));
|
if (m_vertices[i] == glm::vec3(m_vertex[0], m_vertex[1], m_vertex[2])) {
|
||||||
|
int m_vertex_idx = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// if so, add found index to cuboid_vertices_indices
|
// if so, add found index to m_cuboid_vertices_indices
|
||||||
if (vertex_it != -1) {
|
if (m_vertex_idx != -1) {
|
||||||
m_cuboid_vertices_indices.push_back(vertex_it);
|
m_cuboid_vertices_indices.push_back(m_vertex_idx);
|
||||||
|
|
||||||
// if not, add it (vertex) and add its index to cuboid_vertices_indices
|
// if not, add it (vertex) and add its index to m_cuboid_vertices_indices
|
||||||
} else {
|
} else {
|
||||||
m_cuboid_vertices_indices.push_back(vertices.size());
|
m_cuboid_vertices_indices.push_back(m_vertices.size());
|
||||||
vertices.push_back(glm::vec3(vertex[0], vertex[1], vertex[2]));
|
m_vertices.push_back(glm::make_vec3(m_vertex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate faces
|
// calculate faces
|
||||||
|
|
||||||
for (int face_idx = 0; face_idx < 6; ++face_idx) {
|
for (unsigned int face_idx = 0; face_idx < 6; ++face_idx) {
|
||||||
// do not add faces that are not visible. check what sides of cuboid are occupied by voxels completely
|
// do not add faces that are not visible. check what sides of cuboid are occupied by voxels completely
|
||||||
// if a side is not occupied, add the corresponding faces to the mesh
|
// if a side is not occupied, add the corresponding faces to the mesh
|
||||||
|
|
||||||
int face_dir = face_idx / 3;
|
unsigned int face_dir = face_idx / 3;
|
||||||
int face_axis_idx = face_idx % 3;
|
unsigned int face_axis_idx = face_idx % 3;
|
||||||
// face_dir: 0 - negative, 1 - positive
|
// face_dir: 0 - negative, 1 - positive
|
||||||
|
|
||||||
//int slice_axis_C = cur_cuboid[slice_axises_indices[face_axis_idx][4 + face_dir]] - (1 - face_dir)
|
unsigned int slice_axis_C = cur_cuboid.coords[slice_axises_indices[face_axis_idx][4 + face_dir]] - (1 - face_dir);
|
||||||
int slice_axis_C = get_cuboid_axis(cur_cuboid, slice_axises_indices[face_axis_idx][4 + face_dir]) - (1 - face_dir);
|
|
||||||
|
|
||||||
// if face is NOT touching chunk border
|
// if face is NOT touching chunk border
|
||||||
if(slice_axis_C != -1 && slice_axis_C != m_voxel_count) {
|
if (slice_axis_C != -1 && slice_axis_C != m_voxel_count) {
|
||||||
// start and end of axises for scan of slice of voxels next to the face
|
// start and end of axises for scan of slice of voxels next to the face
|
||||||
//int slice_axis_A_start = cur_cuboid[slice_axises_indices[face_axis_idx][0]]
|
unsigned int slice_axis_A_start = cur_cuboid.coords[slice_axises_indices[face_axis_idx][0]];
|
||||||
//int slice_axis_A_end = cur_cuboid[slice_axises_indices[face_axis_idx][1]]
|
unsigned int slice_axis_A_end = cur_cuboid.coords[slice_axises_indices[face_axis_idx][1]];
|
||||||
//int slice_axis_B_start = cur_cuboid[slice_axises_indices[face_axis_idx][2]]
|
unsigned int slice_axis_B_start = cur_cuboid.coords[slice_axises_indices[face_axis_idx][2]];
|
||||||
//int slice_axis_B_end = cur_cuboid[slice_axises_indices[face_axis_idx][3]]
|
unsigned int slice_axis_B_end = cur_cuboid.coords[slice_axises_indices[face_axis_idx][3]];
|
||||||
int slice_axis_A_start = get_cuboid_axis(cur_cuboid, slice_axises_indices[face_axis_idx][0]);
|
|
||||||
int slice_axis_A_end = get_cuboid_axis(cur_cuboid, slice_axises_indices[face_axis_idx][1]);
|
|
||||||
int slice_axis_B_start = get_cuboid_axis(cur_cuboid, slice_axises_indices[face_axis_idx][2]);
|
|
||||||
int slice_axis_B_end = get_cuboid_axis(cur_cuboid, slice_axises_indices[face_axis_idx][3]);
|
|
||||||
|
|
||||||
// check if face is obstructed by any voxels
|
// check if face is obstructed by any voxels
|
||||||
if (is_face_obstructed(chunk, slice_axis_A_start, slice_axis_A_end, slice_axis_B_start, slice_axis_B_end, slice_axis_C, face_axis_idx)) {
|
if (is_face_obstructed(chunk, slice_axis_A_start, slice_axis_A_end, slice_axis_B_start, slice_axis_B_end, slice_axis_C, face_axis_idx)) {
|
||||||
@ -317,14 +287,14 @@ namespace polygun::engine {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 6; ++i) {
|
for (unsigned int i = 0; i < 6; ++i) {
|
||||||
indices.push_back(m_cuboid_vertices_indices[faces_indices[face_idx][i]]);
|
m_indices.push_back(m_cuboid_vertices_indices[faces_indices[face_idx][i]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {vertices, indices};
|
return {m_vertices, m_indices};
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -31,7 +31,7 @@ SOFTWARE.
|
|||||||
|
|
||||||
namespace polygun::engine {
|
namespace polygun::engine {
|
||||||
struct cuboid {
|
struct cuboid {
|
||||||
int x1, y1, z1, x2, y2, z2, material;
|
unsigned int coords[6], material;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct verticies_indices {
|
struct verticies_indices {
|
||||||
@ -51,17 +51,12 @@ namespace polygun::engine {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// greedy merging
|
// greedy merging
|
||||||
const int m_voxel_count = 32;
|
const unsigned int m_voxel_count = 32;
|
||||||
const int m_voxel_max_idx = m_voxel_count - 1;
|
const unsigned int m_voxel_max_idx = m_voxel_count - 1;
|
||||||
|
|
||||||
int m_x, m_y, m_z, m_x_s, m_z_s; // for "for" loops
|
unsigned int m_last_material, m_cuboid_start_x, m_cuboid_end_x, m_cuboid_end_z, m_cuboid_end_y;
|
||||||
|
|
||||||
int m_last_material, m_cuboid_start_x, m_cuboid_end_x, m_cuboid_end_z, m_cuboid_end_y;
|
|
||||||
bool m_cuboid_ended, m_invalid_row, m_invalid_plane;
|
bool m_cuboid_ended, m_invalid_row, m_invalid_plane;
|
||||||
|
|
||||||
// meshing
|
|
||||||
std::vector<unsigned int> m_cuboid_vertices_indices;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user