diff options
-rw-r--r-- | source/blender/editors/space_view3d/view3d_draw.c | 59 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_edit.c | 206 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_fly.c | 2 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_view3d_types.h | 6 |
4 files changed, 181 insertions, 92 deletions
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index d2ff6eef097..f1909bb4049 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -675,6 +675,60 @@ static void draw_view_axis(RegionView3D *rv3d) glDisable(GL_BLEND); } +/* draw center and axis of rotation for ongoing 3D mouse navigation */ +static void draw_rotation_guide(RegionView3D *rv3d) +{ + float o[3]; // center of rotation + float end[3]; // endpoints for drawing + + float color[4] = {1,1,0,1}; // bright yellow so it stands out during development + + negate_v3_v3(o, rv3d->ofs); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glShadeModel(GL_SMOOTH); + glPointSize(5); + glEnable(GL_POINT_SMOOTH); + + if (rv3d->rot_angle != 0.f) { + float scaled_axis[3]; + mul_v3_v3fl(scaled_axis, rv3d->rot_axis, 3.f); + + glBegin(GL_LINE_STRIP); + color[3] = 0; // more transparent toward the ends + glColor4fv(color); + add_v3_v3v3(end, o, scaled_axis); + glVertex3fv(end); + + color[3] = 0.2f + rv3d->rot_angle; // more opaque toward the center + glColor4fv(color); + glVertex3fv(o); + + color[3] = 0; + glColor4fv(color); + sub_v3_v3v3(end, o, scaled_axis); + glVertex3fv(end); + glEnd(); + + color[3] = 1; // solid dot + } + else + color[3] = 0.5; // see-through dot + + glColor4fv(color); + glBegin(GL_POINTS); + glVertex3fv(o); + glEnd(); + + // find screen coordinates for rotation center, then draw pretty icon + // mul_m4_v3(rv3d->persinv, rot_center); + // UI_icon_draw(rot_center[0], rot_center[1], ICON_NDOF_TURN); + // ^^ just playing around, does not work + + glDisable(GL_BLEND); + glDisable(GL_POINT_SMOOTH); +} static void draw_view_icon(RegionView3D *rv3d) { @@ -2618,6 +2672,11 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) BDR_drawSketch(C); } +#if 0 // not yet... + if (U.ndof_flag & NDOF_SHOW_GUIDE) + draw_rotation_guide(rv3d); +#endif + ED_region_pixelspace(ar); // retopo_paint_view_update(v3d); diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 0aceb3bc1ca..75e20ad565e 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -977,101 +977,125 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *op, wmEvent *event) RegionView3D* rv3d = CTX_wm_region_view3d(C); wmNDOFMotionData* ndof = (wmNDOFMotionData*) event->customdata; - const float dt = ndof->dt; + rv3d->rot_angle = 0.f; // off by default, until changed later this function - // tune these until everything feels right - const float rot_sensitivity = 1.f; - const float zoom_sensitivity = 1.f; - const float pan_sensitivity = 1.f; - - // rather have bool, but... - int has_rotation = rv3d->viewlock != RV3D_LOCKED && (ndof->rx || ndof->ry || ndof->rz); - - //#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; - rv3d->dist += zoom_distance; - } - - if (rv3d->viewlock == RV3D_LOCKED) { - /* rotation not allowed -- explore panning options instead */ + 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; + + // rather have bool, but... + int has_rotation = rv3d->viewlock != RV3D_LOCKED && (ndof->rx || ndof->ry || ndof->rz); + float view_inv[4]; - float pan_vec[3] = {ndof->tx, ndof->ty, 0}; - 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) { - - const int invert = U.ndof_flag & NDOF_ORBIT_INVERT_AXES; - - rv3d->view = RV3D_VIEW_USER; - - if (U.flag & USER_TRACKBALL) { - - float rot[4]; - float view_inv[4], view_inv_conj[4]; - - ndof_to_quat(ndof, rot); - // mul_qt_fl(rot, rot_sensitivity); - // ^^ no apparent effect - - if (invert) - invert_qt(rot); - - invert_qt_qt(view_inv, rv3d->viewquat); - copy_qt_qt(view_inv_conj, view_inv); - conjugate_qt(view_inv_conj); - - // transform rotation from view to world coordinates - mul_qt_qtqt(rot, view_inv, rot); - mul_qt_qtqt(rot, rot, view_inv_conj); - - // apply rotation - mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot); - - } else { - /* 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) */ - float view_inv[4]; + + //#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; + 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}; + 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, xvec); - - /* Perform the up/down rotation */ - angle = rot_sensitivity * dt * ndof->rx; - if (invert) - 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 (invert) - angle = -angle; - rot[0] = cos(angle); - rot[1] = rot[2] = 0.0; - rot[3] = sin(angle); - mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot); + 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) { + + const int invert = U.ndof_flag & NDOF_ORBIT_INVERT_AXES; + + rv3d->view = RV3D_VIEW_USER; + + if (U.flag & USER_TRACKBALL) { + float rot[4]; + #if 0 // -------------------------- Mike's nifty original version + float view_inv_conj[4]; + + ndof_to_quat(ndof, rot); + // mul_qt_fl(rot, rot_sensitivity); + // ^^ no apparent effect + + if (invert) + invert_qt(rot); + + copy_qt_qt(view_inv_conj, view_inv); + conjugate_qt(view_inv_conj); + + // transform rotation from view to world coordinates + mul_qt_qtqt(rot, view_inv, rot); + mul_qt_qtqt(rot, rot, view_inv_conj); + #else // ---------------------------------------- Mike's revised version + float axis[3]; + float angle = rot_sensitivity * ndof_to_angle_axis(ndof, axis); + + if (invert) + angle = -angle; + + // update the onscreen doo-dad + rv3d->rot_angle = angle; + copy_v3_v3(rv3d->rot_axis, axis); + + // transform rotation axis from view to world coordinates + mul_qt_v3(view_inv, axis); + + axis_angle_to_quat(rot, axis, angle); + #endif // -------------------------------------------- + // apply rotation + mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot); + } else { + /* 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 (invert) + 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 (invert) + 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); + } } } diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c index 1122438da96..c7ebc296896 100644 --- a/source/blender/editors/space_view3d/view3d_fly.c +++ b/source/blender/editors/space_view3d/view3d_fly.c @@ -942,6 +942,8 @@ static int flyApply_ndof(bContext *C, FlyInfo *fly) float view_inv[4]; invert_qt_qt(view_inv, rv3d->viewquat); + rv3d->rot_angle = 0; // disable onscreen rotation doo-dad + if (shouldTranslate) { const float forward_sensitivity = 1.f; diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index 27ffc6d856b..89b8bad2806 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -130,7 +130,11 @@ typedef struct RegionView3D { float twangle[3]; - float padf; + /* active rotation from NDOF or elsewhere */ + float rot_angle; + float rot_axis[3]; + + char pad2[4]; } RegionView3D; |