diff options
author | Campbell Barton <ideasman42@gmail.com> | 2018-05-11 00:06:55 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2018-05-11 00:06:55 +0300 |
commit | 8c96cb55c33b4ae2d82b6b94472da8bd08b0fb34 (patch) | |
tree | 7e8e6d99fbc5a5a1cdbb6b567e6253fe70742337 | |
parent | be1af8d44c67950102fbc5b077c1b2eb642a1b17 (diff) |
Fix add-manipulator cursor plane calculation
Now use the closest plane facing the view z axis.
-rw-r--r-- | source/blender/editors/mesh/editmesh_add_manipulator.c | 57 |
1 files changed, 30 insertions, 27 deletions
diff --git a/source/blender/editors/mesh/editmesh_add_manipulator.c b/source/blender/editors/mesh/editmesh_add_manipulator.c index 3434ec82bb9..4e88df1cc5b 100644 --- a/source/blender/editors/mesh/editmesh_add_manipulator.c +++ b/source/blender/editors/mesh/editmesh_add_manipulator.c @@ -73,51 +73,54 @@ static void calc_initial_placement_point_from_view( Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); + ARegion *ar = CTX_wm_region(C); + RegionView3D *rv3d = ar->regiondata; + bool use_mouse_project = true; /* TODO: make optional */ float cursor_matrix[4][4]; + float orient_matrix[3][3]; ED_view3d_cursor3d_calc_mat4(scene, v3d, cursor_matrix); - if (use_mouse_project) { - ARegion *ar = CTX_wm_region(C); - float ray_co[3], ray_no[3]; + float dots[3] = { + dot_v3v3(rv3d->viewinv[2], cursor_matrix[0]), + dot_v3v3(rv3d->viewinv[2], cursor_matrix[1]), + dot_v3v3(rv3d->viewinv[2], cursor_matrix[2]), + }; + const int axis = axis_dominant_v3_single(dots); + + copy_v3_v3(orient_matrix[0], cursor_matrix[(axis + 1) % 3]); + copy_v3_v3(orient_matrix[1], cursor_matrix[(axis + 2) % 3]); + copy_v3_v3(orient_matrix[2], cursor_matrix[axis]); - float point_on_plane[3][3]; + if (dot_v3v3(rv3d->viewinv[2], orient_matrix[2]) < 0.0f) { + negate_v3(orient_matrix[2]); + } + if (is_negative_m3(orient_matrix)) { + swap_v3_v3(orient_matrix[0], orient_matrix[1]); + } + if (use_mouse_project) { + float ray_co[3], ray_no[3]; if (ED_view3d_win_to_ray( CTX_data_depsgraph(C), ar, v3d, mval, ray_co, ray_no, false)) { - /* Pick the plane which gives the least distant projection, - * this avoids. */ - float dist_best_sq = FLT_MAX; - int axis_best = -1; - for (int i = 0; i < 3; i++) { - float plane[4]; - plane_from_point_normal_v3(plane, cursor_matrix[3], cursor_matrix[i]); - float lambda; - if (isect_ray_plane_v3(ray_co, ray_no, plane, &lambda, true)) { - madd_v3_v3v3fl(point_on_plane[i], ray_co, ray_no, lambda); - float dist_test_sq = len_squared_v3v3(cursor_matrix[3], point_on_plane[i]); - if (dist_test_sq < dist_best_sq) { - dist_best_sq = dist_test_sq; - axis_best = i; - } - } - } - if (axis_best != -1) { - copy_v3_v3(r_location, point_on_plane[axis_best]); - /* For now always use same orientation. */ - copy_m3_m4(r_rotation, cursor_matrix); + float plane[4]; + plane_from_point_normal_v3(plane, cursor_matrix[3], orient_matrix[2]); + float lambda; + if (isect_ray_plane_v3(ray_co, ray_no, plane, &lambda, true)) { + madd_v3_v3v3fl(r_location, ray_co, ray_no, lambda); + copy_m3_m3(r_rotation, orient_matrix); + return; } - return; } } /* fallback */ copy_v3_v3(r_location, cursor_matrix[3]); - copy_m3_m4(r_rotation, cursor_matrix); + copy_m3_m3(r_rotation, orient_matrix); } /** \} */ |