diff --git a/assets/icons/kenney_icons.svg b/assets/icons/kenney_icons.svg new file mode 100644 index 00000000..af02f854 --- /dev/null +++ b/assets/icons/kenney_icons.svg @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + diff --git a/modules/terrain_editor/edit_history.cpp b/modules/terrain_editor/edit_history.cpp index d2a9de99..c9b9b434 100644 --- a/modules/terrain_editor/edit_history.cpp +++ b/modules/terrain_editor/edit_history.cpp @@ -30,3 +30,8 @@ void EditHistory::redo() { this->undo_count--; } } + +void EditHistory::clear_history() { + this->history.clear(); + this->undo_count = 0; +} diff --git a/modules/terrain_editor/edit_history.h b/modules/terrain_editor/edit_history.h index f35b0c28..da45052e 100644 --- a/modules/terrain_editor/edit_history.h +++ b/modules/terrain_editor/edit_history.h @@ -20,6 +20,7 @@ public: void push_action(Callable do_action, Callable undo_action); void undo(); void redo(); + void clear_history(); private: size_t undo_count{ 0 }; diff --git a/modules/terrain_editor/terrain_mesh_editor.cpp b/modules/terrain_editor/terrain_mesh_editor.cpp index cb743ac5..67679ade 100644 --- a/modules/terrain_editor/terrain_mesh_editor.cpp +++ b/modules/terrain_editor/terrain_mesh_editor.cpp @@ -40,13 +40,15 @@ String const TerrainMeshEditor::sig_selection_changed{ "selection_changed" }; void TerrainMeshEditor::_bind_methods() { BIND_HPROPERTY(Variant::OBJECT, point_primitive_object, PROPERTY_HINT_RESOURCE_TYPE, "PackedScene"); ClassDB::bind_method(D_METHOD("save_data"), &self_type::save_data); + ClassDB::bind_method(D_METHOD("save_data_as"), &self_type::save_data_as); BIND_HPROPERTY(Variant::OBJECT, current_selected, PROPERTY_HINT_RESOURCE_TYPE, "TerrainPrimitive"); + BIND_HPROPERTY(Variant::OBJECT, new_file_data, PROPERTY_HINT_RESOURCE_TYPE, "SaveData"); ADD_SIGNAL(MethodInfo(sig_selection_changed, PropertyInfo(Variant::OBJECT, "new_selection", PROPERTY_HINT_RESOURCE_TYPE, "TerrainPrimitive"))); } void TerrainMeshEditor::ready() { connect(sig_primitive_list_changed, callable_mp(this, &self_type::on_primitive_list_changed)); - on_primitive_list_changed(get_primitives()); + load_new(); if (FileDialog * dialog{ memnew(FileDialog) }) { this->file_dialog = dialog; add_child(dialog); @@ -96,6 +98,13 @@ void TerrainMeshEditor::on_save_file_selected(String path) { } } +void TerrainMeshEditor::load_new() { + this->data = this->new_file_data->duplicate(true); + this->set_primitives(this->data->get_primitives().duplicate(true)); + this->data->set_save_path(""); + EditHistory::get_singleton()->clear_history(); +} + void TerrainMeshEditor::_notification(int what) { if (Engine::get_singleton()->is_editor_hint()) { return; @@ -121,9 +130,7 @@ void TerrainMeshEditor::unhandled_input(Ref const &event) { case Key::S: if (key->is_shift_pressed() && key->is_command_or_control_pressed()) { get_viewport()->set_input_as_handled(); - this->file_dialog->set_file_mode(FileDialog::FILE_MODE_SAVE_FILE); - this->file_dialog->set_ok_button_text("Save"); - this->file_dialog->popup_file_dialog(); + save_data_as(); } else if (key->is_command_or_control_pressed()) { get_viewport()->set_input_as_handled(); save_data(); @@ -146,6 +153,12 @@ void TerrainMeshEditor::unhandled_input(Ref const &event) { EditHistory::get_singleton()->undo(); } break; + case Key::N: + if (key->is_command_or_control_pressed()) { + get_viewport()->set_input_as_handled(); + load_new(); + } + break; } } @@ -155,15 +168,27 @@ void TerrainMeshEditor::save_data() { return; } if (this->data->get_save_path().is_empty()) { - this->file_dialog->set_file_mode(FileDialog::FILE_MODE_SAVE_FILE); - this->file_dialog->set_ok_button_text("Save"); - this->file_dialog->popup_file_dialog(); + save_data_as(); } else { this->data->set_primitives(get_primitives()); this->data->write_to_file(); } } +void TerrainMeshEditor::save_data_as() { + this->file_dialog->set_file_mode(FileDialog::FILE_MODE_SAVE_FILE); + this->file_dialog->set_ok_button_text("Save"); + this->file_dialog->popup_file_dialog(); +} + +void TerrainMeshEditor::set_new_file_data(Ref data) { + this->new_file_data = data; +} + +Ref TerrainMeshEditor::get_new_file_data() const { + return this->new_file_data; +} + void TerrainMeshEditor::set_current_selected(Ref primitive) { this->current_selected = primitive; emit_signal(sig_selection_changed, primitive); diff --git a/modules/terrain_editor/terrain_mesh_editor.h b/modules/terrain_editor/terrain_mesh_editor.h index 19f6b200..ab5ae5b1 100644 --- a/modules/terrain_editor/terrain_mesh_editor.h +++ b/modules/terrain_editor/terrain_mesh_editor.h @@ -28,6 +28,7 @@ class TerrainMeshEditor : public TerrainMeshGenerator { void on_primitive_list_changed(Array primitives); void on_primitive_node_removed(); void on_save_file_selected(String path); + void load_new(); protected: void _notification(int what); @@ -35,12 +36,16 @@ protected: public: void save_data(); + void save_data_as(); + void set_new_file_data(Ref data); + Ref get_new_file_data() const; void set_current_selected(Ref); Ref get_current_selected() const; void set_point_primitive_object(Ref scene); Ref get_point_primitive_object() const; private: + Ref new_file_data{}; Ref data{ memnew(SaveData) }; Ref current_selected{}; FileDialog *file_dialog{}; diff --git a/project/assets/icons/delete.svg b/project/assets/icons/delete.svg index 49dca652..8710e663 100644 --- a/project/assets/icons/delete.svg +++ b/project/assets/icons/delete.svg @@ -12,19 +12,11 @@ + id="layer1" + transform="translate(-26.933333)"> - + d="M 30.406741,3.7096566 C 30.512731,3.4976918 30.6717,3.3652103 30.883665,3.3122201 l 1.927568,-0.5166676 -0.07949,-0.357693 C 32.665497,2.2126442 32.685371,2.0073047 32.79136,1.821833 32.89735,1.6231146 33.062941,1.4972584 33.288157,1.4442682 l 2.305132,-0.61602676 c 0.198719,-0.0529904 0.397436,-0.0198716 0.596155,0.0993594 0.185471,0.092734 0.304702,0.24508716 0.357693,0.45705196 l 0.09936,0.3775648 1.927567,-0.4967957 c 0.198719,-0.066241 0.404062,-0.039743 0.616027,0.079488 0.185471,0.1059837 0.304702,0.2649589 0.357692,0.4769239 l 0.59616,2.2653882 -9.200656,2.4641067 -0.596155,-2.2455166 c -0.05299,-0.2252155 -0.03311,-0.4239337 0.05962,-0.5961549 m 0.53654,11.6250188 V 7.3462013 h 9.538478 v 7.9884747 c 0,0.225215 -0.07949,0.417308 -0.238462,0.576284 -0.158974,0.14572 -0.344447,0.218588 -0.556411,0.218588 h -7.948731 c -0.225216,0 -0.417309,-0.07287 -0.576283,-0.218588 -0.145721,-0.158976 -0.218591,-0.351069 -0.218591,-0.576284" + style="fill:#ffffff;stroke:none;stroke-width:0.264583" + id="path1-0" /> diff --git a/project/assets/icons/redo.svg b/project/assets/icons/redo.svg new file mode 100644 index 00000000..c4349f85 --- /dev/null +++ b/project/assets/icons/redo.svg @@ -0,0 +1,22 @@ + + + + + + + + + diff --git a/project/assets/icons/redo.svg.import b/project/assets/icons/redo.svg.import new file mode 100644 index 00000000..2fefd852 --- /dev/null +++ b/project/assets/icons/redo.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://fpnyca6s1f1y" +path="res://.godot/imported/redo.svg-3f978da4a242cfabee4c9d3cfb8b5e18.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/icons/redo.svg" +dest_files=["res://.godot/imported/redo.svg-3f978da4a242cfabee4c9d3cfb8b5e18.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/project/assets/icons/save.svg b/project/assets/icons/save.svg new file mode 100644 index 00000000..46e10518 --- /dev/null +++ b/project/assets/icons/save.svg @@ -0,0 +1,21 @@ + + + + + + + + + diff --git a/project/assets/icons/save.svg.import b/project/assets/icons/save.svg.import new file mode 100644 index 00000000..2efbbbc5 --- /dev/null +++ b/project/assets/icons/save.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cwl3no6dbtjrf" +path="res://.godot/imported/save.svg-4436a386e8aa6786c3b87b76d11469d6.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/icons/save.svg" +dest_files=["res://.godot/imported/save.svg-4436a386e8aa6786c3b87b76d11469d6.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/project/assets/icons/undo.svg b/project/assets/icons/undo.svg new file mode 100644 index 00000000..d07a0c8f --- /dev/null +++ b/project/assets/icons/undo.svg @@ -0,0 +1,22 @@ + + + + + + + + + diff --git a/project/assets/icons/undo.svg.import b/project/assets/icons/undo.svg.import new file mode 100644 index 00000000..61d0ed35 --- /dev/null +++ b/project/assets/icons/undo.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c1nd3r8w1yj1o" +path="res://.godot/imported/undo.svg-8e39613a5ed2624e54d767b85e6b7dc0.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/icons/undo.svg" +dest_files=["res://.godot/imported/undo.svg-8e39613a5ed2624e54d767b85e6b7dc0.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/project/default_file.tres b/project/default_file.tres new file mode 100644 index 00000000..653d5ac9 --- /dev/null +++ b/project/default_file.tres @@ -0,0 +1,8 @@ +[gd_resource type="SaveData" format=3 uid="uid://djlwnfbjmjb6a"] + +[sub_resource type="PlanePrimitive" id="PlanePrimitive_b8mx7"] +blend_range = 1.0 +baseline = 0.0 + +[resource] +primitives = [SubResource("PlanePrimitive_b8mx7")] diff --git a/project/scenes/editor.tscn b/project/scenes/editor.tscn index 9478906d..1c6dcc45 100644 --- a/project/scenes/editor.tscn +++ b/project/scenes/editor.tscn @@ -2,19 +2,19 @@ [ext_resource type="PackedScene" uid="uid://cnux2fqne284i" path="res://objects/primitive_nodes/point_primitive_node.tscn" id="1_b1cmn"] [ext_resource type="PackedScene" uid="uid://wkqhvjnxs2mx" path="res://objects/terrain_chunk.tscn" id="1_pxqd5"] +[ext_resource type="SaveData" uid="uid://djlwnfbjmjb6a" path="res://default_file.tres" id="3_78fwb"] [ext_resource type="Theme" uid="uid://dh5hqcu3vyhrh" path="res://editor_theme.tres" id="3_ba0ut"] [ext_resource type="Texture2D" uid="uid://b8hetdn3d3ysr" path="res://assets/icons/point.svg" id="4_5lcyj"] [ext_resource type="Texture2D" uid="uid://bb0mnjwx58nt3" path="res://assets/icons/plus.svg" id="4_q68jb"] [ext_resource type="Texture2D" uid="uid://bl3gn6qruuy8w" path="res://assets/icons/plane.svg" id="4_xg7d5"] +[ext_resource type="Texture2D" uid="uid://cwl3no6dbtjrf" path="res://assets/icons/save.svg" id="5_74j0u"] [ext_resource type="Texture2D" uid="uid://d1te42w7wpkrx" path="res://assets/icons/noise.svg" id="5_eqbpn"] [ext_resource type="PackedScene" uid="uid://bsvvhue5x4rb" path="res://ui/primitive_inspectors/point_primitive_inspector.tscn" id="8_5tm2q"] [ext_resource type="PackedScene" uid="uid://c5desl3kt72c7" path="res://ui/primitive_inspectors/noise_primitive_inspector.tscn" id="9_3vi5u"] [ext_resource type="PackedScene" uid="uid://bl16us512blpp" path="res://ui/primitive_inspectors/base_primitive_inspector.tscn" id="9_j8y2p"] [ext_resource type="PackedScene" uid="uid://cq25h75v1bnn1" path="res://ui/primitive_inspectors/plane_primitive_inspector.tscn" id="9_o435n"] - -[sub_resource type="PlanePrimitive" id="PlanePrimitive_ba0ut"] -blend_range = 1.0 -baseline = 0.0 +[ext_resource type="Texture2D" uid="uid://c1nd3r8w1yj1o" path="res://assets/icons/undo.svg" id="10_2w0at"] +[ext_resource type="Texture2D" uid="uid://fpnyca6s1f1y" path="res://assets/icons/redo.svg" id="11_5tdu1"] [sub_resource type="Gradient" id="Gradient_b1cmn"] interpolation_mode = 2 @@ -109,21 +109,51 @@ domain_warp_fractal_gain = 0.662 [sub_resource type="NoisePrimitive" id="NoisePrimitive_5lcyj"] noise = SubResource("FastNoiseLite_3vi5u") +[sub_resource type="GDScript" id="GDScript_74j0u"] +resource_name = "SaveButton" +script/source = "extends Button + +@onready var editor : TerrainMeshEditor = %TerrainMeshEditor + +func _pressed(): + if Input.is_key_pressed(KEY_SHIFT): + editor.save_data_as() + else: + editor.save_data() +" + +[sub_resource type="GDScript" id="GDScript_2w0at"] +resource_name = "UndoButton" +script/source = "extends Button + +func _pressed(): + EditHistory.undo_last() +" + +[sub_resource type="GDScript" id="GDScript_5tdu1"] +resource_name = "RedoButton" +script/source = "extends Button + +func _pressed(): + EditHistory.redo_last() +" + [node name="Editor" type="Node3D" unique_id=1027707839] [node name="TerrainMeshEditor" type="TerrainMeshEditor" parent="." unique_id=1382595562] -primitives = [SubResource("PlanePrimitive_ba0ut")] +unique_name_in_owner = true vertex_color_gradient = SubResource("Gradient_b1cmn") color_gradient_end_height = 100.0 chunk_count = 8 chunk_scene = ExtResource("1_pxqd5") point_primitive_object = ExtResource("1_b1cmn") +new_file_data = ExtResource("3_78fwb") [node name="WorldEnvironment" type="WorldEnvironment" parent="." unique_id=1468550752] environment = SubResource("Environment_pxqd5") [node name="DirectionalLight3D" type="DirectionalLight3D" parent="." unique_id=978399107] -transform = Transform3D(-0.750999, -0.305988, 0.585126, -1.29815e-08, 0.886147, 0.463404, -0.660305, 0.348015, -0.665494, 0, 0, 0) +transform = Transform3D(-0.750999, -0.44822368, 0.48486787, -1.4901161e-08, 0.73431087, 0.678813, -0.66030496, 0.50978696, -0.55146533, 0, 0, 0) light_color = Color(0.89, 0.82948, 0.7387, 1) shadow_enabled = true shadow_reverse_cull_face = true @@ -149,6 +179,7 @@ anchor_right = 1.0 anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 2 +size_flags_vertical = 3 drag_area_highlight_in_editor = true [node name="Layers" type="TabContainer" parent="LeftPanel/VBoxContainer" unique_id=2095156888] @@ -156,22 +187,22 @@ layout_mode = 2 size_flags_vertical = 3 current_tab = 0 -[node name="Layers" type="VBoxContainer" parent="LeftPanel/VBoxContainer/Layers" unique_id=138865385] +[node name="File" type="VBoxContainer" parent="LeftPanel/VBoxContainer/Layers" unique_id=138865385] layout_mode = 2 metadata/_tab_index = 0 -[node name="HBoxContainer" type="HBoxContainer" parent="LeftPanel/VBoxContainer/Layers/Layers" unique_id=702489990] +[node name="HBoxContainer" type="HBoxContainer" parent="LeftPanel/VBoxContainer/Layers/File" unique_id=702489990] layout_mode = 2 size_flags_vertical = 8 -[node name="TextureRect" type="TextureRect" parent="LeftPanel/VBoxContainer/Layers/Layers/HBoxContainer" unique_id=1669840346] +[node name="TextureRect" type="TextureRect" parent="LeftPanel/VBoxContainer/Layers/File/HBoxContainer" unique_id=1669840346] custom_minimum_size = Vector2(32, 32) layout_mode = 2 texture = ExtResource("4_q68jb") expand_mode = 2 stretch_mode = 4 -[node name="AddPointPrimitive" type="AddPrimitiveButton" parent="LeftPanel/VBoxContainer/Layers/Layers/HBoxContainer" unique_id=255935272 node_paths=PackedStringArray("terrain")] +[node name="AddPointPrimitive" type="AddPrimitiveButton" parent="LeftPanel/VBoxContainer/Layers/File/HBoxContainer" unique_id=255935272 node_paths=PackedStringArray("terrain")] custom_minimum_size = Vector2(32, 32) layout_mode = 2 icon = SubResource("CompressedTexture2D_xg7d5") @@ -179,7 +210,7 @@ expand_icon = true primitive_blueprint = SubResource("PointPrimitive_5lcyj") terrain = NodePath("../../../../../../TerrainMeshEditor") -[node name="AddPlanePrimitive" type="AddPrimitiveButton" parent="LeftPanel/VBoxContainer/Layers/Layers/HBoxContainer" unique_id=850669113 node_paths=PackedStringArray("terrain")] +[node name="AddPlanePrimitive" type="AddPrimitiveButton" parent="LeftPanel/VBoxContainer/Layers/File/HBoxContainer" unique_id=850669113 node_paths=PackedStringArray("terrain")] custom_minimum_size = Vector2(32, 32) layout_mode = 2 icon = ExtResource("4_xg7d5") @@ -187,7 +218,7 @@ expand_icon = true primitive_blueprint = SubResource("PlanePrimitive_5lcyj") terrain = NodePath("../../../../../../TerrainMeshEditor") -[node name="AddNoisePrimitive" type="AddPrimitiveButton" parent="LeftPanel/VBoxContainer/Layers/Layers/HBoxContainer" unique_id=761062556 node_paths=PackedStringArray("terrain")] +[node name="AddNoisePrimitive" type="AddPrimitiveButton" parent="LeftPanel/VBoxContainer/Layers/File/HBoxContainer" unique_id=761062556 node_paths=PackedStringArray("terrain")] custom_minimum_size = Vector2(32, 32) layout_mode = 2 icon = ExtResource("5_eqbpn") @@ -195,7 +226,7 @@ expand_icon = true primitive_blueprint = SubResource("NoisePrimitive_5lcyj") terrain = NodePath("../../../../../../TerrainMeshEditor") -[node name="Tree" type="PrimitiveLayerList" parent="LeftPanel/VBoxContainer/Layers/Layers" unique_id=797700186 node_paths=PackedStringArray("terrain")] +[node name="Tree" type="PrimitiveLayerList" parent="LeftPanel/VBoxContainer/Layers/File" unique_id=797700186 node_paths=PackedStringArray("terrain")] layout_mode = 2 size_flags_vertical = 3 hide_root = true @@ -209,6 +240,33 @@ icons = { &"PointPrimitive": ExtResource("4_5lcyj") } +[node name="HBoxContainer2" type="HBoxContainer" parent="LeftPanel/VBoxContainer/Layers/File" unique_id=20324709] +layout_mode = 2 + +[node name="SaveButton" type="Button" parent="LeftPanel/VBoxContainer/Layers/File/HBoxContainer2" unique_id=2060569358] +custom_minimum_size = Vector2(32, 32) +layout_mode = 2 +tooltip_text = "Save file: Ctrl-S/Cmd-S(mac)" +icon = ExtResource("5_74j0u") +expand_icon = true +script = SubResource("GDScript_74j0u") + +[node name="Undo" type="Button" parent="LeftPanel/VBoxContainer/Layers/File/HBoxContainer2" unique_id=133676321] +custom_minimum_size = Vector2(32, 32) +layout_mode = 2 +tooltip_text = "Undo: Ctrl-Z/Cmd-Z(mac)" +icon = ExtResource("10_2w0at") +expand_icon = true +script = SubResource("GDScript_2w0at") + +[node name="Redo" type="Button" parent="LeftPanel/VBoxContainer/Layers/File/HBoxContainer2" unique_id=946837272] +custom_minimum_size = Vector2(32, 32) +layout_mode = 2 +tooltip_text = "Redo: Ctrl-Shift-Z/Cmd-Shift-Z(mac)" +icon = ExtResource("11_5tdu1") +expand_icon = true +script = SubResource("GDScript_5tdu1") + [node name="Inspector" type="LayerEditor" parent="LeftPanel/VBoxContainer" unique_id=833878161 node_paths=PackedStringArray("terrain")] layout_mode = 2 size_flags_vertical = 3 diff --git a/test-terrains/highland.terrain.res b/test-terrains/highland.terrain.res index 5defd4d3..b6fe0ab1 100644 Binary files a/test-terrains/highland.terrain.res and b/test-terrains/highland.terrain.res differ