diff options
author | Ton Roosendaal <ton@blender.org> | 2012-12-29 16:33:24 +0400 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2012-12-29 16:33:24 +0400 |
commit | 31933e747f32c8d2d5f60a523ed063d0b8e96697 (patch) | |
tree | a9f8493236b2623a61da9bd23e996fa1922fd490 /source/blender/editors/space_view3d | |
parent | 4ed4be1fc225e714e21445b82fa129c26552d449 (diff) |
Bug fix #32806
In 2.64, input for using an NDOF device included all 6 DOFs - including panning.
That makes using it for many people (including beginners like me) too hard, you
very quickly lose the 3d view rotation pivot, as if you are in free fly mode.
Fredrik provided an updated patch, which restores the 2.63 method to only
dolly and rotate by default. The new "all dof" operator is hidden in the keymaps
behind modifier keys SHIFT + CTRL. Users can set this in their configs of course.
As usual, we should be careful changing accepted defaults, and provide new
options as additional choice only.
A useful todo is to make user preference "around selection" work well.
Will check on this now too.
Diffstat (limited to 'source/blender/editors/space_view3d')
-rw-r--r-- | source/blender/editors/space_view3d/view3d_edit.c | 170 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_intern.h | 1 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_ops.c | 4 |
3 files changed, 174 insertions, 1 deletions
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 913cf3087bb..f846abdf859 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -1161,6 +1161,176 @@ void VIEW3D_OT_ndof_orbit(struct wmOperatorType *ot) ot->flag = 0; } + +static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + ViewOpsData *vod = op->customdata; + + if (event->type != NDOF_MOTION) + return OPERATOR_CANCELLED; + else { + View3D *v3d = CTX_wm_view3d(C); + RegionView3D *rv3d = CTX_wm_region_view3d(C); + wmNDOFMotionData *ndof = (wmNDOFMotionData *) event->customdata; + + ED_view3d_camera_lock_init(v3d, rv3d); + + rv3d->rot_angle = 0.f; /* off by default, until changed later this function */ + + if (ndof->progress != P_FINISHING) { + const float dt = ndof->dt; + + /* tune these until everything feels right */ + const float rot_sensitivity = 1.f; + + const float zoom_sensitivity = 1.f; + + const float pan_sensitivity = 1.f; + const int has_rotation = rv3d->viewlock != RV3D_LOCKED && !is_zero_v3(ndof->rvec); + + float view_inv[4]; + invert_qt_qt(view_inv, rv3d->viewquat); + + /* #define DEBUG_NDOF_MOTION */ + #ifdef DEBUG_NDOF_MOTION + printf("ndof: T=(%.2f,%.2f,%.2f) R=(%.2f,%.2f,%.2f) dt=%.3f delivered to 3D view\n", + ndof->tx, ndof->ty, ndof->tz, ndof->rx, ndof->ry, ndof->rz, ndof->dt); + #endif + + if (ndof->tz) { + /* Zoom! + * velocity should be proportional to the linear velocity attained by rotational motion of same strength + * [got that?] + * proportional to arclength = radius * angle + */ + float zoom_distance = zoom_sensitivity * rv3d->dist * dt * ndof->tz; + + if (U.ndof_flag & NDOF_ZOOM_INVERT) + zoom_distance = -zoom_distance; + + rv3d->dist += zoom_distance; + } + + if (rv3d->viewlock == RV3D_LOCKED) { + /* rotation not allowed -- explore panning options instead */ + float pan_vec[3] = {ndof->tx, ndof->ty, 0.0f}; + mul_v3_fl(pan_vec, pan_sensitivity * rv3d->dist * dt); + + /* transform motion from view to world coordinates */ + invert_qt_qt(view_inv, rv3d->viewquat); + mul_qt_v3(view_inv, pan_vec); + + /* move center of view opposite of hand motion (this is camera mode, not object mode) */ + sub_v3_v3(rv3d->ofs, pan_vec); + } + + if (has_rotation) { + + rv3d->view = RV3D_VIEW_USER; + + if (U.ndof_flag & NDOF_TURNTABLE) { + + /* turntable view code by John Aughey, adapted for 3D mouse by [mce] */ + float angle, rot[4]; + float xvec[3] = {1, 0, 0}; + + /* Determine the direction of the x vector (for rotating up and down) */ + mul_qt_v3(view_inv, xvec); + + /* Perform the up/down rotation */ + angle = rot_sensitivity * dt * ndof->rx; + if (U.ndof_flag & NDOF_TILT_INVERT_AXIS) + angle = -angle; + rot[0] = cos(angle); + mul_v3_v3fl(rot + 1, xvec, sin(angle)); + mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot); + + /* Perform the orbital rotation */ + angle = rot_sensitivity * dt * ndof->ry; + if (U.ndof_flag & NDOF_ROTATE_INVERT_AXIS) + angle = -angle; + + /* update the onscreen doo-dad */ + rv3d->rot_angle = angle; + rv3d->rot_axis[0] = 0; + rv3d->rot_axis[1] = 0; + rv3d->rot_axis[2] = 1; + + rot[0] = cos(angle); + rot[1] = rot[2] = 0.0; + rot[3] = sin(angle); + mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot); + + } + else { + float rot[4]; + float axis[3]; + float angle = rot_sensitivity * ndof_to_axis_angle(ndof, axis); + + if (U.ndof_flag & NDOF_ROLL_INVERT_AXIS) + axis[2] = -axis[2]; + + if (U.ndof_flag & NDOF_TILT_INVERT_AXIS) + axis[0] = -axis[0]; + + if (U.ndof_flag & NDOF_ROTATE_INVERT_AXIS) + axis[1] = -axis[1]; + + + /* transform rotation axis from view to world coordinates */ + mul_qt_v3(view_inv, axis); + + /* update the onscreen doo-dad */ + rv3d->rot_angle = angle; + copy_v3_v3(rv3d->rot_axis, axis); + + axis_angle_to_quat(rot, axis, angle); + + /* apply rotation */ + mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot); + + } + + /* rotate around custom center */ + if (vod && vod->use_dyn_ofs) { + float q1[4]; + + /* compute the post multiplication quat, to rotate the offset correctly */ + conjugate_qt_qt(q1, vod->oldquat); + mul_qt_qtqt(q1, q1, rv3d->viewquat); + + conjugate_qt(q1); /* conj == inv for unit quat */ + copy_v3_v3(rv3d->ofs, vod->ofs); + sub_v3_v3(rv3d->ofs, vod->dyn_ofs); + mul_qt_v3(q1, rv3d->ofs); + add_v3_v3(rv3d->ofs, vod->dyn_ofs); + } + } + } + + ED_view3d_camera_lock_sync(v3d, rv3d); + + ED_region_tag_redraw(CTX_wm_region(C)); + + return OPERATOR_FINISHED; + } +} + +void VIEW3D_OT_ndof_orbit_zoom(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "NDOF Orbit View with zoom"; + ot->description = "Explore every angle of an object using the 3D mouse"; + ot->idname = "VIEW3D_OT_ndof_orbit_zoom"; + + /* api callbacks */ + ot->invoke = ndof_orbit_zoom_invoke; + ot->poll = ED_operator_view3d_active; + + /* flags */ + ot->flag = 0; +} + /* -- "pan" navigation * -- zoom or dolly? */ diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index f8a7cdde8a5..a6daf610052 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -77,6 +77,7 @@ void VIEW3D_OT_zoom_camera_1_to_1(struct wmOperatorType *ot); void VIEW3D_OT_move(struct wmOperatorType *ot); void VIEW3D_OT_rotate(struct wmOperatorType *ot); void VIEW3D_OT_ndof_orbit(struct wmOperatorType *ot); +void VIEW3D_OT_ndof_orbit_zoom(struct wmOperatorType *ot); void VIEW3D_OT_ndof_pan(struct wmOperatorType *ot); void VIEW3D_OT_ndof_all(struct wmOperatorType *ot); void VIEW3D_OT_view_all(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index 4101ced616a..79561ee7566 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -131,6 +131,7 @@ void view3d_operatortypes(void) WM_operatortype_append(VIEW3D_OT_zoom); WM_operatortype_append(VIEW3D_OT_zoom_camera_1_to_1); WM_operatortype_append(VIEW3D_OT_dolly); + WM_operatortype_append(VIEW3D_OT_ndof_orbit_zoom); WM_operatortype_append(VIEW3D_OT_ndof_orbit); WM_operatortype_append(VIEW3D_OT_ndof_pan); WM_operatortype_append(VIEW3D_OT_ndof_all); @@ -199,9 +200,10 @@ void view3d_keymap(wmKeyConfig *keyconf) /* NDOF: begin */ /* note: positioned here so keymaps show keyboard keys if assigned */ /* 3D mouse */ + WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_orbit_zoom", NDOF_MOTION, 0, 0, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_orbit", NDOF_MOTION, 0, KM_CTRL, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_pan", NDOF_MOTION, 0, KM_SHIFT, 0); - WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_all", NDOF_MOTION, 0, 0, 0); + WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_all", NDOF_MOTION, 0, KM_CTRL | KM_SHIFT, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_view_selected", NDOF_BUTTON_FIT, KM_PRESS, 0, 0); RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_FRONT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_FRONT); RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_BACK, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_BACK); |