Commit: 865bf8ecbc1cf3aac3107cbb70b2e94d8e239adc
Author: Campbell Barton
Date:   Sat Jun 17 14:31:27 2017 +1000
Branches: blender2.8
https://developer.blender.org/rB865bf8ecbc1cf3aac3107cbb70b2e94d8e239adc

Manipulator: correct dial angle

Calculation was done in screen-space giving inaccuracy,
making the angle incorrect for tool code.

Cast mouse coords onto the dial plane to calculate the angle instead.

===================================================================

M       source/blender/editors/manipulator_library/dial3d_manipulator.c

===================================================================

diff --git a/source/blender/editors/manipulator_library/dial3d_manipulator.c 
b/source/blender/editors/manipulator_library/dial3d_manipulator.c
index b3b78826650..a0317fc34b2 100644
--- a/source/blender/editors/manipulator_library/dial3d_manipulator.c
+++ b/source/blender/editors/manipulator_library/dial3d_manipulator.c
@@ -188,38 +188,51 @@ static void dial_ghostarc_draw(
 }
 
 static void dial_ghostarc_get_angles(
-        const DialManipulator *dial, const wmEvent *event, const ARegion *ar,
+        const DialManipulator *dial, const wmEvent *event,
+        const ARegion *ar, const View3D *v3d,
         float mat[4][4], const float co_outer[3],
         float *r_start, float *r_delta)
 {
        DialInteraction *inter = dial->manipulator.interaction_data;
        const RegionView3D *rv3d = ar->regiondata;
        const float mval[2] = {event->x - ar->winrct.xmin, event->y - 
ar->winrct.ymin};
-       bool inv = false;
 
        /* we might need to invert the direction of the angles */
        float view_vec[3], axis_vec[3];
        ED_view3d_global_to_vector(rv3d, dial->manipulator.origin, view_vec);
        normalize_v3_v3(axis_vec, dial->direction);
-       if (dot_v3v3(view_vec, axis_vec) < 0.0f) {
-               inv = true;
-       }
 
-       float co[3], origin2d[2], co2d[2];
-       mul_v3_project_m4_v3(co, mat, co_outer);
-       /* project 3d coordinats to 2d viewplane */
-       ED_view3d_project_float_global(ar, dial->manipulator.origin, origin2d, 
V3D_PROJ_TEST_NOP);
-       ED_view3d_project_float_global(ar, co, co2d, V3D_PROJ_TEST_NOP);
+       float proj_outer_rel[3];
+       mul_v3_project_m4_v3(proj_outer_rel, mat, co_outer);
+       sub_v3_v3(proj_outer_rel, dial->manipulator.origin);
+
+       float proj_mval_new_rel[3];
+       float proj_mval_init_rel[3];
+       float dial_plane[4];
+       float ray_co[3], ray_no[3];
+       float ray_lambda;
+
+       plane_from_point_normal_v3(dial_plane, dial->manipulator.origin, 
axis_vec);
 
-       /* convert to manipulator relative space */
-       float rel_initmval[2], rel_mval[2], rel_co[2];
-       sub_v2_v2v2(rel_initmval, inter->init_mval, origin2d);
-       sub_v2_v2v2(rel_mval, mval, origin2d);
-       sub_v2_v2v2(rel_co, co2d, origin2d);
+       if (!ED_view3d_win_to_ray(ar, v3d, inter->init_mval, ray_co, ray_no, 
false) ||
+               !isect_ray_plane_v3(ray_co, ray_no, dial_plane, &ray_lambda, 
false))
+       {
+               goto fail;
+       }
+       madd_v3_v3v3fl(proj_mval_init_rel, ray_co, ray_no, ray_lambda);
+       sub_v3_v3(proj_mval_init_rel, dial->manipulator.origin);
+
+       if (!ED_view3d_win_to_ray(ar, v3d, mval, ray_co, ray_no, false) ||
+               !isect_ray_plane_v3(ray_co, ray_no, dial_plane, &ray_lambda, 
false))
+       {
+               goto fail;
+       }
+       madd_v3_v3v3fl(proj_mval_new_rel, ray_co, ray_no, ray_lambda);
+       sub_v3_v3(proj_mval_new_rel, dial->manipulator.origin);
 
        /* return angles */
-       const float start = angle_signed_v2v2(rel_co, rel_initmval) * (inv ? -1 
: 1);
-       const float delta = angle_signed_v2v2(rel_initmval, rel_mval) * (inv ? 
-1 : 1);
+       const float start = 
angle_wrap_rad(angle_signed_on_axis_v3v3_v3(proj_outer_rel, proj_mval_init_rel, 
axis_vec));
+       const float delta = 
angle_wrap_rad(angle_signed_on_axis_v3v3_v3(proj_mval_init_rel, 
proj_mval_new_rel, axis_vec));
 
        /* Change of sign, we passed the 180 degree threshold. This means we 
need to add a turn
         * to distinguish between transition from 0 to -1 and -PI to +PI, use 
comparison with PI/2.
@@ -236,6 +249,12 @@ static void dial_ghostarc_get_angles(
 
        *r_start = start;
        *r_delta = fmod(delta + 2.0f * (float)M_PI * inter->rotations, 2 * 
(float)M_PI);
+       return;
+
+       /* If we can't project (unlikely). */
+fail:
+       *r_start = 0.0;
+       *r_delta = 0.0;
 }
 
 static void dial_draw_intern(
@@ -350,7 +369,7 @@ static void manipulator_dial_modal(bContext *C, 
wmManipulator *mpr, const wmEven
 
        dial_calc_matrix(dial, mat);
 
-       dial_ghostarc_get_angles(dial, event, CTX_wm_region(C), mat, co_outer, 
&angle_ofs, &angle_delta);
+       dial_ghostarc_get_angles(dial, event, CTX_wm_region(C), 
CTX_wm_view3d(C), mat, co_outer, &angle_ofs, &angle_delta);
 
        DialInteraction *inter = dial->manipulator.interaction_data;

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to