Expose octree mode, mesh mode and geometric error as properties; initialize stats

This commit is contained in:
Marc Gilleron 2019-04-23 01:30:15 +01:00
parent a80ddc450b
commit b627a5736d
2 changed files with 95 additions and 27 deletions

View File

@ -1241,7 +1241,39 @@ void polygonize_dual_grid(const DualGrid &grid, const VoxelAccess &voxels, MeshB
#define BUILD_OCTREE_BOTTOM_UP #define BUILD_OCTREE_BOTTOM_UP
Ref<ArrayMesh> VoxelMesherDMC::build_mesh(const VoxelBuffer &voxels, real_t geometric_error, Mode mode) { VoxelMesherDMC::VoxelMesherDMC() {
_geometric_error = 0.1;
_mesh_mode = MESH_NORMAL;
_octree_mode = OCTREE_BOTTOM_UP;
_stats = { 0 };
}
void VoxelMesherDMC::set_mesh_mode(MeshMode mode) {
_mesh_mode = mode;
}
VoxelMesherDMC::MeshMode VoxelMesherDMC::get_mesh_mode() const {
return _mesh_mode;
}
void VoxelMesherDMC::set_octree_mode(OctreeMode mode) {
_octree_mode = mode;
}
VoxelMesherDMC::OctreeMode VoxelMesherDMC::get_octree_mode() const {
return _octree_mode;
}
void VoxelMesherDMC::set_geometric_error(real_t geometric_error) {
_geometric_error = geometric_error;
}
float VoxelMesherDMC::get_geometric_error() const {
return _geometric_error;
}
Ref<ArrayMesh> VoxelMesherDMC::build_mesh(const VoxelBuffer &voxels) {
// Requirements: // Requirements:
// - Voxel data must be padded // - Voxel data must be padded
@ -1278,14 +1310,18 @@ Ref<ArrayMesh> VoxelMesherDMC::build_mesh(const VoxelBuffer &voxels, real_t geom
// Building the octree bottom-up ensures to always catch voxels of any size, but will be a bit slower // Building the octree bottom-up ensures to always catch voxels of any size, but will be a bit slower
// because all voxels are queried. // because all voxels are queried.
// //
#ifdef BUILD_OCTREE_BOTTOM_UP // TODO This option might disappear once I find a good enough solution
dmc::OctreeBuilderBottomUp octree_builder(voxels_access, geometric_error, _octree_node_pool); dmc::OctreeNode *root;
dmc::OctreeNode *root = octree_builder.build(Vector3i(), chunk_size); if (_octree_mode == OCTREE_BOTTOM_UP) {
#else
dmc::OctreeBuilderTopDown octree_builder(voxels_access, geometric_error, _octree_node_pool); dmc::OctreeBuilderBottomUp octree_builder(voxels_access, _geometric_error, _octree_node_pool);
dmc::OctreeNode *root = octree_builder.build(Vector3i(), chunk_size); root = octree_builder.build(Vector3i(), chunk_size);
#endif
// TODO OctreeNode pool to stop allocating. Or, flat octree? } else {
dmc::OctreeBuilderTopDown octree_builder(voxels_access, _geometric_error, _octree_node_pool);
root = octree_builder.build(Vector3i(), chunk_size);
}
_stats.octree_build_time = OS::get_singleton()->get_ticks_usec() - time_before; _stats.octree_build_time = OS::get_singleton()->get_ticks_usec() - time_before;
@ -1293,7 +1329,7 @@ Ref<ArrayMesh> VoxelMesherDMC::build_mesh(const VoxelBuffer &voxels, real_t geom
if (root != nullptr) { if (root != nullptr) {
if (mode == VoxelMesherDMC::MODE_DEBUG_OCTREE) { if (_mesh_mode == MESH_DEBUG_OCTREE) {
mesh = dmc::generate_debug_octree_mesh(root); mesh = dmc::generate_debug_octree_mesh(root);
} else { } else {
@ -1306,7 +1342,7 @@ Ref<ArrayMesh> VoxelMesherDMC::build_mesh(const VoxelBuffer &voxels, real_t geom
_stats.dualgrid_derivation_time = OS::get_singleton()->get_ticks_usec() - time_before; _stats.dualgrid_derivation_time = OS::get_singleton()->get_ticks_usec() - time_before;
if (mode == VoxelMesherDMC::MODE_DEBUG_DUAL_GRID) { if (_mesh_mode == MESH_DEBUG_DUAL_GRID) {
mesh = dmc::generate_debug_dual_grid_mesh(_dual_grid); mesh = dmc::generate_debug_dual_grid_mesh(_dual_grid);
} else { } else {
@ -1316,7 +1352,7 @@ Ref<ArrayMesh> VoxelMesherDMC::build_mesh(const VoxelBuffer &voxels, real_t geom
_stats.meshing_time = OS::get_singleton()->get_ticks_usec() - time_before; _stats.meshing_time = OS::get_singleton()->get_ticks_usec() - time_before;
time_before = OS::get_singleton()->get_ticks_usec(); time_before = OS::get_singleton()->get_ticks_usec();
mesh = _mesh_builder.commit(mode == VoxelMesherDMC::MODE_WIREFRAME); mesh = _mesh_builder.commit(_mesh_mode == MESH_WIREFRAME);
_stats.commit_time = OS::get_singleton()->get_ticks_usec() - time_before; _stats.commit_time = OS::get_singleton()->get_ticks_usec() - time_before;
} }
@ -1331,9 +1367,9 @@ Ref<ArrayMesh> VoxelMesherDMC::build_mesh(const VoxelBuffer &voxels, real_t geom
return mesh; return mesh;
} }
Ref<ArrayMesh> VoxelMesherDMC::_build_mesh_b(Ref<VoxelBuffer> voxels, real_t geometric_error, Mode mode) { Ref<ArrayMesh> VoxelMesherDMC::_build_mesh_b(Ref<VoxelBuffer> voxels) {
ERR_FAIL_COND_V(voxels.is_null(), Ref<ArrayMesh>()); ERR_FAIL_COND_V(voxels.is_null(), Ref<ArrayMesh>());
return build_mesh(**voxels, geometric_error, mode); return build_mesh(**voxels);
} }
Dictionary VoxelMesherDMC::get_stats() const { Dictionary VoxelMesherDMC::get_stats() const {
@ -1347,11 +1383,23 @@ Dictionary VoxelMesherDMC::get_stats() const {
void VoxelMesherDMC::_bind_methods() { void VoxelMesherDMC::_bind_methods() {
ClassDB::bind_method(D_METHOD("build_mesh", "voxel_buffer", "geometric_error", "mode"), &VoxelMesherDMC::_build_mesh_b, DEFVAL(MODE_NORMAL)); ClassDB::bind_method(D_METHOD("set_mesh_mode", "mode"), &VoxelMesherDMC::set_mesh_mode);
ClassDB::bind_method(D_METHOD("get_mesh_mode"), &VoxelMesherDMC::get_mesh_mode);
ClassDB::bind_method(D_METHOD("set_octree_mode", "mode"), &VoxelMesherDMC::set_octree_mode);
ClassDB::bind_method(D_METHOD("get_octree_mode"), &VoxelMesherDMC::get_octree_mode);
ClassDB::bind_method(D_METHOD("set_geometric_error", "error"), &VoxelMesherDMC::set_geometric_error);
ClassDB::bind_method(D_METHOD("get_geometric_error"), &VoxelMesherDMC::get_geometric_error);
ClassDB::bind_method(D_METHOD("build_mesh", "voxel_buffer"), &VoxelMesherDMC::_build_mesh_b);
ClassDB::bind_method(D_METHOD("get_stats"), &VoxelMesherDMC::get_stats); ClassDB::bind_method(D_METHOD("get_stats"), &VoxelMesherDMC::get_stats);
BIND_ENUM_CONSTANT(MODE_NORMAL); BIND_ENUM_CONSTANT(MESH_NORMAL);
BIND_ENUM_CONSTANT(MODE_WIREFRAME); BIND_ENUM_CONSTANT(MESH_WIREFRAME);
BIND_ENUM_CONSTANT(MODE_DEBUG_OCTREE); BIND_ENUM_CONSTANT(MESH_DEBUG_OCTREE);
BIND_ENUM_CONSTANT(MODE_DEBUG_DUAL_GRID); BIND_ENUM_CONSTANT(MESH_DEBUG_DUAL_GRID);
BIND_ENUM_CONSTANT(OCTREE_BOTTOM_UP);
BIND_ENUM_CONSTANT(OCTREE_TOP_DOWN);
} }

View File

@ -67,24 +67,43 @@ struct DualGrid {
class VoxelMesherDMC : public Reference { class VoxelMesherDMC : public Reference {
GDCLASS(VoxelMesherDMC, Reference) GDCLASS(VoxelMesherDMC, Reference)
public: public:
enum Mode { enum MeshMode {
MODE_NORMAL, MESH_NORMAL,
MODE_WIREFRAME, MESH_WIREFRAME,
MODE_DEBUG_OCTREE, MESH_DEBUG_OCTREE,
MODE_DEBUG_DUAL_GRID MESH_DEBUG_DUAL_GRID
}; };
Ref<ArrayMesh> build_mesh(const VoxelBuffer &voxels, real_t geometric_error, Mode mode); enum OctreeMode {
OCTREE_BOTTOM_UP,
OCTREE_TOP_DOWN
};
VoxelMesherDMC();
void set_mesh_mode(MeshMode mode);
MeshMode get_mesh_mode() const;
void set_octree_mode(OctreeMode mode);
OctreeMode get_octree_mode() const;
void set_geometric_error(real_t geometric_error);
float get_geometric_error() const;
Ref<ArrayMesh> build_mesh(const VoxelBuffer &voxels);
Dictionary get_stats() const; Dictionary get_stats() const;
protected: protected:
static void _bind_methods(); static void _bind_methods();
Ref<ArrayMesh> _build_mesh_b(Ref<VoxelBuffer> voxels, real_t geometric_error, Mode mode); Ref<ArrayMesh> _build_mesh_b(Ref<VoxelBuffer> voxels);
private: private:
dmc::MeshBuilder _mesh_builder; dmc::MeshBuilder _mesh_builder;
dmc::DualGrid _dual_grid; dmc::DualGrid _dual_grid;
dmc::OctreeNodePool _octree_node_pool; dmc::OctreeNodePool _octree_node_pool;
real_t _geometric_error;
MeshMode _mesh_mode;
OctreeMode _octree_mode;
struct Stats { struct Stats {
real_t octree_build_time; real_t octree_build_time;
@ -96,6 +115,7 @@ private:
Stats _stats; Stats _stats;
}; };
VARIANT_ENUM_CAST(VoxelMesherDMC::Mode) VARIANT_ENUM_CAST(VoxelMesherDMC::OctreeMode)
VARIANT_ENUM_CAST(VoxelMesherDMC::MeshMode)
#endif // VOXEL_MESHER_DMC_H #endif // VOXEL_MESHER_DMC_H