diff options
author | Campbell Barton <ideasman42@gmail.com> | 2020-01-15 12:08:58 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2020-01-15 12:10:58 +0300 |
commit | c0793d662935ce6bf2de7f1c9e684a0b40ce3add (patch) | |
tree | 0948adaa41db35a46130d8fc369a7636ae11d403 /source | |
parent | 5977ed34709ce56823ef755d9c702b8cebba1edd (diff) |
Fix T72419: 3D cursor placement flips axis with geometry orientation
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/editors/space_view3d/view3d_edit.c | 38 |
1 files changed, 29 insertions, 9 deletions
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 6d0b0e8e00a..3dcde401216 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -4968,10 +4968,9 @@ void ED_view3d_cursor3d_position_rotation(bContext *C, copy_v3_v3(cursor_co, ray_co); } - float tquat[4]; - /* Math normal (Z). */ { + float tquat[4]; float z_src[3] = {0, 0, 1}; mul_qt_v3(cursor_quat, z_src); rotation_between_vecs_to_quat(tquat, z_src, ray_no); @@ -4986,13 +4985,34 @@ void ED_view3d_cursor3d_position_rotation(bContext *C, dot_v3v3(ray_no, obmat[2]), }; const int ortho_axis = axis_dominant_v3_ortho_single(ortho_axis_dot); - float x_src[3] = {1, 0, 0}; - float x_dst[3]; - mul_qt_v3(cursor_quat, x_src); - project_plane_v3_v3v3(x_dst, obmat[ortho_axis], ray_no); - normalize_v3(x_dst); - rotation_between_vecs_to_quat(tquat, x_src, x_dst); - mul_qt_qtqt(cursor_quat, tquat, cursor_quat); + + float tquat_best[4]; + float angle_best = -1.0f; + + float tan_dst[3]; + project_plane_v3_v3v3(tan_dst, obmat[ortho_axis], ray_no); + normalize_v3(tan_dst); + + /* As the tangent is arbitrary from the users point of view, + * make the cursor 'roll' on the shortest angle. + * otherwise this can cause noticeable 'flipping', see T72419. */ + for (int axis = 0; axis < 2; axis++) { + float tan_src[3] = {0, 0, 0}; + tan_src[axis] = 1.0f; + mul_qt_v3(cursor_quat, tan_src); + + for (int axis_sign = 0; axis_sign < 2; axis_sign++) { + float tquat_test[4]; + rotation_between_vecs_to_quat(tquat_test, tan_src, tan_dst); + const float angle_test = angle_normalized_qt(tquat_test); + if (angle_test < angle_best || angle_best == -1.0f) { + angle_best = angle_test; + copy_qt_qt(tquat_best, tquat_test); + } + negate_v3(tan_src); + } + } + mul_qt_qtqt(cursor_quat, tquat_best, cursor_quat); } } ED_transform_snap_object_context_destroy(snap_context); |