Make marching cubes skirts an option in VoxelMesherDMC, also use more C++11 initializers

This commit is contained in:
Marc Gilleron 2019-05-05 17:00:42 +01:00
parent 1f219e68eb
commit 46784e4700
3 changed files with 46 additions and 17 deletions

View File

@ -1426,11 +1426,6 @@ void polygonize_volume_directly(const VoxelBuffer &voxels, Vector3i min, Vector3
#define BUILD_OCTREE_BOTTOM_UP
VoxelMesherDMC::VoxelMesherDMC() {
_geometric_error = 0.1;
_mesh_mode = MESH_NORMAL;
_octree_mode = OCTREE_BOTTOM_UP;
_stats = { 0 };
}
void VoxelMesherDMC::set_mesh_mode(MeshMode mode) {
@ -1457,6 +1452,14 @@ float VoxelMesherDMC::get_geometric_error() const {
return _geometric_error;
}
void VoxelMesherDMC::set_seam_mode(SeamMode mode) {
_seam_mode = mode;
}
VoxelMesherDMC::SeamMode VoxelMesherDMC::get_seam_mode() const {
return _seam_mode;
}
void VoxelMesherDMC::build(VoxelMesher::Output &output, const VoxelBuffer &voxels, int padding) {
// Requirements:
@ -1481,7 +1484,15 @@ void VoxelMesherDMC::build(VoxelMesher::Output &output, const VoxelBuffer &voxel
ERR_FAIL_COND(voxels.get_size().z < chunk_size + padding * 2);
// TODO Option for this in case LOD is not used
bool skirts_enabled = true;
bool skirts_enabled = _seam_mode == SEAM_MARCHING_SQUARE_SKIRTS;
// Marching square skirts are a cheap way to hide LOD cracks,
// however they might still be visible because of shadow mapping, and cause potential issues when used for physics.
// Maybe a shader with a `light()` function can prevent shadows from being applied to these,
// but in longer term, proper seams remain a better solution.
// Unfortunately, such seams require the ability to quickly swap index buffers of the mesh using OpenGL/Vulkan,
// which is not possible with current Godot's VisualServer without forking the whole lot (dang!),
// and we are forced to at least re-upload the mesh entirely or have 16 versions of it just swapping seams...
// So we can't improve this further until Godot's API gives us that possibility, or other approaches like skirts need to be taken.
// Construct an intermediate to handle padding transparently
dmc::VoxelAccess voxels_access(voxels, Vector3i(padding));
@ -1601,6 +1612,9 @@ void VoxelMesherDMC::_bind_methods() {
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("set_seam_mode", "mode"), &VoxelMesherDMC::set_seam_mode);
ClassDB::bind_method(D_METHOD("get_seam_mode"), &VoxelMesherDMC::get_seam_mode);
ClassDB::bind_method(D_METHOD("get_stats"), &VoxelMesherDMC::get_stats);
BIND_ENUM_CONSTANT(MESH_NORMAL);
@ -1611,4 +1625,7 @@ void VoxelMesherDMC::_bind_methods() {
BIND_ENUM_CONSTANT(OCTREE_BOTTOM_UP);
BIND_ENUM_CONSTANT(OCTREE_TOP_DOWN);
BIND_ENUM_CONSTANT(OCTREE_NONE);
BIND_ENUM_CONSTANT(SEAM_NONE);
BIND_ENUM_CONSTANT(SEAM_MARCHING_SQUARE_SKIRTS);
}

View File

@ -46,10 +46,7 @@ struct OctreeNode {
struct DualCell {
Vector3 corners[8];
HermiteValue values[8];
bool has_values;
DualCell() :
has_values(false) {}
bool has_values = false;
inline void set_corner(int i, Vector3 vertex, HermiteValue value) {
CRASH_COND(i < 0 || i >= 8);
@ -64,6 +61,7 @@ struct DualGrid {
} // namespace dmc
// Mesher extending Marching Cubes using a dual grid.
class VoxelMesherDMC : public VoxelMesher {
GDCLASS(VoxelMesherDMC, VoxelMesher)
public:
@ -76,12 +74,20 @@ public:
MESH_DEBUG_DUAL_GRID
};
// TODO Rename SimplifyMode because octree isn't the only way
enum OctreeMode {
OCTREE_BOTTOM_UP,
OCTREE_TOP_DOWN,
OCTREE_NONE
};
enum SeamMode {
SEAM_NONE, // No seam management
SEAM_MARCHING_SQUARE_SKIRTS, // Marching square skirts
// SEAM_OVERLAP // Polygonize extra voxels with lower isolevel
// SEAM_JUNCTION_TRIANGLES // Extra triangles for alternate borders, requires index buffer switching
};
VoxelMesherDMC();
void set_mesh_mode(MeshMode mode);
@ -93,6 +99,9 @@ public:
void set_geometric_error(real_t geometric_error);
float get_geometric_error() const;
void set_seam_mode(SeamMode mode);
SeamMode get_seam_mode() const;
void build(VoxelMesher::Output &output, const VoxelBuffer &voxels, int padding) override;
int get_minimum_padding() const override;
@ -105,15 +114,16 @@ private:
dmc::MeshBuilder _mesh_builder;
dmc::DualGrid _dual_grid;
dmc::OctreeNodePool _octree_node_pool;
real_t _geometric_error;
MeshMode _mesh_mode;
OctreeMode _octree_mode;
real_t _geometric_error = 0.1;
MeshMode _mesh_mode = MESH_NORMAL;
OctreeMode _octree_mode = OCTREE_BOTTOM_UP;
SeamMode _seam_mode = SEAM_NONE;
struct Stats {
real_t octree_build_time;
real_t dualgrid_derivation_time;
real_t meshing_time;
real_t commit_time;
real_t octree_build_time = 0;
real_t dualgrid_derivation_time = 0;
real_t meshing_time = 0;
real_t commit_time = 0;
};
Stats _stats;
@ -121,5 +131,6 @@ private:
VARIANT_ENUM_CAST(VoxelMesherDMC::OctreeMode)
VARIANT_ENUM_CAST(VoxelMesherDMC::MeshMode)
VARIANT_ENUM_CAST(VoxelMesherDMC::SeamMode)
#endif // VOXEL_MESHER_DMC_H

View File

@ -16,6 +16,7 @@ VoxelMeshUpdater::VoxelMeshUpdater(Ref<VoxelLibrary> library, MeshingParams para
_dmc_mesher.instance();
_dmc_mesher->set_geometric_error(0.05);
_dmc_mesher->set_octree_mode(VoxelMesherDMC::OCTREE_NONE);
_dmc_mesher->set_seam_mode(VoxelMesherDMC::SEAM_MARCHING_SQUARE_SKIRTS);
}
_input_mutex = Mutex::create();