diff --git a/modules/terrain_editor/terrain_chunk.cpp b/modules/terrain_editor/terrain_chunk.cpp index 83d48ad9..49806a51 100644 --- a/modules/terrain_editor/terrain_chunk.cpp +++ b/modules/terrain_editor/terrain_chunk.cpp @@ -2,7 +2,9 @@ #include "core/config/engine.h" #include "macros.h" #include "scene/3d/camera_3d.h" +#include "scene/3d/physics/static_body_3d.h" #include "scene/main/viewport.h" +#include "scene/resources/mesh.h" #include "terrain_editor/terrain_mesh_generator.h" void TerrainChunk::_bind_methods() { @@ -17,15 +19,19 @@ void TerrainChunk::ready() { print_error(vformat("Chunk %s ready without generator.", get_path())); return; } - process_lod(); on_terrain_changed(); + process_lod(); } void TerrainChunk::on_terrain_changed() { if (this->generator) { Vector3 const position{ get_global_position() }; - this->meshes.resize_zeroed(5); + this->meshes.resize_zeroed(3); size_t lod{ 0 }; + if (this->collisions) { + this->collisions->queue_free(); + this->collisions = nullptr; + } for (MeshStatus &status : this->meshes) { if (!status.mesh.is_valid()) { status.mesh.instantiate(); @@ -39,7 +45,23 @@ void TerrainChunk::on_terrain_changed() { } void TerrainChunk::lod_generated(size_t lod) { - this->meshes.set(lod, MeshStatus{ this->meshes[lod].mesh, false }); + //if (this->collisions && lod <= this->collisions_lod && (lod == 0 || lod == (this->meshes.size() - 1))) { +#if 0 + if (this->collisions && lod == this->meshes.size() - 1) { + this->collisions->queue_free(); + this->collisions = nullptr; + } + if (!this->collisions) { + this->set_mesh(this->meshes[lod].mesh); + //static Ref settings{}; + if ((this->collisions = create_multiple_convex_collisions_node())) { + add_child(this->collisions); + } + this->collisions_lod = lod; + } +#endif + this->meshes.set(lod, { this->meshes[lod].mesh, false }); + process_lod(); } void TerrainChunk::process_lod() { @@ -47,10 +69,11 @@ void TerrainChunk::process_lod() { if (is_ready() && this->meshes.size() > 0) { Vector3 position{ get_global_position() }; Vector3 camera{ get_viewport()->get_camera_3d()->get_global_position() }; - position.y = camera.y = 0; - float distance{ camera.distance_to(position) }; - size_t lod{ size_t(Math::floor(distance / (this->lod4_distance / 5.f))) }; - result = lod < 5 ? lod : 4; + Vector3 diff{ (position - camera).abs() }; + float distance{ (diff.x > diff.z ? diff.z : diff.x) - this->size }; + distance = distance > 0.f ? distance : 0.f; + size_t lod{ size_t(Math::floor(distance / (this->lod_end_distance / this->meshes.size()))) }; + result = lod < this->meshes.size() ? lod : (this->meshes.size() - 1); while (this->meshes[result].dirty && result < (this->meshes.size() - 1)) { result++; } diff --git a/modules/terrain_editor/terrain_chunk.h b/modules/terrain_editor/terrain_chunk.h index 3359d385..5fdfea5f 100644 --- a/modules/terrain_editor/terrain_chunk.h +++ b/modules/terrain_editor/terrain_chunk.h @@ -1,6 +1,5 @@ #pragma once -#include "core/templates/pair.h" #include "core/templates/vector.h" #include "scene/3d/mesh_instance_3d.h" class TerrainMeshGenerator; @@ -27,9 +26,11 @@ public: int get_lod0_detail() const; private: + Node *collisions{ nullptr }; + size_t collisions_lod{ 0 }; Vector meshes{}; - TerrainMeshGenerator *generator{ nullptr }; int lod0_detail{ 200 }; - float lod4_distance{ 1500 }; + float lod_end_distance{ 1000 }; float size{ 200 }; + TerrainMeshGenerator *generator{ nullptr }; }; diff --git a/project/objects/terrain_chunk.tscn b/project/objects/terrain_chunk.tscn index 845515a2..20e6707d 100644 --- a/project/objects/terrain_chunk.tscn +++ b/project/objects/terrain_chunk.tscn @@ -4,3 +4,5 @@ [node name="TerrainChunk" type="TerrainChunk"] material_override = ExtResource("1_6vjd7") +size = 30.0 +lod0_detail = 30