diff --git a/modules/terrain_editor/terrain_mesh_generator.cpp b/modules/terrain_editor/terrain_mesh_generator.cpp index 813405b1..aeeed8b7 100644 --- a/modules/terrain_editor/terrain_mesh_generator.cpp +++ b/modules/terrain_editor/terrain_mesh_generator.cpp @@ -4,6 +4,7 @@ #include "core/object/class_db.h" #include "core/object/object.h" #include "core/templates/local_vector.h" +#include "scene/resources/packed_scene.h" #include "scene/resources/surface_tool.h" #include "terrain_editor/macros.h" #include "terrain_editor/terrain_chunk.h" @@ -18,16 +19,15 @@ void TerrainMeshGenerator::_bind_methods() { BIND_HPROPERTY(Variant::OBJECT, vertex_color_gradient, PROPERTY_HINT_RESOURCE_TYPE, "Gradient"); BIND_PROPERTY(Variant::FLOAT, color_gradient_start_height); BIND_PROPERTY(Variant::FLOAT, color_gradient_end_height); - BIND_PROPERTY(Variant::FLOAT, chunk_size); - BIND_PROPERTY(Variant::INT, lod1_detail); BIND_PROPERTY(Variant::INT, chunk_count); - BIND_HPROPERTY(Variant::OBJECT, material, PROPERTY_HINT_RESOURCE_TYPE, "Material"); + BIND_HPROPERTY(Variant::OBJECT, chunk_scene, PROPERTY_HINT_RESOURCE_TYPE, "PackedScene"); ADD_SIGNAL(MethodInfo(sig_primitives_changed)); ADD_SIGNAL(MethodInfo(sig_primitive_list_changed, PropertyInfo(Variant::ARRAY, "array", PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:TerrainPrimitive", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE)))); ClassDB::bind_method(D_METHOD("generate_grid", "area", "out_mesh", "side_points"), &self_type::generate_grid); } void TerrainMeshGenerator::ready() { + this->thread.instantiate(); if (this->chunks.is_empty()) { rebuild_chunks(); } @@ -52,15 +52,19 @@ void TerrainMeshGenerator::rebuild_chunks() { chunk->queue_free(); } this->chunks.clear(); - Vector3 origin{ -Vector3{ (float)chunks_per_side, 0, (float)chunks_per_side } * this->chunk_size / 2 }; + if (!this->chunk_scene.is_valid()) { + return; + } for (size_t chunk_y{ 0 }; chunk_y < this->chunks_per_side; ++chunk_y) { for (size_t chunk_x{ 0 }; chunk_x < this->chunks_per_side; ++chunk_x) { - TerrainChunk *chunk{ memnew(TerrainChunk) }; - chunk->set_size(this->chunk_size); - chunk->set_lod1_detail(this->lod1_detail); - chunk->set_material_override(this->material); + TerrainChunk *chunk{ cast_to(this->chunk_scene->instantiate()) }; + if (!chunk) { + print_error("Attempt to rebuild chunks when no chunk scene is set"); + return; + } + Vector3 const origin{ -Vector3{ (float)chunks_per_side, 0, (float)chunks_per_side } * chunk->get_size() / 2 }; this->chunks.push_back(chunk); - Vector3 offset{ Vector3{ (float)chunk_x, 0.f, (float)chunk_y } * this->chunk_size }; + Vector3 offset{ Vector3{ (float)chunk_x, 0.f, (float)chunk_y } * chunk->get_size() }; chunk->set_position(origin + offset); add_child(chunk); } @@ -194,23 +198,6 @@ float TerrainMeshGenerator::get_color_gradient_end_height() const { return this->color_gradient_end_height; } -void TerrainMeshGenerator::set_chunk_size(float size) { - this->chunk_size = size; - rebuild_chunks(); -} -float TerrainMeshGenerator::get_chunk_size() const { - return this->chunk_size; -} -void TerrainMeshGenerator::set_lod1_detail(int detail) { - if (detail != this->lod1_detail) { - this->lod1_detail = detail; - rebuild_chunks(); - } -} -int TerrainMeshGenerator::get_lod1_detail() const { - return this->lod1_detail; -} - void TerrainMeshGenerator::set_chunk_count(int num) { if (num != this->chunks_per_side) { this->chunks_per_side = num; @@ -222,13 +209,12 @@ int TerrainMeshGenerator::get_chunk_count() const { return this->chunks_per_side; } -void TerrainMeshGenerator::set_material(Ref material) { - this->material = material; - for (TerrainChunk *chunk : this->chunks) { - chunk->set_material_override(material); +void TerrainMeshGenerator::set_chunk_scene(Ref scene) { + if (!scene.is_valid() || scene->get_state()->get_node_type(0) == TerrainChunk::get_class_static()) { + this->chunk_scene = scene; } } -Ref TerrainMeshGenerator::get_material() const { - return this->material; +Ref TerrainMeshGenerator::get_chunk_scene() const { + return this->chunk_scene; } diff --git a/modules/terrain_editor/terrain_mesh_generator.h b/modules/terrain_editor/terrain_mesh_generator.h index 691f84ed..08c6f709 100644 --- a/modules/terrain_editor/terrain_mesh_generator.h +++ b/modules/terrain_editor/terrain_mesh_generator.h @@ -2,6 +2,9 @@ #include "core/math/color.h" #include "core/object/object.h" +#include "core/os/semaphore.h" +#include "core/os/thread.h" +#include "core/templates/hash_map.h" #include "core/variant/callable.h" #include "scene/main/node.h" #include "scene/resources/gradient.h" @@ -33,14 +36,10 @@ public: float get_color_gradient_start_height() const; void set_color_gradient_end_height(float value); float get_color_gradient_end_height() const; - void set_chunk_size(float size); - float get_chunk_size() const; - void set_lod1_detail(int detail); - int get_lod1_detail() const; void set_chunk_count(int num); int get_chunk_count() const; - void set_material(Ref material); - Ref get_material() const; + void set_chunk_scene(Ref scene); + Ref get_chunk_scene() const; private: Vector> primitives{}; @@ -48,11 +47,9 @@ private: Ref vertex_color_gradient{}; float color_gradient_start_height{ 0.f }; float color_gradient_end_height{ 10.f }; - float chunk_size{ 100.f }; - int lod1_detail{ 25 }; int chunks_per_side{ 10 }; + Ref chunk_scene{}; Vector chunks{}; - Ref material{}; private: Callable generation_changed{ callable_mp(this, &self_type::on_configuration_changed) }; diff --git a/project/objects/terrain_chunk.tscn b/project/objects/terrain_chunk.tscn new file mode 100644 index 00000000..845515a2 --- /dev/null +++ b/project/objects/terrain_chunk.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3 uid="uid://wkqhvjnxs2mx"] + +[ext_resource type="Material" uid="uid://8j7uyk0vnllg" path="res://assets/materials/terrain_material.tres" id="1_6vjd7"] + +[node name="TerrainChunk" type="TerrainChunk"] +material_override = ExtResource("1_6vjd7") diff --git a/project/scenes/editor.tscn b/project/scenes/editor.tscn index 162a03e1..00a1dfb4 100644 --- a/project/scenes/editor.tscn +++ b/project/scenes/editor.tscn @@ -1,7 +1,6 @@ -[gd_scene load_steps=13 format=3 uid="uid://xm383pc5pcnn"] +[gd_scene load_steps=12 format=3 uid="uid://xm383pc5pcnn"] [ext_resource type="PackedScene" uid="uid://cnux2fqne284i" path="res://objects/primitive_nodes/point_primitive_node.tscn" id="1_b1cmn"] -[ext_resource type="Material" uid="uid://8j7uyk0vnllg" path="res://assets/materials/terrain_material.tres" id="1_pxqd5"] [sub_resource type="PointPrimitive" id="PointPrimitive_pxqd5"] slope = -0.585 @@ -107,10 +106,7 @@ func _unhandled_input(event: InputEvent) -> void: primitives = [SubResource("PointPrimitive_pxqd5"), SubResource("NoisePrimitive_ba0ut"), SubResource("NoisePrimitive_pxqd5")] vertex_color_gradient = SubResource("Gradient_b1cmn") color_gradient_end_height = 200.0 -chunk_size = 500.0 -lod1_detail = 30 chunk_count = 5 -material = ExtResource("1_pxqd5") point_primitive_object = ExtResource("1_b1cmn") [node name="WorldEnvironment" type="WorldEnvironment" parent="."]