mirror of
https://github.com/Relintai/godot_voxel.git
synced 2024-11-19 02:47:18 +01:00
Fix dependency in utility.h, move MeshBuilder to its own file, re-use vertex arrays
This commit is contained in:
parent
35e03f7e77
commit
9bb81f9bb7
63
dmc/mesh_builder.cpp
Normal file
63
dmc/mesh_builder.cpp
Normal file
@ -0,0 +1,63 @@
|
||||
#include "mesh_builder.h"
|
||||
|
||||
namespace dmc {
|
||||
|
||||
Ref<ArrayMesh> MeshBuilder::commit(bool wireframe) {
|
||||
|
||||
if (_positions.size() == 0) {
|
||||
return Ref<ArrayMesh>();
|
||||
}
|
||||
|
||||
ERR_FAIL_COND_V(_indices.size() % 3 != 0, Ref<ArrayMesh>());
|
||||
|
||||
if (wireframe) {
|
||||
|
||||
// Debug purpose, no effort to be fast here
|
||||
std::vector<int> 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<ArrayMesh> 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
|
46
dmc/mesh_builder.h
Normal file
46
dmc/mesh_builder.h
Normal file
@ -0,0 +1,46 @@
|
||||
#ifndef MESH_BUILDER_H
|
||||
#define MESH_BUILDER_H
|
||||
|
||||
#include "../utility.h"
|
||||
#include <scene/resources/mesh.h>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
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<ArrayMesh> commit(bool wireframe);
|
||||
void clear();
|
||||
|
||||
private:
|
||||
std::vector<Vector3> _positions;
|
||||
std::vector<Vector3> _normals;
|
||||
std::vector<int> _indices;
|
||||
std::map<Vector3, int> _position_to_index;
|
||||
};
|
||||
|
||||
} // namespace dmc
|
||||
|
||||
#endif // MESH_BUILDER_H
|
@ -1,9 +1,7 @@
|
||||
#include "voxel_mesher_dmc.h"
|
||||
#include "../cube_tables.h"
|
||||
#include "../utility.h"
|
||||
#include "marching_cubes_tables.h"
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#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<ArrayMesh> commit(bool wireframe) {
|
||||
|
||||
if (_positions.size() == 0) {
|
||||
return Ref<ArrayMesh>();
|
||||
}
|
||||
|
||||
ERR_FAIL_COND_V(_indices.size() % 3 != 0, Ref<ArrayMesh>());
|
||||
|
||||
if (wireframe) {
|
||||
|
||||
// Debug purpose, no effort to be fast here
|
||||
std::vector<int> 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<ArrayMesh> mesh;
|
||||
mesh.instance();
|
||||
mesh->add_surface_from_arrays(wireframe ? Mesh::PRIMITIVE_LINES : Mesh::PRIMITIVE_TRIANGLES, surface);
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<Vector3> _positions;
|
||||
std::vector<Vector3> _normals;
|
||||
std::vector<int> _indices;
|
||||
std::map<Vector3, int> _position_to_index;
|
||||
};
|
||||
|
||||
Ref<ArrayMesh> polygonize_dual_grid(const DualGrid &grid, const VoxelBuffer &voxels, bool wireframe) {
|
||||
|
||||
MeshBuilder mesh_builder;
|
||||
Ref<ArrayMesh> 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<ArrayMesh> polygonize_dual_grid(const DualGrid &grid, const VoxelBuffer &vox
|
||||
return mesh_builder.commit(wireframe);
|
||||
}
|
||||
|
||||
Ref<ArrayMesh> polygonize(const VoxelBuffer &voxels, float geometric_error, VoxelMesherDMC::Mode mode) {
|
||||
Ref<ArrayMesh> 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<ArrayMesh> 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<ArrayMesh> mesh = polygonize_dual_grid(grid, voxels, mode == VoxelMesherDMC::MODE_WIREFRAME, mesh_builder);
|
||||
// TODO Marching squares skirts
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
} // namespace dmc
|
||||
|
||||
Ref<ArrayMesh> VoxelMesherDMC::build_mesh(Ref<VoxelBuffer> voxels, real_t geometric_error, Mode mode) {
|
||||
ERR_FAIL_COND_V(voxels.is_null(), Ref<ArrayMesh>());
|
||||
return dmc::polygonize(**voxels, geometric_error, mode);
|
||||
return dmc::polygonize(**voxels, geometric_error, mode, _mesh_builder);
|
||||
}
|
||||
|
||||
void VoxelMesherDMC::_bind_methods() {
|
||||
|
@ -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<ArrayMesh> 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)
|
||||
|
Loading…
Reference in New Issue
Block a user