Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2017-06-17 07:31:27 +0300
committerCampbell Barton <ideasman42@gmail.com>2017-06-17 07:34:23 +0300
commit865bf8ecbc1cf3aac3107cbb70b2e94d8e239adc (patch)
treeaa1a96c1d770cf16183fe6b598f93a899dd06474 /source/blender
parent57c9bc9bb0b4caedd850d0f6797d3d010217bd78 (diff)
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.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/editors/manipulator_library/dial3d_manipulator.c55
1 files changed, 37 insertions, 18 deletions
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;