From faefde721a93b4d34f3c538d75eec13b7b24fbb6 Mon Sep 17 00:00:00 2001 From: Marc Gilleron Date: Sun, 28 Apr 2019 20:48:59 +0100 Subject: [PATCH] Add base class to all meshers, gather common things in it --- SCsub | 1 + meshers/blocky/voxel_mesher_blocky.cpp | 85 +++++++------------ meshers/blocky/voxel_mesher_blocky.h | 12 +-- meshers/dmc/voxel_mesher_dmc.cpp | 48 ++++------- meshers/dmc/voxel_mesher_dmc.h | 12 +-- .../transvoxel/voxel_mesher_transvoxel.cpp | 41 +++------ meshers/transvoxel/voxel_mesher_transvoxel.h | 12 +-- meshers/voxel_mesher.cpp | 36 ++++++++ meshers/voxel_mesher.h | 24 ++++++ register_types.cpp | 1 + terrain/voxel_mesh_updater.cpp | 22 +++-- terrain/voxel_mesh_updater.h | 6 +- terrain/voxel_terrain.cpp | 23 ++--- terrain/voxel_terrain.h | 1 - 14 files changed, 167 insertions(+), 157 deletions(-) create mode 100644 meshers/voxel_mesher.cpp create mode 100644 meshers/voxel_mesher.h diff --git a/SCsub b/SCsub index 8eaba38..8f0c742 100644 --- a/SCsub +++ b/SCsub @@ -4,6 +4,7 @@ env.add_source_files(env.modules_sources, "*.cpp") env.add_source_files(env.modules_sources, "meshers/blocky/*.cpp") env.add_source_files(env.modules_sources, "meshers/transvoxel/*.cpp") env.add_source_files(env.modules_sources, "meshers/dmc/*.cpp") +env.add_source_files(env.modules_sources, "meshers/*.cpp") env.add_source_files(env.modules_sources, "providers/*.cpp") env.add_source_files(env.modules_sources, "util/*.cpp") env.add_source_files(env.modules_sources, "terrain/*.cpp") diff --git a/meshers/blocky/voxel_mesher_blocky.cpp b/meshers/blocky/voxel_mesher_blocky.cpp index f3228fb..964f69f 100644 --- a/meshers/blocky/voxel_mesher_blocky.cpp +++ b/meshers/blocky/voxel_mesher_blocky.cpp @@ -4,6 +4,8 @@ #include "../../voxel_library.h" #include +namespace { + template void raw_copy_to(PoolVector &to, const Vector &from) { to.resize(from.size()); @@ -11,26 +13,6 @@ void raw_copy_to(PoolVector &to, const Vector &from) { memcpy(w.ptr(), from.ptr(), from.size() * sizeof(T)); } -VoxelMesherBlocky::VoxelMesherBlocky() : - _baked_occlusion_darkness(0.8), - _bake_occlusion(true) {} - -void VoxelMesherBlocky::set_library(Ref library) { - _library = library; -} - -void VoxelMesherBlocky::set_occlusion_darkness(float darkness) { - _baked_occlusion_darkness = darkness; - if (_baked_occlusion_darkness < 0.0) - _baked_occlusion_darkness = 0.0; - else if (_baked_occlusion_darkness >= 1.0) - _baked_occlusion_darkness = 1.0; -} - -void VoxelMesherBlocky::set_occlusion_enabled(bool enable) { - _bake_occlusion = enable; -} - inline Color Color_greyscale(float c) { return Color(c, c, c); } @@ -51,36 +33,35 @@ inline bool is_transparent(const VoxelLibrary &lib, int voxel_id) { return true; } -Ref VoxelMesherBlocky::build_mesh(Ref buffer_ref, unsigned int channel, Array materials, Ref mesh) { - ERR_FAIL_COND_V(buffer_ref.is_null(), Ref()); +} // namespace - VoxelBuffer &buffer = **buffer_ref; - Array surfaces = build(buffer, channel, MINIMUM_PADDING); +VoxelMesherBlocky::VoxelMesherBlocky() : + _baked_occlusion_darkness(0.8), + _bake_occlusion(true) {} - if (mesh.is_null()) - mesh.instance(); - - int surface = mesh->get_surface_count(); - for (int i = 0; i < surfaces.size(); ++i) { - - Array arrays = surfaces[i]; - mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, arrays); - - Ref material = materials[i]; - if (material.is_valid()) { - mesh->surface_set_material(surface, material); - } - } - - return mesh; +void VoxelMesherBlocky::set_library(Ref library) { + _library = library; } -Array VoxelMesherBlocky::build(const VoxelBuffer &buffer, unsigned int channel, int padding) { +void VoxelMesherBlocky::set_occlusion_darkness(float darkness) { + _baked_occlusion_darkness = darkness; + if (_baked_occlusion_darkness < 0.0) + _baked_occlusion_darkness = 0.0; + else if (_baked_occlusion_darkness >= 1.0) + _baked_occlusion_darkness = 1.0; +} + +void VoxelMesherBlocky::set_occlusion_enabled(bool enable) { + _bake_occlusion = enable; +} + +void VoxelMesherBlocky::build(VoxelMesher::Output &output, const VoxelBuffer &buffer, int padding) { //uint64_t time_before = OS::get_singleton()->get_ticks_usec(); - ERR_FAIL_COND_V(_library.is_null(), Array()); - ERR_FAIL_COND_V(channel >= VoxelBuffer::MAX_CHANNELS, Array()); - ERR_FAIL_COND_V(padding < MINIMUM_PADDING, Array()); + ERR_FAIL_COND(_library.is_null()); + ERR_FAIL_COND(padding < MINIMUM_PADDING); + + const int channel = VoxelBuffer::CHANNEL_TYPE; const VoxelLibrary &library = **_library; @@ -118,7 +99,7 @@ Array VoxelMesherBlocky::build(const VoxelBuffer &buffer, unsigned int channel, // That means we can use raw pointers to voxel data inside instead of using the higher-level getters, // and then save a lot of time. - uint8_t *type_buffer = buffer.get_channel_raw(Voxel::CHANNEL_TYPE); + uint8_t *type_buffer = buffer.get_channel_raw(channel); // _ // | \ // /\ \\ @@ -132,7 +113,7 @@ Array VoxelMesherBlocky::build(const VoxelBuffer &buffer, unsigned int channel, // No data to read, the channel is probably uniform // TODO This is an invalid behavior IF sending a full block of uniformly opaque cubes, // however not likely for terrains because with neighbor padding, such a case means no face would be generated anyways - return Array(); + return; } //CRASH_COND(memarr_len(type_buffer) != buffer.get_volume() * sizeof(uint8_t)); @@ -367,8 +348,6 @@ Array VoxelMesherBlocky::build(const VoxelBuffer &buffer, unsigned int channel, // print_line(String("Made mesh v: ") + String::num(_arrays[0].positions.size()) // + String(", i: ") + String::num(_arrays[0].indices.size())); - Array surfaces; - // TODO We could return a single byte array and use Mesh::add_surface down the line? for (int i = 0; i < MAX_MATERIALS; ++i) { @@ -407,15 +386,19 @@ Array VoxelMesherBlocky::build(const VoxelBuffer &buffer, unsigned int channel, mesh_arrays[Mesh::ARRAY_INDEX] = indices; } - surfaces.append(mesh_arrays); + output.surfaces.push_back(mesh_arrays); } } + output.primitive_type = Mesh::PRIMITIVE_TRIANGLES; + //uint64_t time_commit = OS::get_singleton()->get_ticks_usec() - time_before; //print_line(String("P: {0}, M: {1}, C: {2}").format(varray(time_prep, time_meshing, time_commit))); +} - return surfaces; +int VoxelMesherBlocky::get_minimum_padding() const { + return MINIMUM_PADDING; } void VoxelMesherBlocky::_bind_methods() { @@ -429,8 +412,6 @@ void VoxelMesherBlocky::_bind_methods() { ClassDB::bind_method(D_METHOD("set_occlusion_darkness", "value"), &VoxelMesherBlocky::set_occlusion_darkness); ClassDB::bind_method(D_METHOD("get_occlusion_darkness"), &VoxelMesherBlocky::get_occlusion_darkness); - ClassDB::bind_method(D_METHOD("build_mesh", "voxel_buffer", "channel", "materials", "existing_mesh"), &VoxelMesherBlocky::build_mesh); - #ifdef VOXEL_PROFILING ClassDB::bind_method(D_METHOD("get_profiling_info"), &VoxelMesherBlocky::get_profiling_info); #endif diff --git a/meshers/blocky/voxel_mesher_blocky.h b/meshers/blocky/voxel_mesher_blocky.h index 4bbc007..3076581 100644 --- a/meshers/blocky/voxel_mesher_blocky.h +++ b/meshers/blocky/voxel_mesher_blocky.h @@ -3,14 +3,13 @@ #include "../../util/zprofiling.h" #include "../../voxel.h" -#include "../../voxel_buffer.h" #include "../../voxel_library.h" +#include "../voxel_mesher.h" #include #include -// TODO Should be renamed VoxelMesherBlocky or something like that -class VoxelMesherBlocky : public Reference { - GDCLASS(VoxelMesherBlocky, Reference) +class VoxelMesherBlocky : public VoxelMesher { + GDCLASS(VoxelMesherBlocky, VoxelMesher) public: static const unsigned int MAX_MATERIALS = 8; // Arbitrary. Tweak if needed. @@ -27,13 +26,14 @@ public: void set_occlusion_enabled(bool enable); bool get_occlusion_enabled() const { return _bake_occlusion; } - Array build(const VoxelBuffer &buffer_ref, unsigned int channel, int padding); - Ref build_mesh(Ref buffer_ref, unsigned int channel, Array materials, Ref mesh = Ref()); + void build(VoxelMesher::Output &output, const VoxelBuffer &voxels, int padding) override; + int get_minimum_padding() const override; protected: static void _bind_methods(); private: + // TODO Replace those with std::vector, it's faster struct Arrays { Vector positions; Vector normals; diff --git a/meshers/dmc/voxel_mesher_dmc.cpp b/meshers/dmc/voxel_mesher_dmc.cpp index 213bd6f..34a37bd 100644 --- a/meshers/dmc/voxel_mesher_dmc.cpp +++ b/meshers/dmc/voxel_mesher_dmc.cpp @@ -1317,7 +1317,7 @@ float VoxelMesherDMC::get_geometric_error() const { return _geometric_error; } -Array VoxelMesherDMC::build(const VoxelBuffer &voxels) { +void VoxelMesherDMC::build(VoxelMesher::Output &output, const VoxelBuffer &voxels, int padding) { // Requirements: // - Voxel data must be padded @@ -1328,17 +1328,18 @@ Array VoxelMesherDMC::build(const VoxelBuffer &voxels) { if (voxels.is_uniform(VoxelBuffer::CHANNEL_ISOLEVEL)) { // That won't produce any polygon - return Array(); + return; } - int padding = 2; + ERR_FAIL_COND(padding < MINIMUM_PADDING); + const Vector3i buffer_size = voxels.get_size(); // Taking previous power of two because the algorithm uses an integer cubic octree, and data should be padded int chunk_size = previous_power_of_2(MIN(MIN(buffer_size.x, buffer_size.y), buffer_size.z)); - ERR_FAIL_COND_V(voxels.get_size().x < chunk_size + padding * 2, Array()); - ERR_FAIL_COND_V(voxels.get_size().y < chunk_size + padding * 2, Array()); - ERR_FAIL_COND_V(voxels.get_size().z < chunk_size + padding * 2, Array()); + ERR_FAIL_COND(voxels.get_size().x < chunk_size + padding * 2); + ERR_FAIL_COND(voxels.get_size().y < chunk_size + padding * 2); + ERR_FAIL_COND(voxels.get_size().z < chunk_size + padding * 2); // Construct an intermediate to handle padding transparently dmc::VoxelAccess voxels_access(voxels, Vector3i(padding)); @@ -1427,33 +1428,17 @@ Array VoxelMesherDMC::build(const VoxelBuffer &voxels) { // TODO Marching squares skirts // surfaces[material][array_type], for now single material - Array surfaces; - surfaces.append(surface); - return surfaces; + output.surfaces.push_back(surface); + + if (_mesh_mode == MESH_NORMAL) { + output.primitive_type = Mesh::PRIMITIVE_TRIANGLES; + } else { + output.primitive_type = Mesh::PRIMITIVE_LINES; + } } -Ref VoxelMesherDMC::build_mesh(Ref voxels) { - - ERR_FAIL_COND_V(voxels.is_null(), Ref()); - - Array surfaces = build(**voxels); - - if (surfaces.empty()) { - return Ref(); - } - - Ref mesh; - mesh.instance(); - - for (int i = 0; i < surfaces.size(); ++i) { - if (_mesh_mode == MESH_NORMAL) { - mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, surfaces[i]); - } else { - mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, surfaces[i]); - } - } - - return mesh; +int VoxelMesherDMC::get_minimum_padding() const { + return MINIMUM_PADDING; } Dictionary VoxelMesherDMC::get_stats() const { @@ -1476,7 +1461,6 @@ 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("build_mesh", "voxel_buffer"), &VoxelMesherDMC::build_mesh); ClassDB::bind_method(D_METHOD("get_stats"), &VoxelMesherDMC::get_stats); BIND_ENUM_CONSTANT(MESH_NORMAL); diff --git a/meshers/dmc/voxel_mesher_dmc.h b/meshers/dmc/voxel_mesher_dmc.h index 9b12afe..0f4a3b6 100644 --- a/meshers/dmc/voxel_mesher_dmc.h +++ b/meshers/dmc/voxel_mesher_dmc.h @@ -1,7 +1,7 @@ #ifndef VOXEL_MESHER_DMC_H #define VOXEL_MESHER_DMC_H -#include "../../voxel_buffer.h" +#include "../voxel_mesher.h" #include "hermite_value.h" #include "mesh_builder.h" #include "object_pool.h" @@ -64,9 +64,11 @@ struct DualGrid { } // namespace dmc -class VoxelMesherDMC : public Reference { - GDCLASS(VoxelMesherDMC, Reference) +class VoxelMesherDMC : public VoxelMesher { + GDCLASS(VoxelMesherDMC, VoxelMesher) public: + static const int MINIMUM_PADDING = 2; + enum MeshMode { MESH_NORMAL, MESH_WIREFRAME, @@ -91,8 +93,8 @@ public: void set_geometric_error(real_t geometric_error); float get_geometric_error() const; - Array build(const VoxelBuffer &voxels); - Ref build_mesh(Ref voxels); + void build(VoxelMesher::Output &output, const VoxelBuffer &voxels, int padding) override; + int get_minimum_padding() const override; Dictionary get_stats() const; diff --git a/meshers/transvoxel/voxel_mesher_transvoxel.cpp b/meshers/transvoxel/voxel_mesher_transvoxel.cpp index a825111..1c57bdd 100644 --- a/meshers/transvoxel/voxel_mesher_transvoxel.cpp +++ b/meshers/transvoxel/voxel_mesher_transvoxel.cpp @@ -3,6 +3,8 @@ #include "transvoxel_tables.cpp" #include +namespace { + inline float tof(int8_t v) { return static_cast(v) / 256.f; } @@ -58,6 +60,8 @@ void copy_to(PoolVector &to, Vector &from) { } } +} // namespace + VoxelMesherTransvoxel::ReuseCell::ReuseCell() { case_index = 0; for (unsigned int i = 0; i < 4; ++i) { @@ -65,32 +69,15 @@ VoxelMesherTransvoxel::ReuseCell::ReuseCell() { } } -VoxelMesherTransvoxel::VoxelMesherTransvoxel() { +int VoxelMesherTransvoxel::get_minimum_padding() const { + return MINIMUM_PADDING; } -Ref VoxelMesherTransvoxel::build_mesh(Ref voxels_ref, unsigned int channel, Ref mesh) { +void VoxelMesherTransvoxel::build(VoxelMesher::Output &output, const VoxelBuffer &voxels, int padding) { - ERR_FAIL_COND_V(voxels_ref.is_null(), Ref()); + ERR_FAIL_COND(padding < MINIMUM_PADDING); - VoxelBuffer &buffer = **voxels_ref; - Array surfaces = build(buffer, channel); - - if (mesh.is_null()) - mesh.instance(); - - //int surface = mesh->get_surface_count(); - for (int i = 0; i < surfaces.size(); ++i) { - Array arrays = surfaces[i]; - mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, arrays); - //mesh->surface_set_material(surface, _materials[i]); - } - - return mesh; -} - -Array VoxelMesherTransvoxel::build(const VoxelBuffer &voxels, unsigned int channel) { - - ERR_FAIL_COND_V(channel >= VoxelBuffer::MAX_CHANNELS, Array()); + int channel = VoxelBuffer::CHANNEL_ISOLEVEL; // Initialize dynamic memory: // These vectors are re-used. @@ -109,7 +96,7 @@ Array VoxelMesherTransvoxel::build(const VoxelBuffer &voxels, unsigned int chann if (m_output_vertices.size() == 0) { // The mesh can be empty - return Array(); + return; } PoolVector vertices; @@ -128,10 +115,8 @@ Array VoxelMesherTransvoxel::build(const VoxelBuffer &voxels, unsigned int chann } arrays[Mesh::ARRAY_INDEX] = indices; - Array surfaces; - surfaces.append(arrays); - - return surfaces; + output.surfaces.push_back(arrays); + output.primitive_type = Mesh::PRIMITIVE_TRIANGLES; } void VoxelMesherTransvoxel::build_internal(const VoxelBuffer &voxels, unsigned int channel) { @@ -393,6 +378,4 @@ void VoxelMesherTransvoxel::emit_vertex(Vector3 primary, Vector3 normal) { } void VoxelMesherTransvoxel::_bind_methods() { - - ClassDB::bind_method(D_METHOD("build", "voxels", "channel", "existing_mesh"), &VoxelMesherTransvoxel::build_mesh, DEFVAL(Variant())); } diff --git a/meshers/transvoxel/voxel_mesher_transvoxel.h b/meshers/transvoxel/voxel_mesher_transvoxel.h index 3b8fe1d..1fa5ca7 100644 --- a/meshers/transvoxel/voxel_mesher_transvoxel.h +++ b/meshers/transvoxel/voxel_mesher_transvoxel.h @@ -1,17 +1,17 @@ #ifndef VOXEL_MESHER_SMOOTH_H #define VOXEL_MESHER_SMOOTH_H -#include "../../voxel_buffer.h" +#include "../voxel_mesher.h" #include -class VoxelMesherTransvoxel : public Reference { - GDCLASS(VoxelMesherTransvoxel, Reference) +class VoxelMesherTransvoxel : public VoxelMesher { + GDCLASS(VoxelMesherTransvoxel, VoxelMesher) public: - VoxelMesherTransvoxel(); + static const int MINIMUM_PADDING = 2; - Ref build_mesh(Ref voxels_ref, unsigned int channel, Ref mesh = Ref()); - Array build(const VoxelBuffer &voxels, unsigned int channel); + void build(VoxelMesher::Output &output, const VoxelBuffer &voxels, int padding) override; + int get_minimum_padding() const override; protected: static void _bind_methods(); diff --git a/meshers/voxel_mesher.cpp b/meshers/voxel_mesher.cpp new file mode 100644 index 0000000..6e197a2 --- /dev/null +++ b/meshers/voxel_mesher.cpp @@ -0,0 +1,36 @@ +#include "voxel_mesher.h" + +Ref VoxelMesher::build_mesh(Ref voxels) { + + ERR_FAIL_COND_V(voxels.is_null(), Ref()); + + Output output; + build(output, **voxels, get_minimum_padding()); + + if (output.surfaces.empty()) { + return Ref(); + } + + Ref mesh; + mesh.instance(); + + for (int i = 0; i < output.surfaces.size(); ++i) { + mesh->add_surface_from_arrays(output.primitive_type, output.surfaces[i]); + } + + return mesh; +} + +void VoxelMesher::build(Output &output, const VoxelBuffer &voxels, int padding) { +} + +int VoxelMesher::get_minimum_padding() const { + return 0; +} + +void VoxelMesher::_bind_methods() { + + // Shortcut if you want to generate a mesh directly from a fixed grid of voxels. + // Useful for testing the different meshers. + ClassDB::bind_method(D_METHOD("build_mesh", "voxel_buffer"), &VoxelMesher::build_mesh); +} diff --git a/meshers/voxel_mesher.h b/meshers/voxel_mesher.h new file mode 100644 index 0000000..bc2d61c --- /dev/null +++ b/meshers/voxel_mesher.h @@ -0,0 +1,24 @@ +#ifndef VOXEL_MESHER_H +#define VOXEL_MESHER_H + +#include "../voxel_buffer.h" +#include + +class VoxelMesher : public Reference { + GDCLASS(VoxelMesher, Reference) +public: + struct Output { + Vector surfaces; + Mesh::PrimitiveType primitive_type; + }; + + virtual void build(Output &output, const VoxelBuffer &voxels, int padding); + virtual int get_minimum_padding() const; + + Ref build_mesh(Ref voxels); + +protected: + static void _bind_methods(); +}; + +#endif // VOXEL_MESHER_H diff --git a/register_types.cpp b/register_types.cpp index 286f5a0..eeb210e 100644 --- a/register_types.cpp +++ b/register_types.cpp @@ -34,6 +34,7 @@ void register_voxel_types() { ClassDB::register_class(); // Meshers + ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_class(); diff --git a/terrain/voxel_mesh_updater.cpp b/terrain/voxel_mesh_updater.cpp index 9cfcebc..0d42f93 100644 --- a/terrain/voxel_mesh_updater.cpp +++ b/terrain/voxel_mesh_updater.cpp @@ -107,6 +107,17 @@ void VoxelMeshUpdater::pop(Output &output) { _shared_output.blocks.clear(); } +int VoxelMeshUpdater::get_required_padding() const { + + int padding = _blocky_mesher->get_minimum_padding(); + + if (_dmc_mesher.is_valid()) { + padding = max(padding, _dmc_mesher->get_minimum_padding()); + } + + return padding; +} + void VoxelMeshUpdater::_thread_func(void *p_self) { VoxelMeshUpdater *self = reinterpret_cast(p_self); self->thread_func(); @@ -181,17 +192,12 @@ void VoxelMeshUpdater::process_block(const InputBlock &block, OutputBlock &outpu CRASH_COND(block.voxels.is_null()); - int padding = 1; - if (_dmc_mesher.is_valid()) { - padding = 2; - } + int padding = get_required_padding(); - // Build cubic parts of the mesh - output.model_surfaces = _blocky_mesher->build(**block.voxels, Voxel::CHANNEL_TYPE, padding); + _blocky_mesher->build(output.blocky_surfaces, **block.voxels, padding); if (_dmc_mesher.is_valid()) { - // Build smooth parts of the mesh - output.smooth_surfaces = _dmc_mesher->build(**block.voxels); + _dmc_mesher->build(output.smooth_surfaces, **block.voxels, padding); } output.position = block.position; diff --git a/terrain/voxel_mesh_updater.h b/terrain/voxel_mesh_updater.h index 283b30e..d63240a 100644 --- a/terrain/voxel_mesh_updater.h +++ b/terrain/voxel_mesh_updater.h @@ -26,8 +26,8 @@ public: }; struct OutputBlock { - Array model_surfaces; - Array smooth_surfaces; + VoxelMesher::Output blocky_surfaces; + VoxelMesher::Output smooth_surfaces; Vector3i position; }; @@ -66,6 +66,8 @@ public: void push(const Input &input); void pop(Output &output); + int get_required_padding() const; + private: static void _thread_func(void *p_self); void thread_func(); diff --git a/terrain/voxel_terrain.cpp b/terrain/voxel_terrain.cpp index d44bb0d..920dac7 100644 --- a/terrain/voxel_terrain.cpp +++ b/terrain/voxel_terrain.cpp @@ -286,15 +286,6 @@ void VoxelTerrain::reset_updater() { _block_updater = memnew(VoxelMeshUpdater(_library, params)); } -int VoxelTerrain::get_block_padding() const { - // How many neighbor voxels we should pad for mesh updates to be seamless - // TODO Generalize padding retrieval, or split terrain systems because blocky and smooth are two different beasts - // - Blocky needs padding of 1 - // - Transvoxel needs padding of 2 - // - DMC needs padding of 2 - return _smooth_meshing_enabled ? 2 : 1; -} - inline int get_border_index(int x, int max) { return x == 0 ? 0 : x != max ? 1 : 2; } @@ -757,7 +748,7 @@ void VoxelTerrain::_process() { // TODO Make the buffer re-usable unsigned int block_size = _map->get_block_size(); - unsigned int padding = get_block_padding(); + unsigned int padding = _block_updater->get_required_padding(); nbuffer->create(block_size + 2 * padding, block_size + 2 * padding, block_size + 2 * padding); unsigned int channels_mask = (1 << VoxelBuffer::CHANNEL_TYPE) | (1 << VoxelBuffer::CHANNEL_ISOLEVEL); @@ -820,30 +811,30 @@ void VoxelTerrain::_process() { mesh.instance(); int surface_index = 0; - for (int i = 0; i < ob.model_surfaces.size(); ++i) { + for (int i = 0; i < ob.blocky_surfaces.surfaces.size(); ++i) { - Array surface = ob.model_surfaces[i]; + Array surface = ob.blocky_surfaces.surfaces[i]; if (surface.empty()) { continue; } CRASH_COND(surface.size() != Mesh::ARRAY_MAX); - mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, surface); + mesh->add_surface_from_arrays(ob.blocky_surfaces.primitive_type, surface); mesh->surface_set_material(surface_index, _materials[i]); ++surface_index; } - for (int i = 0; i < ob.smooth_surfaces.size(); ++i) { + for (int i = 0; i < ob.smooth_surfaces.surfaces.size(); ++i) { - Array surface = ob.smooth_surfaces[i]; + Array surface = ob.smooth_surfaces.surfaces[i]; if (surface.empty()) { continue; } CRASH_COND(surface.size() != Mesh::ARRAY_MAX); // TODO Problem here, the mesher could be configured to output wireframe! Need to output some MeshData struct instead - mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, surface); + mesh->add_surface_from_arrays(ob.smooth_surfaces.primitive_type, surface); mesh->surface_set_material(surface_index, _materials[i]); // No material supported yet ++surface_index; diff --git a/terrain/voxel_terrain.h b/terrain/voxel_terrain.h index 66eca2b..e864f34 100644 --- a/terrain/voxel_terrain.h +++ b/terrain/voxel_terrain.h @@ -98,7 +98,6 @@ private: void make_all_view_dirty_deferred(); void reset_updater(); - int get_block_padding() const; Spatial *get_viewer(NodePath path) const;