From 6e68267bd070e9affed8cf8dc24e9308d3154ada Mon Sep 17 00:00:00 2001 From: Relintai Date: Tue, 20 Oct 2020 16:29:39 +0200 Subject: [PATCH] My mesh utils module is now an optional dependency. The terrarin job will use it to simplify meshes over lod level 4. --- README.md | 3 +- SCsub | 3 ++ world/default/voxel_world_default.cpp | 18 +++++++- world/default/voxel_world_default.h | 4 ++ world/jobs/voxel_terrarin_job.cpp | 62 ++++++++++++++++----------- 5 files changed, 62 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index b57fbcd..84721c2 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,8 @@ check whether it works from time to time. `https://github.com/Relintai/thread_pool`: Threaded chunk generation. Without this Voxelman is single threaded! \ `https://github.com/Relintai/texture_packer`: You get access to [VoxelmanLibraryMerger](#voxelmanlibrarymerger). \ `https://github.com/Relintai/mesh_data_resource`: You get access to a bunch of properties, and methods that can manipulate meshes.\ -`https://github.com/Relintai/props`: You get access to a bunch of properties, and methods that can manipulate, and use props. +`https://github.com/Relintai/props`: You get access to a bunch of properties, and methods that can manipulate, and use props.\ +`https://github.com/Relintai/mesh_utils`: Lets you use lod levels higher than 4 by default. ## Pre-built binaries diff --git a/SCsub b/SCsub index bf099c9..79d30de 100644 --- a/SCsub +++ b/SCsub @@ -18,6 +18,9 @@ if os.path.isdir('../mesh_data_resource'): if os.path.isdir('../props'): module_env.Append(CPPDEFINES=['PROPS_PRESENT']) +if os.path.isdir('../mesh_utils'): + module_env.Append(CPPDEFINES=['MESH_UTILS_PRESENT']) + sources = [ "register_types.cpp", diff --git a/world/default/voxel_world_default.cpp b/world/default/voxel_world_default.cpp index d902a61..ac882df 100644 --- a/world/default/voxel_world_default.cpp +++ b/world/default/voxel_world_default.cpp @@ -54,6 +54,13 @@ void VoxelWorldDefault::set_lod_update_interval(const float value) { _lod_update_interval = value; } +int VoxelWorldDefault::get_num_lods() const { + return _num_lods; +} +void VoxelWorldDefault::set_num_lods(const int value) { + _num_lods = value; +} + void VoxelWorldDefault::update_lods() { call("_update_lods"); } @@ -134,6 +141,9 @@ void VoxelWorldDefault::_update_lods() { return; } + if (_num_lods <= 1) + return; + Vector3 ppos = get_player()->get_transform().origin; int ppx = int(ppos.x / get_chunk_size_x() / get_voxel_scale()); @@ -155,7 +165,7 @@ void VoxelWorldDefault::_update_lods() { mr -= _chunk_lod_falloff; //Todo 3 should be _num_lod, but it's NYI, because chunk can only handle 3 lod levels for now -> FQMS needs to be fixed - mr = CLAMP(mr, 0, 3); + mr = CLAMP(mr, 0, _num_lods - 1); if (c->get_current_lod_level() != mr) c->set_current_lod_level(mr); @@ -185,6 +195,7 @@ Ref VoxelWorldDefault::_create_chunk(int x, int y, int z, Refset_build_flags(_build_flags); + vcd->set_lod_num(_num_lods); } return VoxelWorld::_create_chunk(x, y, z, chunk); @@ -216,6 +227,7 @@ VoxelWorldDefault::VoxelWorldDefault() { _lod_update_timer = 0; _lod_update_interval = 0.5; _build_flags = VoxelChunkDefault::BUILD_FLAG_CREATE_COLLIDER | VoxelChunkDefault::BUILD_FLAG_CREATE_LODS; + _num_lods = 4; set_data_margin_start(1); set_data_margin_end(1); @@ -268,6 +280,10 @@ void VoxelWorldDefault::_bind_methods() { ClassDB::bind_method(D_METHOD("set_chunk_lod_falloff", "value"), &VoxelWorldDefault::set_chunk_lod_falloff); ADD_PROPERTY(PropertyInfo(Variant::INT, "chunk_lod_falloff"), "set_chunk_lod_falloff", "get_chunk_lod_falloff"); + ClassDB::bind_method(D_METHOD("get_num_lods"), &VoxelWorldDefault::get_num_lods); + ClassDB::bind_method(D_METHOD("set_num_lods", "value"), &VoxelWorldDefault::set_num_lods); + ADD_PROPERTY(PropertyInfo(Variant::INT, "num_lods"), "set_num_lods", "get_num_lods"); + BIND_VMETHOD(MethodInfo("_update_lods")); ClassDB::bind_method(D_METHOD("update_lods"), &VoxelWorldDefault::update_lods); ClassDB::bind_method(D_METHOD("_update_lods"), &VoxelWorldDefault::_update_lods); diff --git a/world/default/voxel_world_default.h b/world/default/voxel_world_default.h index e30c0a8..5b67736 100644 --- a/world/default/voxel_world_default.h +++ b/world/default/voxel_world_default.h @@ -38,6 +38,9 @@ public: int get_chunk_lod_falloff() const; void set_chunk_lod_falloff(const int value); + int get_num_lods() const; + void set_num_lods(const int value); + void update_lods(); PoolColorArray get_vertex_colors(const Transform &transform, const PoolVector3Array &vertices, const float base_light_value = 0.45, const float ao_strength = 0.2); @@ -60,6 +63,7 @@ private: float _lod_update_timer; float _lod_update_interval; int _chunk_lod_falloff; + int _num_lods; }; #endif diff --git a/world/jobs/voxel_terrarin_job.cpp b/world/jobs/voxel_terrarin_job.cpp index a12f9b0..5745165 100644 --- a/world/jobs/voxel_terrarin_job.cpp +++ b/world/jobs/voxel_terrarin_job.cpp @@ -30,6 +30,12 @@ SOFTWARE. #include "../default/voxel_chunk_default.h" +//#define MESH_UTILS_PRESENT 1 + +#ifdef MESH_UTILS_PRESENT +#include "../../../mesh_utils/fast_quadratic_mesh_simplifier.h" +#endif + Ref VoxelTerrarinJob::get_mesher(int index) const { ERR_FAIL_INDEX_V(index, _meshers.size(), Ref()); @@ -457,10 +463,14 @@ void VoxelTerrarinJob::phase_terrarin_mesh() { temp_mesh_arr = bake_mesh_array_uv(temp_mesh_arr, tex); temp_mesh_arr[VisualServer::ARRAY_TEX_UV] = Variant(); - VisualServer::get_singleton()->mesh_add_surface_from_arrays(chunk->get_mesh_rid_index(VoxelChunkDefault::MESH_INDEX_TERRARIN, VoxelChunkDefault::MESH_TYPE_INDEX_MESH, 3), VisualServer::PRIMITIVE_TRIANGLES, temp_mesh_arr); + VisualServer::get_singleton()->mesh_add_surface_from_arrays( + chunk->get_mesh_rid_index(VoxelChunkDefault::MESH_INDEX_TERRARIN, VoxelChunkDefault::MESH_TYPE_INDEX_MESH, 3), + VisualServer::PRIMITIVE_TRIANGLES, temp_mesh_arr); if (chunk->get_library()->get_material(3).is_valid()) - VisualServer::get_singleton()->mesh_surface_set_material(chunk->get_mesh_rid_index(VoxelChunkDefault::MESH_INDEX_TERRARIN, VoxelChunkDefault::MESH_TYPE_INDEX_MESH, 3), 0, chunk->get_library()->get_material(3)->get_rid()); + VisualServer::get_singleton()->mesh_surface_set_material( + chunk->get_mesh_rid_index(VoxelChunkDefault::MESH_INDEX_TERRARIN, VoxelChunkDefault::MESH_TYPE_INDEX_MESH, 3), 0, + chunk->get_library()->get_material(3)->get_rid()); } } @@ -469,34 +479,34 @@ void VoxelTerrarinJob::phase_terrarin_mesh() { } } - /* - if (should_do()) { - if (chunk->get_lod_num() > 4) { - Ref fqms; - fqms.instance(); - fqms->initialize(temp_mesh_arr); +#ifdef MESH_UTILS_PRESENT + if (should_do()) { + if (chunk->get_lod_num() > 4) { + Ref fqms; + fqms.instance(); + fqms->set_preserve_border_edges(true); + fqms->initialize(temp_mesh_arr); - Array arr_merged_simplified; + for (int i = 4; i < chunk->get_lod_num(); ++i) { + fqms->simplify_mesh(temp_mesh_arr.size() * 0.8, 7); + temp_mesh_arr = fqms->get_arrays(); - for (int i = 4; i < _lod_num; ++i) { - fqms->simplify_mesh(arr_merged_simplified[0].size() * 0.8, 7); - arr_merged_simplified = fqms->get_arrays(); + VisualServer::get_singleton()->mesh_add_surface_from_arrays( + chunk->get_mesh_rid_index(VoxelChunkDefault::MESH_INDEX_TERRARIN, VoxelChunkDefault::MESH_TYPE_INDEX_MESH, i), + VisualServer::PRIMITIVE_TRIANGLES, temp_mesh_arr); - if (arr_merged_simplified[0].size() == 0) - break; - - VisualServer::get_singleton()->mesh_add_surface_from_arrays(get_mesh_rid_index(MESH_INDEX_TERRARIN, MESH_TYPE_INDEX_MESH, i), VisualServer::PRIMITIVE_TRIANGLES, arr_merged_simplified); - - if (get_library()->get_material(i).is_valid()) - VisualServer::get_singleton()->mesh_surface_set_material(get_mesh_rid_index(MESH_INDEX_TERRARIN, MESH_TYPE_INDEX_MESH, i), 0, get_library()->get_material(i)->get_rid()); - } - } - - if (should_return()) { - return; - } + if (chunk->get_library()->get_material(i).is_valid()) + VisualServer::get_singleton()->mesh_surface_set_material( + chunk->get_mesh_rid_index(VoxelChunkDefault::MESH_INDEX_TERRARIN, VoxelChunkDefault::MESH_TYPE_INDEX_MESH, i), 0, + chunk->get_library()->get_material(i)->get_rid()); } - */ + } + + if (should_return()) { + return; + } + } +#endif } }