Merge pull request #116075 from ryevdokimov/arc-sync

Fix gizmo rotation arc and applied transform not being in sync
This commit is contained in:
Thaddeus Crews 2026-02-12 08:19:15 -06:00
commit 3294d50d82
No known key found for this signature in database
GPG key ID: 8C6E5FEB5FC03CCC
2 changed files with 29 additions and 28 deletions

View file

@ -1478,6 +1478,7 @@ bool Node3DEditorViewport::_transform_gizmo_select(const Vector2 &p_screenpos, b
_compute_edit(p_screenpos);
_edit.plane = TRANSFORM_VIEW;
_edit.accumulated_rotation_angle = 0.0;
_edit.rotation_angle = 0.0;
_edit.rotation_axis = _get_camera_normal();
_edit.view_axis_local = spatial_editor->get_gizmo_transform().basis.xform_inv(_get_camera_normal()).normalized();
_edit.gizmo_initiated = true;
@ -1493,6 +1494,7 @@ bool Node3DEditorViewport::_transform_gizmo_select(const Vector2 &p_screenpos, b
_edit.is_trackball = true;
_edit.show_rotation_line = false;
_edit.accumulated_rotation_angle = 0.0;
_edit.rotation_angle = 0.0;
_edit.rotation_axis = _get_camera_normal();
_edit.gizmo_initiated = true;
spatial_editor->select_gizmo_highlight_axis(-1);
@ -1507,6 +1509,7 @@ bool Node3DEditorViewport::_transform_gizmo_select(const Vector2 &p_screenpos, b
_compute_edit(p_screenpos);
_edit.plane = TransformPlane(TRANSFORM_X_AXIS + col_axis);
_edit.accumulated_rotation_angle = 0.0;
_edit.rotation_angle = 0.0;
_edit.rotation_axis = gt.basis.get_column(col_axis).normalized();
_edit.gizmo_initiated = true;
}
@ -2752,7 +2755,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
_edit.initial_click_vector = Vector3();
_edit.previous_rotation_vector = Vector3();
_edit.accumulated_rotation_angle = 0.0;
_edit.display_rotation_angle = 0.0;
_edit.rotation_angle = 0.0;
set_message(vformat(TTR("Rotating %s degrees."), String::num(0, 0)));
}
surface->queue_redraw();
@ -3834,7 +3837,7 @@ void Node3DEditorViewport::_draw() {
}
const int segments = 64;
float display_angle = _edit.display_rotation_angle;
float display_angle = _edit.rotation_angle;
float abs_angle = Math::abs(display_angle);
if (abs_angle > Math::TAU) {
@ -3862,12 +3865,11 @@ void Node3DEditorViewport::_draw() {
Vector3 point1_3d = _edit.center + gizmo_scale * rotation_radius * (right * Math::cos(angle1) + forward * Math::sin(angle1));
Vector3 point2_3d = _edit.center + gizmo_scale * rotation_radius * (right * Math::cos(angle2) + forward * Math::sin(angle2));
Point2 center_2d = center;
Point2 point1_2d = point_to_screen(point1_3d);
Point2 point2_2d = point_to_screen(point2_3d);
Vector<Point2> triangle_points;
triangle_points.push_back(center_2d);
triangle_points.push_back(center);
triangle_points.push_back(point1_2d);
triangle_points.push_back(point2_2d);
@ -5680,7 +5682,7 @@ void Node3DEditorViewport::begin_transform(TransformMode p_mode, bool instant) {
_edit.initial_click_vector = Vector3();
_edit.previous_rotation_vector = Vector3();
_edit.accumulated_rotation_angle = 0.0;
_edit.display_rotation_angle = 0.0;
_edit.rotation_angle = 0.0;
_edit.gizmo_initiated = false;
switch (p_mode) {
case TRANSFORM_ROTATE:
@ -6040,25 +6042,12 @@ void Node3DEditorViewport::update_transform(bool p_shift) {
}
_edit.previous_rotation_vector = current_rotation_vector;
_edit.accumulated_rotation_angle = 0.0;
_edit.display_rotation_angle = 0.0;
_edit.rotation_angle = 0.0;
}
static const float orthogonal_threshold = Math::cos(Math::deg_to_rad(85.0f));
bool axis_is_orthogonal = Math::abs(plane.normal.dot(global_axis)) < orthogonal_threshold;
double angle = 0.0f;
if (axis_is_orthogonal) {
_edit.show_rotation_line = false;
Vector3 projection_axis = plane.normal.cross(global_axis);
Vector3 delta = intersection - click;
float projection = delta.dot(projection_axis);
angle = (projection * (Math::PI / 2.0f)) / (gizmo_scale * GIZMO_CIRCLE_SIZE);
} else {
_edit.show_rotation_line = true;
Vector3 click_axis = (click - _edit.center).normalized();
angle = click_axis.signed_angle_to(current_rotation_vector, global_axis);
}
if (_edit.previous_rotation_vector != Vector3()) {
double delta_angle = _edit.previous_rotation_vector.signed_angle_to(current_rotation_vector, global_axis);
_edit.accumulated_rotation_angle += delta_angle;
@ -6068,16 +6057,28 @@ void Node3DEditorViewport::update_transform(bool p_shift) {
bool snapping = _edit.snap || spatial_editor->is_snap_enabled();
if (snapping) {
snap = spatial_editor->get_rotate_snap();
_edit.display_rotation_angle = Math::deg_to_rad(Math::snapped(Math::rad_to_deg(_edit.accumulated_rotation_angle), snap));
} else {
_edit.display_rotation_angle = _edit.accumulated_rotation_angle;
snap_step_decimals = Math::range_step_decimals(snap);
}
angle = Math::snapped(Math::rad_to_deg(angle), snap);
set_message(vformat(TTR("Rotating %s degrees."), String::num(angle, snap_step_decimals)));
angle = Math::deg_to_rad(angle);
if (axis_is_orthogonal) {
_edit.show_rotation_line = false;
Vector3 projection_axis = plane.normal.cross(global_axis);
Vector3 delta = intersection - click;
float projection = delta.dot(projection_axis);
double orth_angle = (projection * (Math::PI / 2.0f)) / (gizmo_scale * GIZMO_CIRCLE_SIZE);
_edit.rotation_angle = snapping
? Math::deg_to_rad(Math::snapped(Math::rad_to_deg(orth_angle), snap))
: orth_angle;
} else {
_edit.show_rotation_line = true;
_edit.rotation_angle = snapping
? Math::deg_to_rad(Math::snapped(Math::rad_to_deg(_edit.accumulated_rotation_angle), snap))
: _edit.accumulated_rotation_angle;
}
set_message(vformat(TTR("Rotating %s degrees."), String::num(Math::rad_to_deg(_edit.rotation_angle), snap_step_decimals)));
Vector3 compute_axis = local_coords ? local_axis : global_axis;
apply_transform(compute_axis, angle);
apply_transform(compute_axis, _edit.rotation_angle);
} break;
default: {
}
@ -6158,7 +6159,7 @@ void Node3DEditorViewport::finish_transform() {
_edit.initial_click_vector = Vector3();
_edit.previous_rotation_vector = Vector3();
_edit.accumulated_rotation_angle = 0.0;
_edit.display_rotation_angle = 0.0;
_edit.rotation_angle = 0.0;
_edit.gizmo_initiated = false;
spatial_editor->set_local_coords_enabled(_edit.original_local);
spatial_editor->update_transform_gizmo();