From 9bb81f9bb7520310ed0b2db8b009a1340bf3fa43 Mon Sep 17 00:00:00 2001 From: Marc Gilleron Date: Sun, 21 Apr 2019 01:14:28 +0100 Subject: [PATCH] Fix dependency in utility.h, move MeshBuilder to its own file, re-use vertex arrays --- dmc/mesh_builder.cpp | 63 +++++++++++++++++++++++++++ dmc/mesh_builder.h | 46 ++++++++++++++++++++ dmc/voxel_mesher_dmc.cpp | 94 +++------------------------------------- dmc/voxel_mesher_dmc.h | 9 ++-- utility.h | 1 + 5 files changed, 121 insertions(+), 92 deletions(-) create mode 100644 dmc/mesh_builder.cpp create mode 100644 dmc/mesh_builder.h diff --git a/dmc/mesh_builder.cpp b/dmc/mesh_builder.cpp new file mode 100644 index 0000000..d3d57e6 --- /dev/null +++ b/dmc/mesh_builder.cpp @@ -0,0 +1,63 @@ +#include "mesh_builder.h" + +namespace dmc { + +Ref MeshBuilder::commit(bool wireframe) { + + if (_positions.size() == 0) { + return Ref(); + } + + ERR_FAIL_COND_V(_indices.size() % 3 != 0, Ref()); + + if (wireframe) { + + // Debug purpose, no effort to be fast here + std::vector wireframe_indices; + + for (int i = 0; i < _indices.size(); i += 3) { + + wireframe_indices.push_back(_indices[i]); + wireframe_indices.push_back(_indices[i + 1]); + + wireframe_indices.push_back(_indices[i + 1]); + wireframe_indices.push_back(_indices[i + 2]); + + wireframe_indices.push_back(_indices[i + 2]); + wireframe_indices.push_back(_indices[i]); + } + + _indices = wireframe_indices; + } + + PoolVector3Array positions; + PoolVector3Array normals; + PoolIntArray indices; + + raw_copy_to(positions, _positions); + raw_copy_to(normals, _normals); + raw_copy_to(indices, _indices); + + clear(); + + Array surface; + surface.resize(Mesh::ARRAY_MAX); + surface[Mesh::ARRAY_VERTEX] = positions; + surface[Mesh::ARRAY_NORMAL] = normals; + surface[Mesh::ARRAY_INDEX] = indices; + + Ref mesh; + mesh.instance(); + mesh->add_surface_from_arrays(wireframe ? Mesh::PRIMITIVE_LINES : Mesh::PRIMITIVE_TRIANGLES, surface); + + return mesh; +} + +void MeshBuilder::clear() { + _positions.clear(); + _normals.clear(); + _indices.clear(); + _position_to_index.clear(); +} + +} // namespace dmc diff --git a/dmc/mesh_builder.h b/dmc/mesh_builder.h new file mode 100644 index 0000000..3d86de3 --- /dev/null +++ b/dmc/mesh_builder.h @@ -0,0 +1,46 @@ +#ifndef MESH_BUILDER_H +#define MESH_BUILDER_H + +#include "../utility.h" +#include +#include +#include + +namespace dmc { + +// Faster than SurfaceTool, only does what is needed +class MeshBuilder { +public: + inline void add_vertex(Vector3 position, Vector3 normal) { + + int i = 0; + + if (_position_to_index.find(position) != _position_to_index.end()) { + + i = _position_to_index[position]; + + } else { + + i = _positions.size(); + _position_to_index[position] = i; + + _positions.push_back(position); + _normals.push_back(normal); + } + + _indices.push_back(i); + } + + Ref commit(bool wireframe); + void clear(); + +private: + std::vector _positions; + std::vector _normals; + std::vector _indices; + std::map _position_to_index; +}; + +} // namespace dmc + +#endif // MESH_BUILDER_H diff --git a/dmc/voxel_mesher_dmc.cpp b/dmc/voxel_mesher_dmc.cpp index eb37c38..0bb7538 100644 --- a/dmc/voxel_mesher_dmc.cpp +++ b/dmc/voxel_mesher_dmc.cpp @@ -1,9 +1,7 @@ #include "voxel_mesher_dmc.h" #include "../cube_tables.h" -#include "../utility.h" #include "marching_cubes_tables.h" -#include -#include +#include "mesh_builder.h" // Algorithm taken from https://www.volume-gfx.com/volume-rendering/dual-marching-cubes/ @@ -1118,87 +1116,7 @@ void node_proc(DualGrid &grid, OctreeNode *node) { vert_proc(grid, children[0], children[1], children[2], children[3], children[4], children[5], children[6], children[7]); } -class MeshBuilder { -public: - void add_vertex(Vector3 position, Vector3 normal) { - - int i = 0; - - if (_position_to_index.find(position) != _position_to_index.end()) { - - i = _position_to_index[position]; - - } else { - - i = _positions.size(); - _position_to_index[position] = i; - - _positions.push_back(position); - _normals.push_back(normal); - } - - _indices.push_back(i); - } - - Ref commit(bool wireframe) { - - if (_positions.size() == 0) { - return Ref(); - } - - ERR_FAIL_COND_V(_indices.size() % 3 != 0, Ref()); - - if (wireframe) { - - // Debug purpose, no effort to be fast here - std::vector wireframe_indices; - - for (int i = 0; i < _indices.size(); i += 3) { - - wireframe_indices.push_back(_indices[i]); - wireframe_indices.push_back(_indices[i + 1]); - - wireframe_indices.push_back(_indices[i + 1]); - wireframe_indices.push_back(_indices[i + 2]); - - wireframe_indices.push_back(_indices[i + 2]); - wireframe_indices.push_back(_indices[i]); - } - - _indices = wireframe_indices; - } - - PoolVector3Array positions; - PoolVector3Array normals; - PoolIntArray indices; - - raw_copy_to(positions, _positions); - raw_copy_to(normals, _normals); - raw_copy_to(indices, _indices); - - Array surface; - surface.resize(Mesh::ARRAY_MAX); - surface[Mesh::ARRAY_VERTEX] = positions; - surface[Mesh::ARRAY_NORMAL] = normals; - surface[Mesh::ARRAY_INDEX] = indices; - - Ref mesh; - mesh.instance(); - mesh->add_surface_from_arrays(wireframe ? Mesh::PRIMITIVE_LINES : Mesh::PRIMITIVE_TRIANGLES, surface); - - return mesh; - } - -private: - std::vector _positions; - std::vector _normals; - std::vector _indices; - std::map _position_to_index; -}; - -Ref polygonize_dual_grid(const DualGrid &grid, const VoxelBuffer &voxels, bool wireframe) { - - MeshBuilder mesh_builder; +Ref polygonize_dual_grid(const DualGrid &grid, const VoxelBuffer &voxels, bool wireframe, MeshBuilder &mesh_builder) { for (int dci = 0; dci < grid.cells.size(); ++dci) { @@ -1287,7 +1205,7 @@ Ref polygonize_dual_grid(const DualGrid &grid, const VoxelBuffer &vox return mesh_builder.commit(wireframe); } -Ref polygonize(const VoxelBuffer &voxels, float geometric_error, VoxelMesherDMC::Mode mode) { +Ref polygonize(const VoxelBuffer &voxels, float geometric_error, VoxelMesherDMC::Mode mode, MeshBuilder &mesh_builder) { int padding = 1; int chunk_size = CHUNK_SIZE; @@ -1313,15 +1231,17 @@ Ref polygonize(const VoxelBuffer &voxels, float geometric_error, Voxe return generate_debug_dual_grid_mesh(grid); } - return polygonize_dual_grid(grid, voxels, mode == VoxelMesherDMC::MODE_WIREFRAME); + Ref mesh = polygonize_dual_grid(grid, voxels, mode == VoxelMesherDMC::MODE_WIREFRAME, mesh_builder); // TODO Marching squares skirts + + return mesh; } } // namespace dmc Ref VoxelMesherDMC::build_mesh(Ref voxels, real_t geometric_error, Mode mode) { ERR_FAIL_COND_V(voxels.is_null(), Ref()); - return dmc::polygonize(**voxels, geometric_error, mode); + return dmc::polygonize(**voxels, geometric_error, mode, _mesh_builder); } void VoxelMesherDMC::_bind_methods() { diff --git a/dmc/voxel_mesher_dmc.h b/dmc/voxel_mesher_dmc.h index b6557b7..0e55c5f 100644 --- a/dmc/voxel_mesher_dmc.h +++ b/dmc/voxel_mesher_dmc.h @@ -2,13 +2,9 @@ #define VOXEL_MESHER_DMC_H #include "../voxel_buffer.h" +#include "mesh_builder.h" #include "scene/resources/mesh.h" -namespace dmc { - -Ref polygonize(const VoxelBuffer &voxels, float geometric_error); -} - class VoxelMesherDMC : public Reference { GDCLASS(VoxelMesherDMC, Reference) public: @@ -23,6 +19,9 @@ public: protected: static void _bind_methods(); + +private: + dmc::MeshBuilder _mesh_builder; }; VARIANT_ENUM_CAST(VoxelMesherDMC::Mode) diff --git a/utility.h b/utility.h index ee62580..e1e2a85 100644 --- a/utility.h +++ b/utility.h @@ -2,6 +2,7 @@ #define HEADER_VOXEL_UTILITY_H #include "vector3i.h" +#include #include #include #include