summaryrefslogtreecommitdiffstats
path: root/editor/plugins/node_3d_editor_plugin.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'editor/plugins/node_3d_editor_plugin.cpp')
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp82
1 files changed, 58 insertions, 24 deletions
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index 5a4d79cdc8..72a63539b3 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -467,22 +467,31 @@ void Node3DEditorViewport::_select_clicked(bool p_append, bool p_single, bool p_
}
void Node3DEditorViewport::_select(Node *p_node, bool p_append, bool p_single) {
- if (!p_append) {
- editor_selection->clear();
- }
-
- if (editor_selection->is_selected(p_node)) {
- //erase
- editor_selection->remove_node(p_node);
+ // Add or remove a single node from the selection
+ if (p_append && p_single) {
+ if (editor_selection->is_selected(p_node)) {
+ // Already in the selection, remove it from the selected nodes
+ editor_selection->remove_node(p_node);
+ } else {
+ // Add the item to the selection
+ editor_selection->add_node(p_node);
+ }
+ } else if (p_append && !p_single) {
+ // Add the item to the selection
+ editor_selection->add_node(p_node);
} else {
+ // No append; single select
+ editor_selection->clear();
editor_selection->add_node(p_node);
- }
-
- if (p_single) {
+ // Reselect
if (Engine::get_singleton()->is_editor_hint()) {
editor->call("edit_node", p_node);
}
}
+
+ if (editor_selection->get_selected_node_list().size() == 1) {
+ editor->push_item(editor_selection->get_selected_node_list()[0]);
+ }
}
ObjectID Node3DEditorViewport::_select_ray(const Point2 &p_pos, bool p_append, bool &r_includes_current, int *r_gizmo_handle, bool p_alt_select) {
@@ -1967,6 +1976,13 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
return;
}
+ if (EditorSettings::get_singleton()->get("editors/3d/navigation/emulate_numpad")) {
+ const uint32_t code = k->get_keycode();
+ if (code >= KEY_0 && code <= KEY_9) {
+ k->set_keycode(code - KEY_0 + KEY_KP_0);
+ }
+ }
+
if (ED_IS_SHORTCUT("spatial_editor/snap", p_event)) {
if (_edit.mode != TRANSFORM_NONE) {
_edit.snap = !_edit.snap;
@@ -2504,15 +2520,15 @@ void Node3DEditorViewport::_notification(int p_what) {
}
if (show_info) {
+ const String viewport_size = vformat(String::utf8("%d × %d"), viewport->get_size().x, viewport->get_size().y);
String text;
text += vformat(TTR("X: %s\n"), rtos(current_camera->get_position().x).pad_decimals(1));
text += vformat(TTR("Y: %s\n"), rtos(current_camera->get_position().y).pad_decimals(1));
text += vformat(TTR("Z: %s\n"), rtos(current_camera->get_position().z).pad_decimals(1));
text += "\n";
text += vformat(
- TTR("Size: %dx%d (%.1fMP)\n"),
- viewport->get_size().x,
- viewport->get_size().y,
+ TTR("Size: %s (%.1fMP)\n"),
+ viewport_size,
viewport->get_size().x * viewport->get_size().y * 0.000001);
text += "\n";
@@ -3250,14 +3266,12 @@ void Node3DEditorViewport::_toggle_camera_preview(bool p_activate) {
if (!preview) {
preview_camera->hide();
}
- view_menu->set_disabled(false);
surface->update();
} else {
previewing = preview;
previewing->connect("tree_exiting", callable_mp(this, &Node3DEditorViewport::_preview_exited_scene));
RS::get_singleton()->viewport_attach_camera(viewport->get_viewport_rid(), preview->get_camera()); //replace
- view_menu->set_disabled(true);
surface->update();
}
}
@@ -3504,7 +3518,6 @@ void Node3DEditorViewport::set_state(const Dictionary &p_state) {
previewing = Object::cast_to<Camera3D>(pv);
previewing->connect("tree_exiting", callable_mp(this, &Node3DEditorViewport::_preview_exited_scene));
RS::get_singleton()->viewport_attach_camera(viewport->get_viewport_rid(), previewing->get_camera()); //replace
- view_menu->set_disabled(true);
surface->update();
preview_camera->set_pressed(true);
preview_camera->show();
@@ -6214,31 +6227,47 @@ void Node3DEditor::_sun_environ_settings_pressed() {
sun_environ_popup->popup();
}
-void Node3DEditor::_add_sun_to_scene() {
+void Node3DEditor::_add_sun_to_scene(bool p_already_added_environment) {
sun_environ_popup->hide();
+ if (!p_already_added_environment && world_env_count == 0 && Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+ // Prevent infinite feedback loop between the sun and environment methods.
+ _add_environment_to_scene(true);
+ }
+
Node *base = get_tree()->get_edited_scene_root();
if (!base) {
- EditorNode::get_singleton()->show_warning(TTR("A root node is needed for this operation"));
- return;
+ // Create a root node so we can add child nodes to it.
+ EditorNode::get_singleton()->get_scene_tree_dock()->add_root_node(memnew(Node3D));
+ base = get_tree()->get_edited_scene_root();
}
ERR_FAIL_COND(!base);
Node *new_sun = preview_sun->duplicate();
undo_redo->create_action("Add Preview Sun to Scene");
undo_redo->add_do_method(base, "add_child", new_sun);
+ // Move to the beginning of the scene tree since more "global" nodes
+ // generally look better when placed at the top.
+ undo_redo->add_do_method(base, "move_child", new_sun, 0);
undo_redo->add_do_method(new_sun, "set_owner", base);
undo_redo->add_undo_method(base, "remove_child", new_sun);
undo_redo->add_do_reference(new_sun);
undo_redo->commit_action();
}
-void Node3DEditor::_add_environment_to_scene() {
+
+void Node3DEditor::_add_environment_to_scene(bool p_already_added_sun) {
sun_environ_popup->hide();
+ if (!p_already_added_sun && directional_light_count == 0 && Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+ // Prevent infinite feedback loop between the sun and environment methods.
+ _add_sun_to_scene(true);
+ }
+
Node *base = get_tree()->get_edited_scene_root();
if (!base) {
- EditorNode::get_singleton()->show_warning(TTR("A root node is needed for this operation"));
- return;
+ // Create a root node so we can add child nodes to it.
+ EditorNode::get_singleton()->get_scene_tree_dock()->add_root_node(memnew(Node3D));
+ base = get_tree()->get_edited_scene_root();
}
ERR_FAIL_COND(!base);
@@ -6247,6 +6276,9 @@ void Node3DEditor::_add_environment_to_scene() {
undo_redo->create_action("Add Preview Environment to Scene");
undo_redo->add_do_method(base, "add_child", new_env);
+ // Move to the beginning of the scene tree since more "global" nodes
+ // generally look better when placed at the top.
+ undo_redo->add_do_method(base, "move_child", new_env, 0);
undo_redo->add_do_method(new_env, "set_owner", base);
undo_redo->add_undo_method(base, "remove_child", new_env);
undo_redo->add_do_reference(new_env);
@@ -7174,7 +7206,8 @@ Node3DEditor::Node3DEditor(EditorNode *p_editor) {
sun_add_to_scene = memnew(Button);
sun_add_to_scene->set_text(TTR("Add Sun to Scene"));
- sun_add_to_scene->connect("pressed", callable_mp(this, &Node3DEditor::_add_sun_to_scene));
+ sun_add_to_scene->set_tooltip(TTR("Adds a DirectionalLight3D node matching the preview sun settings to the current scene.\nHold Shift while clicking to also add the preview environment to the current scene."));
+ sun_add_to_scene->connect("pressed", callable_mp(this, &Node3DEditor::_add_sun_to_scene), varray(false));
sun_vb->add_spacer();
sun_vb->add_child(sun_add_to_scene);
@@ -7238,7 +7271,8 @@ Node3DEditor::Node3DEditor(EditorNode *p_editor) {
environ_add_to_scene = memnew(Button);
environ_add_to_scene->set_text(TTR("Add Environment to Scene"));
- environ_add_to_scene->connect("pressed", callable_mp(this, &Node3DEditor::_add_environment_to_scene));
+ environ_add_to_scene->set_tooltip(TTR("Adds a WorldEnvironment node matching the preview environment settings to the current scene.\nHold Shift while clicking to also add the preview sun to the current scene."));
+ environ_add_to_scene->connect("pressed", callable_mp(this, &Node3DEditor::_add_environment_to_scene), varray(false));
environ_vb->add_spacer();
environ_vb->add_child(environ_add_to_scene);