experimental onscreen rotation guide
authorMike Erwin <significant.bit@gmail.com>
Tue, 26 Jul 2011 02:35:46 +0000 (02:35 +0000)
committerMike Erwin <significant.bit@gmail.com>
Tue, 26 Jul 2011 02:35:46 +0000 (02:35 +0000)
source/blender/editors/space_view3d/view3d_draw.c
source/blender/editors/space_view3d/view3d_edit.c
source/blender/editors/space_view3d/view3d_fly.c
source/blender/makesdna/DNA_view3d_types.h

index d2ff6eef09798234ffd8366455385d1f69b9a5bc..f1909bb404986b9b866de161609c8573f8da359f 100644 (file)
@@ -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);
index 0aceb3bc1ca29fa9bf397b2b8afd8b0f3ecd56fd..75e20ad565ee86f3a86a84fcd3764e96c62d9953 100644 (file)
@@ -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);
+                       }
                }
        }
 
index 1122438da96e1aec9f4405c07401e7dd26f584bb..c7ebc2968969ca6070065f34386ca9d6e1969ddf 100644 (file)
@@ -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;
index 27ffc6d856bfa47229e8dd30d77272ad7760782f..89b8bad28069db22865f0ab0144ffe91147423e5 100644 (file)
@@ -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;