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 "voxel_mesher_dmc.h"
|
||||||
#include "../cube_tables.h"
|
#include "../cube_tables.h"
|
||||||
#include "../utility.h"
|
|
||||||
#include "marching_cubes_tables.h"
|
#include "marching_cubes_tables.h"
|
||||||
#include <map>
|
#include "mesh_builder.h"
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
// Algorithm taken from https://www.volume-gfx.com/volume-rendering/dual-marching-cubes/
|
// 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]);
|
vert_proc(grid, children[0], children[1], children[2], children[3], children[4], children[5], children[6], children[7]);
|
||||||
}
|
}
|
||||||
|
|
||||||
class MeshBuilder {
|
Ref<ArrayMesh> polygonize_dual_grid(const DualGrid &grid, const VoxelBuffer &voxels, bool wireframe, MeshBuilder &mesh_builder) {
|
||||||
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;
|
|
||||||
|
|
||||||
for (int dci = 0; dci < grid.cells.size(); ++dci) {
|
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);
|
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 padding = 1;
|
||||||
int chunk_size = CHUNK_SIZE;
|
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 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
|
// TODO Marching squares skirts
|
||||||
|
|
||||||
|
return mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace dmc
|
} // namespace dmc
|
||||||
|
|
||||||
Ref<ArrayMesh> VoxelMesherDMC::build_mesh(Ref<VoxelBuffer> voxels, real_t geometric_error, Mode mode) {
|
Ref<ArrayMesh> VoxelMesherDMC::build_mesh(Ref<VoxelBuffer> voxels, real_t geometric_error, Mode mode) {
|
||||||
ERR_FAIL_COND_V(voxels.is_null(), Ref<ArrayMesh>());
|
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() {
|
void VoxelMesherDMC::_bind_methods() {
|
||||||
|
@ -2,13 +2,9 @@
|
|||||||
#define VOXEL_MESHER_DMC_H
|
#define VOXEL_MESHER_DMC_H
|
||||||
|
|
||||||
#include "../voxel_buffer.h"
|
#include "../voxel_buffer.h"
|
||||||
|
#include "mesh_builder.h"
|
||||||
#include "scene/resources/mesh.h"
|
#include "scene/resources/mesh.h"
|
||||||
|
|
||||||
namespace dmc {
|
|
||||||
|
|
||||||
Ref<ArrayMesh> polygonize(const VoxelBuffer &voxels, float geometric_error);
|
|
||||||
}
|
|
||||||
|
|
||||||
class VoxelMesherDMC : public Reference {
|
class VoxelMesherDMC : public Reference {
|
||||||
GDCLASS(VoxelMesherDMC, Reference)
|
GDCLASS(VoxelMesherDMC, Reference)
|
||||||
public:
|
public:
|
||||||
@ -23,6 +19,9 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
|
private:
|
||||||
|
dmc::MeshBuilder _mesh_builder;
|
||||||
};
|
};
|
||||||
|
|
||||||
VARIANT_ENUM_CAST(VoxelMesherDMC::Mode)
|
VARIANT_ENUM_CAST(VoxelMesherDMC::Mode)
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define HEADER_VOXEL_UTILITY_H
|
#define HEADER_VOXEL_UTILITY_H
|
||||||
|
|
||||||
#include "vector3i.h"
|
#include "vector3i.h"
|
||||||
|
#include <core/pool_vector.h>
|
||||||
#include <core/ustring.h>
|
#include <core/ustring.h>
|
||||||
#include <core/vector.h>
|
#include <core/vector.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
Loading…
Reference in New Issue
Block a user