From 2c9d4ef9610cbfd43488e97d3c02624d9236d59d Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Sat, 15 Aug 2020 13:18:01 +0200 Subject: [PATCH] Add an editor setting to invert 3D pan/orbit on the X axis This also makes the invert Y axis option apply to 3D panning. This closes #28082. --- editor/editor_settings.cpp | 1 + editor/plugins/node_3d_editor_plugin.cpp | 34 +++++++++++++++++------- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index f86b485dd1f..7b24e6967ad 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -543,6 +543,7 @@ void EditorSettings::_load_defaults(Ref p_extra_config) { // 3D: Navigation _initial_set("editors/3d/navigation/navigation_scheme", 0); _initial_set("editors/3d/navigation/invert_y_axis", false); + _initial_set("editors/3d/navigation/invert_x_axis", false); hints["editors/3d/navigation/navigation_scheme"] = PropertyInfo(Variant::INT, "editors/3d/navigation/navigation_scheme", PROPERTY_HINT_ENUM, "Godot,Maya,Modo"); _initial_set("editors/3d/navigation/zoom_style", 0); hints["editors/3d/navigation/zoom_style"] = PropertyInfo(Variant::INT, "editors/3d/navigation/zoom_style", PROPERTY_HINT_ENUM, "Vertical, Horizontal"); diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index b4b81cc7f0c..21a75c2f5dd 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -2059,7 +2059,12 @@ void Node3DEditorViewport::_nav_pan(Ref p_event, const camera_transform.translate(cursor.pos); camera_transform.basis.rotate(Vector3(1, 0, 0), -cursor.x_rot); camera_transform.basis.rotate(Vector3(0, 1, 0), -cursor.y_rot); - Vector3 translation(-p_relative.x * pan_speed, p_relative.y * pan_speed, 0); + const bool invert_x_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_x_axis"); + const bool invert_y_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_y_axis"); + Vector3 translation( + (invert_x_axis ? -1 : 1) * -p_relative.x * pan_speed, + (invert_y_axis ? -1 : 1) * p_relative.y * pan_speed, + 0); translation *= cursor.distance / DISTANCE_DEFAULT; camera_transform.translate(translation); cursor.pos = camera_transform.origin; @@ -2100,17 +2105,24 @@ void Node3DEditorViewport::_nav_orbit(Ref p_event, cons _menu_option(VIEW_PERSPECTIVE); } - real_t degrees_per_pixel = EditorSettings::get_singleton()->get("editors/3d/navigation_feel/orbit_sensitivity"); - real_t radians_per_pixel = Math::deg2rad(degrees_per_pixel); - bool invert_y_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_y_axis"); + const real_t degrees_per_pixel = EditorSettings::get_singleton()->get("editors/3d/navigation_feel/orbit_sensitivity"); + const real_t radians_per_pixel = Math::deg2rad(degrees_per_pixel); + const bool invert_y_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_y_axis"); + const bool invert_x_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_x_axis"); if (invert_y_axis) { cursor.x_rot -= p_relative.y * radians_per_pixel; } else { cursor.x_rot += p_relative.y * radians_per_pixel; } - cursor.y_rot += p_relative.x * radians_per_pixel; + // Clamp the Y rotation to roughly -90..90 degrees so the user can't look upside-down and end up disoriented. cursor.x_rot = CLAMP(cursor.x_rot, -1.57, 1.57); + + if (invert_x_axis) { + cursor.y_rot -= p_relative.x * radians_per_pixel; + } else { + cursor.y_rot += p_relative.x * radians_per_pixel; + } name = ""; _update_name(); } @@ -2125,21 +2137,23 @@ void Node3DEditorViewport::_nav_look(Ref p_event, const _menu_option(VIEW_PERSPECTIVE); } - real_t degrees_per_pixel = EditorSettings::get_singleton()->get("editors/3d/freelook/freelook_sensitivity"); - real_t radians_per_pixel = Math::deg2rad(degrees_per_pixel); - bool invert_y_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_y_axis"); + const real_t degrees_per_pixel = EditorSettings::get_singleton()->get("editors/3d/freelook/freelook_sensitivity"); + const real_t radians_per_pixel = Math::deg2rad(degrees_per_pixel); + const bool invert_y_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_y_axis"); // Note: do NOT assume the camera has the "current" transform, because it is interpolated and may have "lag". - Transform prev_camera_transform = to_camera_transform(cursor); + const Transform prev_camera_transform = to_camera_transform(cursor); if (invert_y_axis) { cursor.x_rot -= p_relative.y * radians_per_pixel; } else { cursor.x_rot += p_relative.y * radians_per_pixel; } - cursor.y_rot += p_relative.x * radians_per_pixel; + // Clamp the Y rotation to roughly -90..90 degrees so the user can't look upside-down and end up disoriented. cursor.x_rot = CLAMP(cursor.x_rot, -1.57, 1.57); + cursor.y_rot += p_relative.x * radians_per_pixel; + // Look is like the opposite of Orbit: the focus point rotates around the camera Transform camera_transform = to_camera_transform(cursor); Vector3 pos = camera_transform.xform(Vector3(0, 0, 0));