From 3518b0dc5a53a5426a1c34d9cd4a73c7ecd62510 Mon Sep 17 00:00:00 2001 From: Robert Yevdokimov <105675984+ryevdokimov@users.noreply.github.com> Date: Wed, 7 Jan 2026 20:59:25 -0500 Subject: [PATCH] Keep other parts of transform gizmo visible when rotating in local mode --- doc/classes/EditorSettings.xml | 3 ++ editor/scene/3d/node_3d_editor_plugin.cpp | 37 ++++++++++++++++++++--- editor/scene/3d/node_3d_editor_plugin.h | 4 +++ editor/settings/editor_settings.cpp | 3 +- 4 files changed, 41 insertions(+), 6 deletions(-) diff --git a/doc/classes/EditorSettings.xml b/doc/classes/EditorSettings.xml index e577c05144..f7f598f101 100644 --- a/doc/classes/EditorSettings.xml +++ b/doc/classes/EditorSettings.xml @@ -503,6 +503,9 @@ The color to use for the selection box that surrounds selected nodes in the 3D editor viewport. The color's alpha channel influences the selection box's opacity. + + If checked, the transform gizmo remains visible during rotation in that transform mode. + The color to use for the AABB gizmo that displays the [GeometryInstance3D]'s custom [AABB]. diff --git a/editor/scene/3d/node_3d_editor_plugin.cpp b/editor/scene/3d/node_3d_editor_plugin.cpp index 6611dbcd19..29c91368d5 100644 --- a/editor/scene/3d/node_3d_editor_plugin.cpp +++ b/editor/scene/3d/node_3d_editor_plugin.cpp @@ -4602,9 +4602,34 @@ void Node3DEditorViewport::update_transform_gizmo_view() { return; } - bool hide_during_rotation = _is_rotation_arc_visible(); + bool local_coords = spatial_editor->are_local_coords_enabled(); + bool arc_visible = _is_rotation_arc_visible(); + int show_gizmo_flags = EDITOR_GET("editors/3d/show_gizmo_during_rotation"); - bool show_gizmo = spatial_editor->is_gizmo_visible() && !_edit.instant && transform_gizmo_visible && !collision_reposition && !hide_during_rotation; + bool keep_gizmo_visible = arc_visible && ((local_coords && (show_gizmo_flags & Node3DEditor::TRANSFORM_MODE_LOCAL)) || (!local_coords && (show_gizmo_flags & Node3DEditor::TRANSFORM_MODE_GLOBAL))); + bool hide_gizmo_during_rotation = arc_visible && !keep_gizmo_visible; + + int arc_replaces_ring = -1; + if (keep_gizmo_visible) { + switch (_edit.plane) { + case TRANSFORM_X_AXIS: + arc_replaces_ring = 0; + break; + case TRANSFORM_Y_AXIS: + arc_replaces_ring = 1; + break; + case TRANSFORM_Z_AXIS: + arc_replaces_ring = 2; + break; + case TRANSFORM_VIEW: + arc_replaces_ring = 3; + break; + default: + break; + } + } + + bool show_gizmo = spatial_editor->is_gizmo_visible() && !_edit.instant && transform_gizmo_visible && !collision_reposition && !hide_gizmo_during_rotation; bool show_rotate_gizmo = show_gizmo && (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_TRANSFORM || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_ROTATE); for (int i = 0; i < 3; i++) { @@ -4619,7 +4644,7 @@ void Node3DEditorViewport::update_transform_gizmo_view() { RenderingServer::get_singleton()->instance_set_transform(move_plane_gizmo_instance[i], axis_angle); RenderingServer::get_singleton()->instance_set_visible(move_plane_gizmo_instance[i], show_gizmo && (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_TRANSFORM || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_MOVE)); RenderingServer::get_singleton()->instance_set_transform(rotate_gizmo_instance[i], axis_angle); - RenderingServer::get_singleton()->instance_set_visible(rotate_gizmo_instance[i], show_rotate_gizmo); + RenderingServer::get_singleton()->instance_set_visible(rotate_gizmo_instance[i], show_rotate_gizmo && i != arc_replaces_ring); RenderingServer::get_singleton()->instance_set_transform(scale_gizmo_instance[i], axis_angle); RenderingServer::get_singleton()->instance_set_visible(scale_gizmo_instance[i], show_gizmo && (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SCALE)); RenderingServer::get_singleton()->instance_set_transform(scale_plane_gizmo_instance[i], axis_angle); @@ -4629,9 +4654,11 @@ void Node3DEditorViewport::update_transform_gizmo_view() { Transform3D view_rotation_xform = xform; view_rotation_xform.orthonormalize(); - view_rotation_xform.basis.scale(scale); + bool shrink_view_ring = arc_replaces_ring >= 0 && arc_replaces_ring < 3; + Vector3 view_ring_scale = shrink_view_ring ? scale * (GIZMO_CIRCLE_SIZE / GIZMO_VIEW_ROTATION_SIZE) : scale; + view_rotation_xform.basis.scale(view_ring_scale); RenderingServer::get_singleton()->instance_set_transform(rotate_gizmo_instance[3], view_rotation_xform); - RenderingServer::get_singleton()->instance_set_visible(rotate_gizmo_instance[3], show_rotate_gizmo); + RenderingServer::get_singleton()->instance_set_visible(rotate_gizmo_instance[3], show_rotate_gizmo && arc_replaces_ring != 3); bool show_axes = spatial_editor->is_gizmo_visible() && _edit.mode != TRANSFORM_NONE; RenderingServer *rs = RenderingServer::get_singleton(); diff --git a/editor/scene/3d/node_3d_editor_plugin.h b/editor/scene/3d/node_3d_editor_plugin.h index 7a1db01d52..de5f2a9842 100644 --- a/editor/scene/3d/node_3d_editor_plugin.h +++ b/editor/scene/3d/node_3d_editor_plugin.h @@ -677,7 +677,11 @@ public: TOOL_OPT_LOCAL_COORDS, TOOL_OPT_USE_SNAP, TOOL_OPT_MAX + }; + enum TransformMode { + TRANSFORM_MODE_GLOBAL = 1, + TRANSFORM_MODE_LOCAL = 2, }; private: diff --git a/editor/settings/editor_settings.cpp b/editor/settings/editor_settings.cpp index 158df9dd9a..0412cdaebc 100644 --- a/editor/settings/editor_settings.cpp +++ b/editor/settings/editor_settings.cpp @@ -964,7 +964,8 @@ void EditorSettings::_load_defaults(Ref p_extra_config) { // 3D: Manipulator EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "editors/3d/manipulator_gizmo_size", 80, "16,160,1"); - EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/3d/manipulator_gizmo_opacity", 0.9, "0,1,0.01") + EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/3d/manipulator_gizmo_opacity", 0.9, "0,1,0.01"); + EDITOR_SETTING(Variant::INT, PROPERTY_HINT_FLAGS, "editors/3d/show_gizmo_during_rotation", 2, "Global,Local"); // 2D _initial_set("editors/2d/grid_color", Color(1.0, 1.0, 1.0, 0.07), true);