From 11112a895336c97590d3bc25167f553bb4b756ed Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 3 Mar 2014 14:58:07 +1100 Subject: Fixes for view3d rotate axis snapping - turntable would lockup when snapping, not allowing further rotation. - userpref rotate-about-selection was ignored (causing strange panning) --- source/blender/editors/space_view3d/view3d_edit.c | 98 ++++++++++------------- 1 file changed, 44 insertions(+), 54 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 14298acff6e..55950579637 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -550,13 +550,15 @@ static void viewops_data_create_ex(bContext *C, wmOperator *op, const wmEvent *e vod->origx = vod->oldx = event->x; vod->origy = vod->oldy = event->y; vod->origkey = event->type; /* the key that triggered the operator. */ - vod->use_dyn_ofs = use_orbit_select; + vod->use_dyn_ofs = false; copy_v3_v3(vod->ofs, rv3d->ofs); - if (vod->use_dyn_ofs) { + if (use_orbit_select) { Scene *scene = CTX_data_scene(C); Object *ob = OBACT; + vod->use_dyn_ofs = true; + if (ob && (ob->mode & OB_MODE_ALL_PAINT) && (BKE_object_pose_armature_get(ob) == NULL)) { /* in case of sculpting use last average stroke position as a rotation * center, in other cases it's not clear what rotation center shall be @@ -798,6 +800,24 @@ void viewrotate_modal_keymap(wmKeyConfig *keyconf) } +static void viewrotate_apply_dyn_ofs(ViewOpsData *vod, const float viewquat[4]) +{ + RegionView3D *rv3d = vod->rv3d; + + if (vod->use_dyn_ofs) { + float q1[4]; + conjugate_qt_qt(q1, vod->oldquat); + mul_qt_qtqt(q1, q1, 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); + } +} + static void viewrotate_apply(ViewOpsData *vod, int x, int y) { RegionView3D *rv3d = vod->rv3d; @@ -832,21 +852,11 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y) mul_v3_fl(q1 + 1, sin(phi)); mul_qt_qtqt(vod->viewquat, q1, vod->oldquat); - if (vod->use_dyn_ofs) { - /* compute the post multiplication quat, to rotate the offset correctly */ - conjugate_qt_qt(q1, vod->oldquat); - mul_qt_qtqt(q1, q1, vod->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); - } + viewrotate_apply_dyn_ofs(vod, vod->viewquat); } else { /* New turntable view code by John Aughey */ - float q1[4]; + float quat_local_x[4], quat_global_z[4]; float m[3][3]; float m_inv[3][3]; const float zvec_global[3] = {0.0f, 0.0f, 1.0f}; @@ -886,29 +896,25 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y) /* This can likely be computed directly from the quaternion. */ /* Perform the up/down rotation */ - axis_angle_to_quat(q1, xaxis, sensitivity * -(y - vod->oldy)); - mul_qt_qtqt(vod->viewquat, vod->viewquat, q1); - - if (vod->use_dyn_ofs) { - conjugate_qt(q1); /* conj == inv for unit quat */ - sub_v3_v3(rv3d->ofs, vod->dyn_ofs); - mul_qt_v3(q1, rv3d->ofs); - add_v3_v3(rv3d->ofs, vod->dyn_ofs); - } + axis_angle_to_quat(quat_local_x, xaxis, sensitivity * -(y - vod->oldy)); + mul_qt_qtqt(quat_local_x, vod->viewquat, quat_local_x); /* Perform the orbital rotation */ - axis_angle_normalized_to_quat(q1, zvec_global, sensitivity * vod->reverse * (x - vod->oldx)); - mul_qt_qtqt(vod->viewquat, vod->viewquat, q1); - - if (vod->use_dyn_ofs) { - conjugate_qt(q1); - sub_v3_v3(rv3d->ofs, vod->dyn_ofs); - mul_qt_v3(q1, rv3d->ofs); - add_v3_v3(rv3d->ofs, vod->dyn_ofs); - } + axis_angle_normalized_to_quat(quat_global_z, zvec_global, sensitivity * vod->reverse * (x - vod->oldx)); + mul_qt_qtqt(vod->viewquat, quat_local_x, quat_global_z); + + viewrotate_apply_dyn_ofs(vod, vod->viewquat); } - /* check for view snap */ + /* avoid precision loss over time */ + normalize_qt(vod->viewquat); + + /* use a working copy so view rotation locking doesnt overwrite the locked + * rotation back into the view we calculate with */ + copy_qt_qt(rv3d->viewquat, vod->viewquat); + + /* check for view snap, + * note: don't apply snap to vod->viewquat so the view wont jam up */ if (vod->axis_snap) { int i; float viewquat_inv[4]; @@ -968,9 +974,11 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y) } } - copy_qt_qt(vod->viewquat, quat_best); + copy_qt_qt(rv3d->viewquat, quat_best); rv3d->view = view; /* if we snap to a rolled camera the grid is invalid */ + viewrotate_apply_dyn_ofs(vod, rv3d->viewquat); + break; } } @@ -978,13 +986,6 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y) vod->oldx = x; vod->oldy = y; - /* avoid precision loss over time */ - normalize_qt(vod->viewquat); - - /* use a working copy so view rotation locking doesnt overwrite the locked - * rotation back into the view we calculate with */ - copy_qt_qt(rv3d->viewquat, vod->viewquat); - ED_view3d_camera_lock_sync(vod->v3d, rv3d); ED_region_tag_redraw(vod->ar); @@ -1346,19 +1347,8 @@ static void view3d_ndof_orbit(const struct wmNDOFMotionData *ndof, ScrArea *sa, mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, quat); } - /* 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); + if (vod) { + viewrotate_apply_dyn_ofs(vod, rv3d->viewquat); } } -- cgit v1.2.3