diff options
-rw-r--r-- | editor/plugins/node_3d_editor_plugin.cpp | 103 | ||||
-rw-r--r-- | editor/plugins/node_3d_editor_plugin.h | 79 |
2 files changed, 45 insertions, 137 deletions
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index f79b5027cb..2e8ae1a286 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -886,15 +886,13 @@ void Node3DEditorViewport::_update_name() { view_menu->reset_size(); } -void Node3DEditorViewport::_compute_edit(const Point2 &p_point, const bool p_auto_center) { +void Node3DEditorViewport::_compute_edit(const Point2 &p_point) { _edit.original_local = spatial_editor->are_local_coords_enabled(); _edit.click_ray = _get_ray(p_point); _edit.click_ray_pos = _get_ray_pos(p_point); _edit.plane = TRANSFORM_VIEW; - if (p_auto_center) { - _edit.center = spatial_editor->get_gizmo_transform().origin; - } spatial_editor->update_transform_gizmo(); + _edit.center = spatial_editor->get_gizmo_transform().origin; Node3D *selected = spatial_editor->get_single_selected_node(); Node3DEditorSelectedItem *se = selected ? editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(selected) : nullptr; @@ -1366,7 +1364,6 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { } } - _edit.center = spatial_editor->get_gizmo_target_center(); Ref<InputEventMouseButton> b = p_event; if (b.is_valid()) { @@ -3367,7 +3364,7 @@ void Node3DEditorViewport::update_transform_gizmo_view() { Transform3D xform = spatial_editor->get_gizmo_transform(); - const Transform3D camera_xform = camera->get_transform(); + Transform3D camera_xform = camera->get_transform(); if (xform.origin.is_equal_approx(camera_xform.origin)) { for (int i = 0; i < 3; i++) { @@ -3386,63 +3383,11 @@ void Node3DEditorViewport::update_transform_gizmo_view() { const Vector3 camz = -camera_xform.get_basis().get_axis(2).normalized(); const Vector3 camy = -camera_xform.get_basis().get_axis(1).normalized(); const Plane p = Plane(camz, camera_xform.origin); - const real_t gizmo_d = CLAMP(Math::abs(p.distance_to(xform.origin)), camera->get_near() * 2, camera->get_far() / 2); + const real_t gizmo_d = MAX(Math::abs(p.distance_to(xform.origin)), CMP_EPSILON); const real_t d0 = camera->unproject_position(camera_xform.origin + camz * gizmo_d).y; const real_t d1 = camera->unproject_position(camera_xform.origin + camz * gizmo_d + camy).y; const real_t dd = MAX(Math::abs(d0 - d1), CMP_EPSILON); - // This code ensures the gizmo stays on the screen. This includes if - // the gizmo would otherwise be behind the camera, to the sides of - // the camera, too close to the edge of the screen, too close to - // the camera, or too far away from the camera. First we calculate - // where the gizmo would go on screen, then we put it there. - const Vector3 object_position = spatial_editor->get_gizmo_target_center(); - Vector2 gizmo_screen_position = camera->unproject_position(object_position); - const Vector2 viewport_size = viewport->get_size(); - // We would use "camera.is_position_behind(parent_translation)" instead of dot, - // except that it also accounts for the near clip plane, which we don't want. - const bool is_in_front = camera_xform.basis.get_column(2).dot(object_position - camera_xform.origin) < 0; - const bool is_in_viewport = is_in_front && Rect2(Vector2(0, 0), viewport_size).has_point(gizmo_screen_position); - if (spatial_editor->is_keep_gizmo_onscreen_enabled()) { - if (!spatial_editor->is_gizmo_visible() || is_in_viewport) { - // In this case, the gizmo is either not visible, or in the viewport - // already, so we should hide the offscreen line. - gizmo_offscreen_line->hide(); - } else { - // In this case, the point is not "normally" on screen, and - // it should be placed in the center. - const Vector2 half_viewport_size = viewport_size / 2; - gizmo_screen_position = half_viewport_size; - // The rest of this is for drawing the offscreen line. - // One point goes in the center of the viewport. - // Calculate where to put the other point of the line. - Vector2 unprojected_position = camera->unproject_position(object_position); - if (!is_in_front) { - // When the object is behind, we need to flip and grow the line. - unprojected_position -= half_viewport_size; - unprojected_position = unprojected_position.normalized() * -half_viewport_size.length_squared(); - unprojected_position += half_viewport_size; - } - gizmo_offscreen_line->point1 = half_viewport_size; - gizmo_offscreen_line->point2 = unprojected_position; - gizmo_offscreen_line->update(); - gizmo_offscreen_line->show(); - } - // Update the gizmo's position using what we calculated. - xform.origin = camera->project_position(gizmo_screen_position, gizmo_d); - } else { - // In this case, the user does not want the gizmo to be - // kept on screen, so we should hide the offscreen line, - // and just use the gizmo's unmodified position. - gizmo_offscreen_line->hide(); - if (is_in_viewport) { - xform.origin = camera->project_position(gizmo_screen_position, gizmo_d); - } else { - xform.origin = object_position; - } - } - spatial_editor->set_gizmo_transform(xform); - const real_t gizmo_size = EditorSettings::get_singleton()->get("editors/3d/manipulator_gizmo_size"); // At low viewport heights, multiply the gizmo scale based on the viewport height. // This prevents the gizmo from growing very large and going outside the viewport. @@ -3451,6 +3396,7 @@ void Node3DEditorViewport::update_transform_gizmo_view() { (gizmo_size / Math::abs(dd)) * MAX(1, EDSCALE) * MIN(viewport_base_height, subviewport_container->get_size().height) / viewport_base_height / subviewport_container->get_stretch_shrink(); + Vector3 scale = Vector3(1, 1, 1) * gizmo_scale; // if the determinant is zero, we should disable the gizmo from being rendered // this prevents supplying bad values to the renderer and then having to filter it out again @@ -3472,7 +3418,7 @@ void Node3DEditorViewport::update_transform_gizmo_view() { if (xform.basis.get_axis(i).normalized().dot(xform.basis.get_axis((i + 1) % 3).normalized()) < 1.0) { axis_angle = axis_angle.looking_at(xform.basis.get_axis(i).normalized(), xform.basis.get_axis((i + 1) % 3).normalized()); } - axis_angle.basis *= gizmo_scale; + axis_angle.basis.scale(scale); axis_angle.origin = xform.origin; RenderingServer::get_singleton()->instance_set_transform(move_gizmo_instance[i], axis_angle); RenderingServer::get_singleton()->instance_set_visible(move_gizmo_instance[i], spatial_editor->is_gizmo_visible() && (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_MOVE)); @@ -3495,7 +3441,7 @@ void Node3DEditorViewport::update_transform_gizmo_view() { // Rotation white outline xform.orthonormalize(); - xform.basis *= gizmo_scale; + xform.basis.scale(scale); RenderingServer::get_singleton()->instance_set_transform(rotate_gizmo_instance[3], xform); RenderingServer::get_singleton()->instance_set_visible(rotate_gizmo_instance[3], spatial_editor->is_gizmo_visible() && (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_ROTATE)); } @@ -4077,7 +4023,7 @@ void Node3DEditorViewport::drop_data_fw(const Point2 &p_point, const Variant &p_ void Node3DEditorViewport::begin_transform(TransformMode p_mode, bool instant) { if (get_selected_count() > 0) { _edit.mode = p_mode; - _compute_edit(_edit.mouse_pos, false); + _compute_edit(_edit.mouse_pos); _edit.instant = instant; _edit.snap = spatial_editor->is_snap_enabled(); } @@ -4480,14 +4426,15 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito zoom_indicator_delay = 0.0; spatial_editor = p_spatial_editor; - subviewport_container = memnew(SubViewportContainer); - subviewport_container->set_stretch(true); - add_child(subviewport_container); - subviewport_container->set_anchors_and_offsets_preset(Control::PRESET_WIDE); + SubViewportContainer *c = memnew(SubViewportContainer); + subviewport_container = c; + c->set_stretch(true); + add_child(c); + c->set_anchors_and_offsets_preset(Control::PRESET_WIDE); viewport = memnew(SubViewport); viewport->set_disable_input(true); - subviewport_container->add_child(viewport); + c->add_child(viewport); surface = memnew(Control); surface->set_drag_forwarding(this); add_child(surface); @@ -4500,9 +4447,6 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito camera->make_current(); surface->set_focus_mode(FOCUS_ALL); - gizmo_offscreen_line = memnew(GizmoOffScreenLine); - subviewport_container->add_child(gizmo_offscreen_line); - VBoxContainer *vbox = memnew(VBoxContainer); surface->add_child(vbox); vbox->set_offset(SIDE_LEFT, 10 * EDSCALE); @@ -5127,7 +5071,6 @@ void Node3DEditor::update_transform_gizmo() { gizmo.visible = count > 0; gizmo.transform.origin = (count > 0) ? gizmo_center / count : Vector3(); gizmo.transform.basis = (count == 1) ? gizmo_basis : Basis(); - gizmo.target_center = gizmo_center / count; for (uint32_t i = 0; i < VIEWPORTS_COUNT; i++) { viewports[i]->update_transform_gizmo_view(); @@ -5280,7 +5223,6 @@ Dictionary Node3DEditor::get_state() const { d["show_grid"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_GRID)); d["show_origin"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_ORIGIN)); - d["keep_gizmo_onscreen"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_KEEP_GIZMO_ONSCREEN)); d["fov"] = get_fov(); d["znear"] = get_znear(); d["zfar"] = get_zfar(); @@ -5405,13 +5347,6 @@ void Node3DEditor::set_state(const Dictionary &p_state) { RenderingServer::get_singleton()->instance_set_visible(origin_instance, use); } } - if (d.has("keep_gizmo_onscreen")) { - bool use = d["keep_gizmo_onscreen"]; - - if (use != view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_KEEP_GIZMO_ONSCREEN))) { - _menu_item_pressed(MENU_KEEP_GIZMO_ONSCREEN); - } - } if (d.has("gizmos_status")) { Dictionary gizmos_status = d["gizmos_status"]; @@ -5765,13 +5700,7 @@ void Node3DEditor::_menu_item_pressed(int p_option) { _init_grid(); view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(p_option), grid_enabled); - } break; - case MENU_KEEP_GIZMO_ONSCREEN: { - keep_gizmo_onscreen = !view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(p_option)); - for (uint32_t i = 0; i < VIEWPORTS_COUNT; i++) { - get_editor_viewport(i)->update_transform_gizmo_view(); - } - view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(p_option), keep_gizmo_onscreen); + } break; case MENU_VIEW_CAMERA_SETTINGS: { settings_dialog->popup_centered(settings_vbc->get_combined_minimum_size() + Size2(50, 50)); @@ -7756,14 +7685,12 @@ Node3DEditor::Node3DEditor(EditorNode *p_editor) { p->add_separator(); p->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_origin", TTR("View Origin")), MENU_VIEW_ORIGIN); p->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_grid", TTR("View Grid"), Key::NUMBERSIGN), MENU_VIEW_GRID); - p->add_check_shortcut(ED_SHORTCUT("spatial_editor/keep_gizmo_onscreen", TTR("Keep Gizmo On Screen"), KeyModifierMask::CMD + KeyModifierMask::ALT + Key::G), MENU_KEEP_GIZMO_ONSCREEN); p->add_separator(); p->add_shortcut(ED_SHORTCUT("spatial_editor/settings", TTR("Settings...")), MENU_VIEW_CAMERA_SETTINGS); p->set_item_checked(p->get_item_index(MENU_VIEW_ORIGIN), true); p->set_item_checked(p->get_item_index(MENU_VIEW_GRID), true); - p->set_item_checked(p->get_item_index(MENU_KEEP_GIZMO_ONSCREEN), true); p->connect("id_pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed)); diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index f14f8b90b9..bbe5615570 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -87,19 +87,6 @@ public: void set_viewport(Node3DEditorViewport *p_viewport); }; -class GizmoOffScreenLine : public Control { - GDCLASS(GizmoOffScreenLine, Control); - -public: - Vector2 point1; - Vector2 point2; - void _notification(int p_what) { - if (p_what == NOTIFICATION_DRAW && is_visible()) { - draw_line(point1, point2, Color(0.0f, 0.75f, 0.75f), 2); - } - } -}; - class Node3DEditorViewport : public Control { GDCLASS(Node3DEditorViewport, Control); friend class Node3DEditor; @@ -214,7 +201,6 @@ private: CheckBox *preview_camera; SubViewportContainer *subviewport_container; - GizmoOffScreenLine *gizmo_offscreen_line; MenuButton *view_menu; PopupMenu *display_submenu; @@ -251,7 +237,7 @@ private: }; void _update_name(); - void _compute_edit(const Point2 &p_point, const bool p_auto_center = true); + void _compute_edit(const Point2 &p_point); void _clear_selected(); void _select_clicked(bool p_allow_locked); ObjectID _select_ray(const Point2 &p_pos); @@ -521,35 +507,6 @@ class Node3DEditor : public VBoxContainer { public: static const unsigned int VIEWPORTS_COUNT = 4; - enum MenuOption { - MENU_GROUP_SELECTED, - MENU_KEEP_GIZMO_ONSCREEN, - MENU_LOCK_SELECTED, - MENU_SNAP_TO_FLOOR, - MENU_TOOL_LIST_SELECT, - MENU_TOOL_LOCAL_COORDS, - MENU_TOOL_MOVE, - MENU_TOOL_OVERRIDE_CAMERA, - MENU_TOOL_ROTATE, - MENU_TOOL_SCALE, - MENU_TOOL_SELECT, - MENU_TOOL_USE_SNAP, - MENU_TRANSFORM_CONFIGURE_SNAP, - MENU_TRANSFORM_DIALOG, - MENU_UNGROUP_SELECTED, - MENU_UNLOCK_SELECTED, - MENU_VIEW_CAMERA_SETTINGS, - MENU_VIEW_GIZMOS_3D_ICONS, - MENU_VIEW_GRID, - MENU_VIEW_ORIGIN, - MENU_VIEW_USE_1_VIEWPORT, - MENU_VIEW_USE_2_VIEWPORTS, - MENU_VIEW_USE_2_VIEWPORTS_ALT, - MENU_VIEW_USE_3_VIEWPORTS, - MENU_VIEW_USE_3_VIEWPORTS_ALT, - MENU_VIEW_USE_4_VIEWPORTS, - }; - enum ToolMode { TOOL_MODE_SELECT, TOOL_MODE_MOVE, @@ -568,6 +525,7 @@ public: TOOL_OPT_USE_SNAP, TOOL_OPT_OVERRIDE_CAMERA, TOOL_OPT_MAX + }; private: @@ -596,7 +554,6 @@ private: Camera3D::Projection grid_camera_last_update_perspective = Camera3D::PROJECTION_PERSPECTIVE; Vector3 grid_camera_last_update_position = Vector3(); - bool keep_gizmo_onscreen = true; Ref<ArrayMesh> move_gizmo[3], move_plane_gizmo[3], rotate_gizmo[4], scale_gizmo[3], scale_plane_gizmo[3], axis_gizmo[3]; Ref<StandardMaterial3D> gizmo_color[3]; Ref<StandardMaterial3D> plane_gizmo_color[3]; @@ -630,10 +587,37 @@ private: struct Gizmo { bool visible = false; real_t scale = 0; - Vector3 target_center; Transform3D transform; } gizmo; + enum MenuOption { + MENU_TOOL_SELECT, + MENU_TOOL_MOVE, + MENU_TOOL_ROTATE, + MENU_TOOL_SCALE, + MENU_TOOL_LIST_SELECT, + MENU_TOOL_LOCAL_COORDS, + MENU_TOOL_USE_SNAP, + MENU_TOOL_OVERRIDE_CAMERA, + MENU_TRANSFORM_CONFIGURE_SNAP, + MENU_TRANSFORM_DIALOG, + MENU_VIEW_USE_1_VIEWPORT, + MENU_VIEW_USE_2_VIEWPORTS, + MENU_VIEW_USE_2_VIEWPORTS_ALT, + MENU_VIEW_USE_3_VIEWPORTS, + MENU_VIEW_USE_3_VIEWPORTS_ALT, + MENU_VIEW_USE_4_VIEWPORTS, + MENU_VIEW_ORIGIN, + MENU_VIEW_GRID, + MENU_VIEW_GIZMOS_3D_ICONS, + MENU_VIEW_CAMERA_SETTINGS, + MENU_LOCK_SELECTED, + MENU_UNLOCK_SELECTED, + MENU_GROUP_SELECTED, + MENU_UNGROUP_SELECTED, + MENU_SNAP_TO_FLOOR + }; + Button *tool_button[TOOL_MAX]; Button *tool_option_button[TOOL_OPT_MAX]; @@ -792,10 +776,7 @@ public: float get_zfar() const { return settings_zfar->get_value(); } float get_fov() const { return settings_fov->get_value(); } - Vector3 get_gizmo_target_center() const { return gizmo.target_center; } Transform3D get_gizmo_transform() const { return gizmo.transform; } - void set_gizmo_transform(const Transform3D &p_transform) { gizmo.transform = p_transform; } - bool is_keep_gizmo_onscreen_enabled() const { return keep_gizmo_onscreen; } bool is_gizmo_visible() const; ToolMode get_tool_mode() const { return tool_mode; } |