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.cpp76
1 files changed, 36 insertions, 40 deletions
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index 0a4dfd2e0d..b097523c2f 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -1749,8 +1749,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
_edit.mode = TRANSFORM_NONE;
_edit.original = spatial_editor->get_gizmo_transform(); // To prevent to break when flipping with scale.
- bool node_selected = spatial_editor->get_single_selected_node();
- bool can_select_gizmos = node_selected;
+ bool can_select_gizmos = spatial_editor->get_single_selected_node();
{
int idx = view_menu->get_popup()->get_item_index(VIEW_GIZMOS);
@@ -1840,6 +1839,8 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
clicked = ObjectID();
+ bool node_selected = get_selected_count() > 0;
+
if (node_selected && ((spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT && b->is_command_or_control_pressed()) || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_ROTATE)) {
begin_transform(TRANSFORM_ROTATE, false);
break;
@@ -1985,9 +1986,8 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
} else {
const bool movement_threshold_passed = _edit.original_mouse_pos.distance_to(_edit.mouse_pos) > 8 * EDSCALE;
- // enable region-select if nothing has been selected yet or multi-select (shift key) is active
- if (selection_in_progress && movement_threshold_passed) {
- if (get_selected_count() == 0 || clicked_wants_append) {
+ if (selection_in_progress && movement_threshold_passed && clicked.is_valid()) {
+ if (clicked_wants_append || !editor_selection->is_selected(Object::cast_to<Node>(ObjectDB::get_instance(clicked)))) {
cursor.region_select = true;
cursor.region_begin = _edit.original_mouse_pos;
clicked = ObjectID();
@@ -2790,8 +2790,7 @@ void Node3DEditorViewport::_notification(int p_what) {
}
Transform3D t = sp->get_global_gizmo_transform();
- VisualInstance3D *vi = Object::cast_to<VisualInstance3D>(sp);
- AABB new_aabb = vi ? vi->get_aabb() : _calculate_spatial_bounds(sp);
+ AABB new_aabb = _calculate_spatial_bounds(sp);
exist = true;
if (se->last_xform == t && se->aabb == new_aabb && !se->last_xform_dirty) {
@@ -2837,7 +2836,7 @@ void Node3DEditorViewport::_notification(int p_what) {
last_message = message;
}
- message_time -= get_physics_process_delta_time();
+ message_time -= get_process_delta_time();
if (message_time < 0) {
surface->queue_redraw();
}
@@ -3018,6 +3017,8 @@ void Node3DEditorViewport::_notification(int p_what) {
// Clear preview material when dropped outside applicable object.
if (spatial_editor->get_preview_material().is_valid() && !is_drag_successful()) {
_remove_preview_material();
+ } else {
+ _remove_preview_node();
}
} break;
}
@@ -4087,35 +4088,35 @@ Vector3 Node3DEditorViewport::_get_instance_position(const Point2 &p_pos) const
return world_pos + world_ray * FALLBACK_DISTANCE;
}
-AABB Node3DEditorViewport::_calculate_spatial_bounds(const Node3D *p_parent, bool p_exclude_top_level_transform) {
+AABB Node3DEditorViewport::_calculate_spatial_bounds(const Node3D *p_parent, const Node3D *p_top_level_parent) {
AABB bounds;
+ if (!p_top_level_parent) {
+ p_top_level_parent = p_parent;
+ }
+
+ if (!p_parent) {
+ return AABB(Vector3(-0.2, -0.2, -0.2), Vector3(0.4, 0.4, 0.4));
+ }
+
+ Transform3D xform_to_top_level_parent_space = p_top_level_parent->get_global_transform().affine_inverse() * p_parent->get_global_transform();
+
const VisualInstance3D *visual_instance = Object::cast_to<VisualInstance3D>(p_parent);
if (visual_instance) {
bounds = visual_instance->get_aabb();
+ } else {
+ bounds = AABB();
}
+ bounds = xform_to_top_level_parent_space.xform(bounds);
for (int i = 0; i < p_parent->get_child_count(); i++) {
Node3D *child = Object::cast_to<Node3D>(p_parent->get_child(i));
if (child) {
- AABB child_bounds = _calculate_spatial_bounds(child, false);
-
- if (bounds.size == Vector3() && p_parent) {
- bounds = child_bounds;
- } else {
- bounds.merge_with(child_bounds);
- }
+ AABB child_bounds = _calculate_spatial_bounds(child, p_top_level_parent);
+ bounds.merge_with(child_bounds);
}
}
- if (bounds.size == Vector3() && !p_parent) {
- bounds = AABB(Vector3(-0.2, -0.2, -0.2), Vector3(0.4, 0.4, 0.4));
- }
-
- if (!p_exclude_top_level_transform) {
- bounds = p_parent->get_transform().xform(bounds);
- }
-
return bounds;
}
@@ -4531,7 +4532,7 @@ void Node3DEditorViewport::drop_data_fw(const Point2 &p_point, const Variant &p_
}
bool is_shift = Input::get_singleton()->is_key_pressed(Key::SHIFT);
- bool is_ctrl = Input::get_singleton()->is_key_pressed(Key::CTRL);
+ bool is_alt = Input::get_singleton()->is_key_pressed(Key::ALT);
selected_files.clear();
Dictionary d = p_data;
@@ -4541,15 +4542,15 @@ void Node3DEditorViewport::drop_data_fw(const Point2 &p_point, const Variant &p_
List<Node *> selected_nodes = EditorNode::get_singleton()->get_editor_selection()->get_selected_node_list();
Node *root_node = EditorNode::get_singleton()->get_edited_scene();
- if (selected_nodes.size() == 1) {
+ if (selected_nodes.size() > 0) {
Node *selected_node = selected_nodes[0];
- target_node = root_node;
- if (is_ctrl) {
- target_node = selected_node;
+ target_node = selected_node;
+ if (is_alt) {
+ target_node = root_node;
} else if (is_shift && selected_node != root_node) {
target_node = selected_node->get_parent();
}
- } else if (selected_nodes.size() == 0) {
+ } else {
if (root_node) {
target_node = root_node;
} else {
@@ -4557,11 +4558,6 @@ void Node3DEditorViewport::drop_data_fw(const Point2 &p_point, const Variant &p_
SceneTreeDock::get_singleton()->add_root_node(memnew(Node3D));
target_node = get_tree()->get_edited_scene_root();
}
- } else {
- accept->set_text(TTR("Cannot drag and drop into multiple selected nodes."));
- accept->popup_centered();
- _remove_preview_node();
- return;
}
drop_pos = p_point;
@@ -6501,20 +6497,20 @@ void vertex() {
// Points are already in world space, so no need for MODEL_MATRIX anymore.
vec4 clip_a = PROJECTION_MATRIX * (VIEW_MATRIX * vec4(point_a, 1.0));
vec4 clip_b = PROJECTION_MATRIX * (VIEW_MATRIX * vec4(point_b, 1.0));
-
+
vec2 screen_a = VIEWPORT_SIZE * (0.5 * clip_a.xy / clip_a.w + 0.5);
vec2 screen_b = VIEWPORT_SIZE * (0.5 * clip_b.xy / clip_b.w + 0.5);
-
+
vec2 x_basis = normalize(screen_b - screen_a);
vec2 y_basis = vec2(-x_basis.y, x_basis.x);
-
+
float width = 3.0;
vec2 screen_point_a = screen_a + width * (VERTEX.x * x_basis + VERTEX.y * y_basis);
vec2 screen_point_b = screen_b + width * (VERTEX.x * x_basis + VERTEX.y * y_basis);
vec2 screen_point_final = mix(screen_point_a, screen_point_b, VERTEX.z);
-
+
vec4 clip_final = mix(clip_a, clip_b, VERTEX.z);
-
+
POSITION = vec4(clip_final.w * ((2.0 * screen_point_final) / VIEWPORT_SIZE - 1.0), clip_final.z, clip_final.w);
UV = VERTEX.yz * clip_final.w;