Page Menu
Home
Search
Configure Global Search
Log In
Paste
P2081
Trackpad: precise rotation and magnification
Archived
Public
Actions
Authored by
Yevgeny Makarov (jenkm)
on Apr 21 2021, 10:27 AM.
Edit Paste
Activate Paste
View Raw File
Subscribe
Mute Notifications
Award Token
Tags
None
Subscribers
None
diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c
--- a/source/blender/editors/interface/view2d_ops.c
+++ b/source/blender/editors/interface/view2d_ops.c
@@ -1245,7 +1245,7 @@ static int view_zoomdrag_invoke(bContext *C, wmOperator *op, const wmEvent *even
}
}
else { /* MOUSEZOOM */
- facx = facy = zoomfac * WM_event_absolute_delta_x(event);
+ facx = facy = event->factor;
}
/* Only respect user setting zoom axis if the view does not have any zoom restrictions
diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c
--- a/source/blender/editors/space_clip/clip_ops.c
+++ b/source/blender/editors/space_clip/clip_ops.c
@@ -619,13 +619,24 @@ static int view_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *event)
if (ELEM(event->type, MOUSEZOOM, MOUSEPAN)) {
float delta, factor;
- delta = event->prevx - event->x + event->prevy - event->y;
+ if (event->type == MOUSEPAN) {
+ if (U.uiflag & USER_ZOOM_HORIZ) {
+ delta = WM_event_absolute_delta_x(event) / U.dpi_fac;
+ }
+ else {
+ delta = WM_event_absolute_delta_y(event) / U.dpi_fac;
+ }
+
+ if (U.uiflag & USER_ZOOM_INVERT) {
+ delta *= -1.0f;
+ }
- if (U.uiflag & USER_ZOOM_INVERT) {
- delta *= -1;
+ factor = 1.0f + delta / 150.0f;
+ }
+ else { /* MOUSEZOOM */
+ factor = 1.0f + event->factor;
}
- factor = 1.0f + delta / 300.0f;
RNA_float_set(op->ptr, "factor", factor);
sclip_zoom_set_factor_exec(C, event, factor);
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -584,13 +584,24 @@ static int image_view_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *ev
UI_view2d_region_to_view(
®ion->v2d, event->mval[0], event->mval[1], &location[0], &location[1]);
- delta = event->prevx - event->x + event->prevy - event->y;
+ if (event->type == MOUSEPAN) {
+ if (U.uiflag & USER_ZOOM_HORIZ) {
+ delta = WM_event_absolute_delta_x(event) / U.dpi_fac;
+ }
+ else {
+ delta = WM_event_absolute_delta_y(event) / U.dpi_fac;
+ }
- if (U.uiflag & USER_ZOOM_INVERT) {
- delta *= -1;
+ if (U.uiflag & USER_ZOOM_INVERT) {
+ delta *= -1.0f;
+ }
+
+ factor = 1.0f + delta / 150.0f;
+ }
+ else { /* MOUSEZOOM */
+ factor = 1.0f + event->factor;
}
- factor = 1.0f + delta / 300.0f;
RNA_float_set(op->ptr, "factor", factor);
const bool use_cursor_init = RNA_boolean_get(op->ptr, "use_cursor_init");
sima_zoom_set(sima,
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -140,6 +140,7 @@ enum eV3D_OpPropFlag {
V3D_OP_PROP_DELTA = (1 << 1),
V3D_OP_PROP_USE_ALL_REGIONS = (1 << 2),
V3D_OP_PROP_USE_MOUSE_INIT = (1 << 3),
+ V3D_OP_PROP_FACTOR = (1 << 4),
};
static void view3d_operator_properties_common(wmOperatorType *ot, const enum eV3D_OpPropFlag flag)
@@ -154,6 +155,9 @@ static void view3d_operator_properties_common(wmOperatorType *ot, const enum eV3
if (flag & V3D_OP_PROP_DELTA) {
RNA_def_int(ot->srna, "delta", 0, INT_MIN, INT_MAX, "Delta", "", INT_MIN, INT_MAX);
}
+ if (flag & V3D_OP_PROP_FACTOR) {
+ RNA_def_float(ot->srna, "factor", 0.0f, -FLT_MAX, FLT_MAX, "Factor", "", -FLT_MAX, FLT_MAX);
+ }
if (flag & V3D_OP_PROP_USE_ALL_REGIONS) {
PropertyRNA *prop;
prop = RNA_def_boolean(
@@ -772,13 +776,13 @@ static void viewrotate_apply_snap(ViewOpsData *vod)
}
}
-static void viewrotate_apply(ViewOpsData *vod, const int event_xy[2])
+static void viewrotate_apply(ViewOpsData *vod, const int event_xy[2], const float degrees)
{
RegionView3D *rv3d = vod->rv3d;
rv3d->view = RV3D_VIEW_USER; /* need to reset every time because of view snapping */
- if (U.flag & USER_TRACKBALL) {
+ if ((U.flag & USER_TRACKBALL) && !degrees) {
float axis[3], q1[4], dvec[3], newvec[3];
float angle;
@@ -819,6 +823,7 @@ static void viewrotate_apply(ViewOpsData *vod, const int event_xy[2])
float m_inv[3][3];
const float zvec_global[3] = {0.0f, 0.0f, 1.0f};
float xaxis[3];
+ float angle_x, angle_z;
/* Radians per-pixel. */
const float sensitivity = U.view_rotate_sensitivity_turntable / U.dpi_fac;
@@ -872,16 +877,25 @@ static void viewrotate_apply(ViewOpsData *vod, const int event_xy[2])
copy_v3_v3(xaxis, m_inv[0]);
#endif
+ /* MOUSEROTATE performs an orbital rotation directly using degrees. */
+ if (degrees) {
+ angle_x = 0.0f;
+ angle_z = vod->reverse * DEG2RADF(degrees);
+ }
+ else {
+ angle_x = sensitivity * -(event_xy[1] - vod->prev.event_xy[1]);
+ angle_z = sensitivity * vod->reverse * (event_xy[0] - vod->prev.event_xy[0]);
+ }
+
/* Determine the direction of the x vector (for rotating up and down) */
/* This can likely be computed directly from the quaternion. */
/* Perform the up/down rotation */
- axis_angle_to_quat(quat_local_x, xaxis, sensitivity * -(event_xy[1] - vod->prev.event_xy[1]));
+ axis_angle_to_quat(quat_local_x, xaxis, angle_x);
mul_qt_qtqt(quat_local_x, vod->curr.viewquat, quat_local_x);
/* Perform the orbital rotation */
- axis_angle_to_quat_single(
- quat_global_z, 'Z', sensitivity * vod->reverse * (event_xy[0] - vod->prev.event_xy[0]));
+ axis_angle_to_quat_single(quat_global_z, 'Z', angle_z);
mul_qt_qtqt(vod->curr.viewquat, quat_local_x, quat_global_z);
viewrotate_apply_dyn_ofs(vod, vod->curr.viewquat);
@@ -947,7 +961,7 @@ static int viewrotate_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
if (event_code == VIEW_APPLY) {
- viewrotate_apply(vod, &event->x);
+ viewrotate_apply(vod, &event->x, 0.0f);
if (ED_screen_animation_playing(CTX_wm_manager(C))) {
use_autokey = true;
}
@@ -998,22 +1012,16 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
int event_xy[2];
if (event->type == MOUSEPAN) {
- if (event->is_direction_inverted) {
- event_xy[0] = 2 * event->x - event->prevx;
- event_xy[1] = 2 * event->y - event->prevy;
- }
- else {
- event_xy[0] = event->prevx;
- event_xy[1] = event->prevy;
- }
+ event_xy[0] = event->x + WM_event_absolute_delta_x(event);
+ event_xy[1] = event->y + WM_event_absolute_delta_y(event);
}
else {
- /* MOUSEROTATE performs orbital rotation, so y axis delta is set to 0 */
- event_xy[0] = event->prevx;
+ /* MOUSEROTATE performs orbital rotation directly using 'factor' in degrees. */
+ event_xy[0] = event->x;
event_xy[1] = event->y;
}
- viewrotate_apply(vod, event_xy);
+ viewrotate_apply(vod, event_xy, event->factor);
ED_view3d_depth_tag_update(vod->rv3d);
viewops_data_free(C, op);
@@ -2313,8 +2321,15 @@ static int viewzoom_exec(bContext *C, wmOperator *op)
ED_view3d_dist_range_get(v3d, dist_range);
- if (delta < 0) {
- const float step = 1.2f;
+ float step;
+ if (RNA_struct_property_is_set(op->ptr, "factor")) { /* MOUSEZOOM */
+ step = 1.0f - RNA_float_get(op->ptr, "factor");
+ }
+ else {
+ step = delta < 0 ? 1.2f : 1.0f / 1.2f;
+ }
+
+ if (step > 1.0f) {
/* this min and max is also in viewmove() */
if (use_cam_zoom) {
view_zoom_to_window_xy_camera(scene, depsgraph, v3d, region, step, zoom_xy);
@@ -2326,7 +2341,6 @@ static int viewzoom_exec(bContext *C, wmOperator *op)
}
}
else {
- const float step = 1.0f / 1.2f;
if (use_cam_zoom) {
view_zoom_to_window_xy_camera(scene, depsgraph, v3d, region, step, zoom_xy);
}
@@ -2380,19 +2394,18 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, const wmEvent *event)
if (RNA_struct_property_is_set(op->ptr, "delta")) {
viewzoom_exec(C, op);
}
- else {
- if (ELEM(event->type, MOUSEZOOM, MOUSEPAN)) {
+ else if (event->type == MOUSEZOOM) {
+ RNA_float_set(op->ptr, "factor", event->factor);
+ viewzoom_exec(C, op);
+ }
+ else if (event->type == MOUSEPAN) {
+ int event_xy[2];
+
+ event_xy[0] = event->x + WM_event_absolute_delta_x(event);
+ event_xy[1] = event->y + WM_event_absolute_delta_y(event);
- if (U.uiflag & USER_ZOOM_HORIZ) {
- vod->init.event_xy[0] = vod->prev.event_xy[0] = event->x;
- }
- else {
- /* Set y move = x move as MOUSEZOOM uses only x axis to pass magnification value */
- vod->init.event_xy[1] = vod->prev.event_xy[1] = vod->init.event_xy[1] + event->x -
- event->prevx;
- }
viewzoom_apply(vod,
- &event->prevx,
+ event_xy,
USER_ZOOM_DOLLY,
(U.uiflag & USER_ZOOM_INVERT) != 0,
(use_cursor_init && (U.uiflag & USER_ZOOM_TO_MOUSEPOS)));
@@ -2401,9 +2414,8 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, const wmEvent *event)
ED_view3d_depth_tag_update(vod->rv3d);
viewops_data_free(C, op);
- return OPERATOR_FINISHED;
- }
-
+ }
+ else {
if (U.viewzoom == USER_ZOOM_CONTINUE) {
/* needs a timer to continue redrawing */
vod->timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f);
@@ -2442,7 +2454,7 @@ void VIEW3D_OT_zoom(wmOperatorType *ot)
/* properties */
view3d_operator_properties_common(
- ot, V3D_OP_PROP_DELTA | V3D_OP_PROP_MOUSE_CO | V3D_OP_PROP_USE_MOUSE_INIT);
+ ot, V3D_OP_PROP_DELTA | V3D_OP_PROP_FACTOR | V3D_OP_PROP_MOUSE_CO | V3D_OP_PROP_USE_MOUSE_INIT);
}
/** \} */
@@ -2630,7 +2642,15 @@ static int viewdolly_exec(bContext *C, wmOperator *op)
negate_v3(mousevec);
}
- view_dolly_to_vector_3d(region, rv3d->ofs, mousevec, delta < 0 ? 1.8f : 0.2f);
+ float fac;
+ if (RNA_struct_property_is_set(op->ptr, "factor")) { /* MOUSEZOOM */
+ fac = 1.0f - RNA_float_get(op->ptr, "factor");
+ }
+ else {
+ fac = delta < 0 ? 1.8f : 0.2f;
+ }
+
+ view_dolly_to_vector_3d(region, rv3d->ofs, mousevec, fac);
if (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXVIEW) {
view3d_boxview_sync(area, region);
@@ -2699,6 +2719,10 @@ static int viewdolly_invoke(bContext *C, wmOperator *op, const wmEvent *event)
if (RNA_struct_property_is_set(op->ptr, "delta")) {
viewdolly_exec(C, op);
}
+ else if (event->type == MOUSEZOOM) {
+ RNA_float_set(op->ptr, "factor", event->factor);
+ viewdolly_exec(C, op);
+ }
else {
/* overwrite the mouse vector with the view direction (zoom into the center) */
if ((use_cursor_init && (U.uiflag & USER_ZOOM_TO_MOUSEPOS)) == 0) {
@@ -2706,18 +2730,13 @@ static int viewdolly_invoke(bContext *C, wmOperator *op, const wmEvent *event)
normalize_v3(vod->init.mousevec);
}
- if (event->type == MOUSEZOOM) {
- /* Bypass Zoom invert flag for track pads (pass false always) */
+ if (event->type == MOUSEPAN) {
+ int event_xy[2];
- if (U.uiflag & USER_ZOOM_HORIZ) {
- vod->init.event_xy[0] = vod->prev.event_xy[0] = event->x;
- }
- else {
- /* Set y move = x move as MOUSEZOOM uses only x axis to pass magnification value */
- vod->init.event_xy[1] = vod->prev.event_xy[1] = vod->init.event_xy[1] + event->x -
- event->prevx;
- }
- viewdolly_apply(vod, &event->prevx, (U.uiflag & USER_ZOOM_INVERT) == 0);
+ event_xy[0] = event->x + WM_event_absolute_delta_x(event);
+ event_xy[1] = event->y + WM_event_absolute_delta_y(event);
+
+ viewdolly_apply(vod, event_xy, (U.uiflag & USER_ZOOM_INVERT) != 0);
ED_view3d_depth_tag_update(vod->rv3d);
viewops_data_free(C, op);
@@ -2755,7 +2774,7 @@ void VIEW3D_OT_dolly(wmOperatorType *ot)
/* properties */
view3d_operator_properties_common(
- ot, V3D_OP_PROP_DELTA | V3D_OP_PROP_MOUSE_CO | V3D_OP_PROP_USE_MOUSE_INIT);
+ ot, V3D_OP_PROP_DELTA | V3D_OP_PROP_FACTOR | V3D_OP_PROP_MOUSE_CO | V3D_OP_PROP_USE_MOUSE_INIT);
}
/** \} */
@@ -4364,11 +4383,15 @@ static void view_roll_angle(
rv3d->view = RV3D_VIEW_USER;
}
-static void viewroll_apply(ViewOpsData *vod, int x, int UNUSED(y))
+static void viewroll_apply(ViewOpsData *vod, int x, int UNUSED(y), const float degrees)
{
float angle = 0.0;
- {
+ /* MOUSEROTATE uses the rotation factor in degrees. */
+ if (degrees) {
+ angle = -DEG2RADF(degrees);
+ }
+ else {
float len1, len2, tot;
tot = vod->region->winrct.xmax - vod->region->winrct.xmin;
@@ -4426,7 +4449,7 @@ static int viewroll_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
if (event_code == VIEW_APPLY) {
- viewroll_apply(vod, event->x, event->y);
+ viewroll_apply(vod, event->x, event->y, 0.0f);
if (ED_screen_animation_playing(CTX_wm_manager(C))) {
use_autokey = true;
}
@@ -4539,7 +4562,7 @@ static int viewroll_invoke(bContext *C, wmOperator *op, const wmEvent *event)
if (event->type == MOUSEROTATE) {
vod->init.event_xy[0] = vod->prev.event_xy[0] = event->x;
- viewroll_apply(vod, event->prevx, event->prevy);
+ viewroll_apply(vod, event->x, event->y, event->factor);
ED_view3d_depth_tag_update(vod->rv3d);
viewops_data_free(C, op);
Event Timeline
Yevgeny Makarov (jenkm)
created this paste.
Apr 21 2021, 10:27 AM
Yevgeny Makarov (jenkm)
mentioned this in
D8521: Trackpad support improvements
.
Apr 21 2021, 10:38 AM
Yevgeny Makarov (jenkm)
mentioned this in
T82006: Trackpad Support Improvement (Parent Task)
.
Apr 21 2021, 11:06 AM
Yevgeny Makarov (jenkm)
archived this paste.
Oct 15 2021, 1:42 PM
Log In to Comment