summaryrefslogtreecommitdiff
path: root/editor
diff options
context:
space:
mode:
authorRĂ©mi Verschelde <remi@verschelde.fr>2022-02-08 21:13:00 +0100
committerGitHub <noreply@github.com>2022-02-08 21:13:00 +0100
commitfaeb71865eae069c1940d0e84c35ad82591a400a (patch)
tree1ea3232804f5cab5f7e1c8994dc4b7e96cbcdc7c /editor
parent39562294ff3e6a273f9a73f97bc54791a4e98f07 (diff)
parent8345aabaf49fde32729fe168775d6a394115553b (diff)
Merge pull request #56946 from JFonS/editor_transform_improvements
Diffstat (limited to 'editor')
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp88
-rw-r--r--editor/plugins/node_3d_editor_plugin.h1
2 files changed, 61 insertions, 28 deletions
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index 67079a6965..2e8ae1a286 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -1041,24 +1041,40 @@ bool Node3DEditorViewport::_transform_gizmo_select(const Vector2 &p_screenpos, b
if (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_ROTATE) {
int col_axis = -1;
- float col_d = 1e20;
- for (int i = 0; i < 3; i++) {
- Plane plane(gt.basis.get_axis(i).normalized(), gt.origin);
- Vector3 r;
- if (!plane.intersects_ray(ray_pos, ray, &r)) {
- continue;
+ Vector3 hit_position;
+ Vector3 hit_normal;
+ real_t ray_length = gt.origin.distance_to(ray_pos) + (GIZMO_CIRCLE_SIZE * gizmo_scale) * 4.0f;
+ if (Geometry3D::segment_intersects_sphere(ray_pos, ray_pos + ray * ray_length, gt.origin, gizmo_scale * (GIZMO_CIRCLE_SIZE), &hit_position, &hit_normal)) {
+ if (hit_normal.dot(_get_camera_normal()) < 0.05) {
+ hit_position = gt.xform_inv(hit_position).abs();
+ int min_axis = hit_position.min_axis_index();
+ if (hit_position[min_axis] < gizmo_scale * GIZMO_RING_HALF_WIDTH) {
+ col_axis = min_axis;
+ }
}
+ }
- const real_t dist = r.distance_to(gt.origin);
- const Vector3 r_dir = (r - gt.origin).normalized();
+ if (col_axis == -1) {
+ float col_d = 1e20;
- if (_get_camera_normal().dot(r_dir) <= 0.005) {
- if (dist > gizmo_scale * (GIZMO_CIRCLE_SIZE - GIZMO_RING_HALF_WIDTH) && dist < gizmo_scale * (GIZMO_CIRCLE_SIZE + GIZMO_RING_HALF_WIDTH)) {
- const real_t d = ray_pos.distance_to(r);
- if (d < col_d) {
- col_d = d;
- col_axis = i;
+ for (int i = 0; i < 3; i++) {
+ Plane plane(gt.basis.get_axis(i).normalized(), gt.origin);
+ Vector3 r;
+ if (!plane.intersects_ray(ray_pos, ray, &r)) {
+ continue;
+ }
+
+ const real_t dist = r.distance_to(gt.origin);
+ const Vector3 r_dir = (r - gt.origin).normalized();
+
+ if (_get_camera_normal().dot(r_dir) <= 0.005) {
+ if (dist > gizmo_scale * (GIZMO_CIRCLE_SIZE - GIZMO_RING_HALF_WIDTH) && dist < gizmo_scale * (GIZMO_CIRCLE_SIZE + GIZMO_RING_HALF_WIDTH)) {
+ const real_t d = ray_pos.distance_to(r);
+ if (d < col_d) {
+ col_d = d;
+ col_axis = i;
+ }
}
}
}
@@ -2730,7 +2746,7 @@ void Node3DEditorViewport::_draw() {
font->draw_string(ci, msgpos, message, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, Color(1, 1, 1, 1));
}
- if (_edit.mode == TRANSFORM_ROTATE) {
+ if (_edit.mode == TRANSFORM_ROTATE && _edit.show_rotation_line) {
Point2 center = _point_to_screen(_edit.center);
Color handle_color;
@@ -4278,24 +4294,23 @@ void Node3DEditorViewport::update_transform(Point2 p_mousepos, bool p_shift) {
} break;
case TRANSFORM_ROTATE: {
- Plane plane;
- Vector3 axis;
+ Plane plane = Plane(_get_camera_normal(), _edit.center);
+ Vector3 local_axis;
+ Vector3 global_axis;
switch (_edit.plane) {
case TRANSFORM_VIEW:
- plane = Plane(_get_camera_normal(), _edit.center);
+ // local_axis unused
+ global_axis = _get_camera_normal();
break;
case TRANSFORM_X_AXIS:
- plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(0).normalized(), _edit.center);
- axis = Vector3(1, 0, 0);
+ local_axis = Vector3(1, 0, 0);
break;
case TRANSFORM_Y_AXIS:
- plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(1).normalized(), _edit.center);
- axis = Vector3(0, 1, 0);
+ local_axis = Vector3(0, 1, 0);
break;
case TRANSFORM_Z_AXIS:
- plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(2).normalized(), _edit.center);
- axis = Vector3(0, 0, 1);
+ local_axis = Vector3(0, 0, 1);
break;
case TRANSFORM_YZ:
case TRANSFORM_XZ:
@@ -4303,6 +4318,10 @@ void Node3DEditorViewport::update_transform(Point2 p_mousepos, bool p_shift) {
break;
}
+ if (_edit.plane != TRANSFORM_VIEW) {
+ global_axis = spatial_editor->get_gizmo_transform().basis.xform(local_axis).normalized();
+ }
+
Vector3 intersection;
if (!plane.intersects_ray(ray_pos, ray, &intersection)) {
break;
@@ -4313,10 +4332,22 @@ void Node3DEditorViewport::update_transform(Point2 p_mousepos, bool p_shift) {
break;
}
- Vector3 y_axis = (click - _edit.center).normalized();
- Vector3 x_axis = plane.normal.cross(y_axis).normalized();
+ static const float orthogonal_threshold = Math::cos(Math::deg2rad(87.0f));
+ bool axis_is_orthogonal = ABS(plane.normal.dot(global_axis)) < orthogonal_threshold;
- double angle = Math::atan2(x_axis.dot(intersection - _edit.center), y_axis.dot(intersection - _edit.center));
+ 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();
+ Vector3 current_axis = (intersection - _edit.center).normalized();
+ angle = click_axis.signed_angle_to(current_axis, global_axis);
+ }
if (_edit.snap || spatial_editor->is_snap_enabled()) {
snap = spatial_editor->get_rotate_snap();
@@ -4344,7 +4375,7 @@ void Node3DEditorViewport::update_transform(Point2 p_mousepos, bool p_shift) {
continue;
}
- Vector3 compute_axis = local_coords ? axis : plane.normal;
+ Vector3 compute_axis = local_coords ? local_axis : global_axis;
if (se->gizmo.is_valid()) {
for (KeyValue<int, Transform3D> &GE : se->subgizmos) {
Transform3D xform = GE.value;
@@ -4377,6 +4408,7 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito
_edit.mode = TRANSFORM_NONE;
_edit.plane = TRANSFORM_VIEW;
_edit.snap = true;
+ _edit.show_rotation_line = true;
_edit.instant = false;
_edit.gizmo_handle = -1;
_edit.gizmo_handle_secondary = false;
diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h
index 5c5980eb88..bbe5615570 100644
--- a/editor/plugins/node_3d_editor_plugin.h
+++ b/editor/plugins/node_3d_editor_plugin.h
@@ -311,6 +311,7 @@ private:
Point2 mouse_pos;
Point2 original_mouse_pos;
bool snap = false;
+ bool show_rotation_line = false;
Ref<EditorNode3DGizmo> gizmo;
int gizmo_handle = 0;
bool gizmo_handle_secondary = false;