fixed crash when NDOF operators were called without an NDOF_MOTION event
authorMike Erwin <significant.bit@gmail.com>
Sat, 6 Aug 2011 22:31:16 +0000 (22:31 +0000)
committerMike Erwin <significant.bit@gmail.com>
Sat, 6 Aug 2011 22:31:16 +0000 (22:31 +0000)
source/blender/editors/space_image/image_ops.c
source/blender/editors/space_view3d/view3d_edit.c

index e0ebde589a8be34fd2de024e54ebd6cc12b28613..ea8c7fc0cfa5227fda5b5c365270c09710c9ca01 100644 (file)
@@ -447,34 +447,41 @@ void IMAGE_OT_view_zoom(wmOperatorType *ot)
 
 static int view_ndof_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
 {
-       SpaceImage *sima= CTX_wm_space_image(C);
-       ARegion *ar= CTX_wm_region(C);
+       if (event->type != NDOF_MOTION)
+               return OPERATOR_CANCELLED;
+       else {
+               SpaceImage *sima= CTX_wm_space_image(C);
+               ARegion *ar= CTX_wm_region(C);
 
-       wmNDOFMotionData* ndof = (wmNDOFMotionData*) event->customdata;
+               wmNDOFMotionData* ndof = (wmNDOFMotionData*) event->customdata;
 
-       float dt = ndof->dt;
-       /* tune these until it feels right */
-       const float zoom_sensitivity = 0.5f; // 50% per second (I think)
-       const float pan_sensitivity = 300.f; // screen pixels per second
+               float dt = ndof->dt;
+               /* tune these until it feels right */
+               const float zoom_sensitivity = 0.5f; // 50% per second (I think)
+               const float pan_sensitivity = 300.f; // screen pixels per second
 
-       float pan_x = pan_sensitivity * dt * ndof->tvec[0] / sima->zoom;
-       float pan_y = pan_sensitivity * dt * ndof->tvec[1] / sima->zoom;
+               float pan_x = pan_sensitivity * dt * ndof->tvec[0] / sima->zoom;
+               float pan_y = pan_sensitivity * dt * ndof->tvec[1] / sima->zoom;
 
-       /* "mouse zoom" factor = 1 + (dx + dy) / 300
-        * what about "ndof zoom" factor? should behave like this:
-        * at rest -> factor = 1
-        * move forward -> factor > 1
-        * move backward -> factor < 1
-        */
-       float zoom_factor = 1.f + zoom_sensitivity * dt * -ndof->tvec[2];
+               /* "mouse zoom" factor = 1 + (dx + dy) / 300
+                * what about "ndof zoom" factor? should behave like this:
+                * at rest -> factor = 1
+                * move forward -> factor > 1
+                * move backward -> factor < 1
+                */
+               float zoom_factor = 1.f + zoom_sensitivity * dt * -ndof->tvec[2];
 
-       sima_zoom_set_factor(sima, ar, zoom_factor);
-       sima->xof += pan_x;
-       sima->yof += pan_y;
+               if (U.ndof_flag & NDOF_ZOOM_INVERT)
+                       zoom_factor = -zoom_factor;
 
-       ED_region_tag_redraw(ar);       
+               sima_zoom_set_factor(sima, ar, zoom_factor);
+               sima->xof += pan_x;
+               sima->yof += pan_y;
 
-       return OPERATOR_FINISHED;
+               ED_region_tag_redraw(ar);       
+
+               return OPERATOR_FINISHED;
+       }
 }
 
 void IMAGE_OT_view_ndof(wmOperatorType *ot)
index e6fd9e8867b0617ce4ddae4d982484b2cca0031a..3e6bbc1333487beb57768f30f7f349883ccc1da2 100644 (file)
@@ -949,134 +949,125 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event
 // -- zooming
 // -- panning in rotationally-locked views
 {
-       RegionView3D* rv3d = CTX_wm_region_view3d(C);
-       wmNDOFMotionData* ndof = (wmNDOFMotionData*) event->customdata;
+       if (event->type != NDOF_MOTION)
+               return OPERATOR_CANCELLED;
+       else {
+               RegionView3D* rv3d = CTX_wm_region_view3d(C);
+               wmNDOFMotionData* ndof = (wmNDOFMotionData*) event->customdata;
 
-       rv3d->rot_angle = 0.f; // off by default, until changed later this function
+               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;
-       
-               // rather have bool, but...
-               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->tvec[2]) {
-                       // 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->tvec[2];
-                       rv3d->dist += zoom_distance;
-               }
-       
-               if (rv3d->viewlock == RV3D_LOCKED) {
-                       /* rotation not allowed -- explore panning options instead */
-                       float pan_vec[3] = {ndof->tvec[0], ndof->tvec[1], 0.0f};
-                       mul_v3_fl(pan_vec, pan_sensitivity * rv3d->dist * dt);
-       
-                       /* transform motion from view to world coordinates */
+               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 && !is_zero_v3(ndof->rvec);
+               
+                       float view_inv[4];
                        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];
-       #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_axis_angle(ndof, axis);
-       
-                               if (invert)
-                                       angle = -angle;
-       
-                               // 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);
-       #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->rvec[0];
-                               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->rvec[1];
-                               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);
+               
+                       //#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->tvec[2]) {
+                               // 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->tvec[2];
+
+                               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->tvec[0], ndof->tvec[1], 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) {
+               
+                               const int invert = U.ndof_flag & NDOF_ORBIT_INVERT_AXES;
+               
+                               rv3d->view = RV3D_VIEW_USER;
+               
+                               if (U.flag & USER_TRACKBALL) {
+                                       float rot[4];
+                                       float axis[3];
+                                       float angle = rot_sensitivity * ndof_to_axis_angle(ndof, axis);
+               
+                                       if (invert)
+                                               angle = -angle;
+               
+                                       // 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);
+                               } 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->rvec[0];
+                                       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->rvec[1];
+                                       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);
+                               }
                        }
                }
-       }
 
-       ED_region_tag_redraw(CTX_wm_region(C));
+               ED_region_tag_redraw(CTX_wm_region(C));
 
-       return OPERATOR_FINISHED;
+               return OPERATOR_FINISHED;
+       }
 }
 
 void VIEW3D_OT_ndof_orbit(struct wmOperatorType *ot)
@@ -1098,57 +1089,62 @@ static int ndof_pan_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
 // -- "pan" navigation
 // -- zoom or dolly?
 {
-       RegionView3D* rv3d = CTX_wm_region_view3d(C);
-       wmNDOFMotionData* ndof = (wmNDOFMotionData*) event->customdata;
+       if (event->type != NDOF_MOTION)
+               return OPERATOR_CANCELLED;
+       else {
+               RegionView3D* rv3d = CTX_wm_region_view3d(C);
+               wmNDOFMotionData* ndof = (wmNDOFMotionData*) event->customdata;
+
 
-       rv3d->rot_angle = 0.f; // we're panning here! so erase any leftover rotation from other operators
+               rv3d->rot_angle = 0.f; // we're panning here! so erase any leftover rotation from other operators
 
-       if (ndof->progress != P_FINISHING) {
-               const float dt = ndof->dt;
-               float view_inv[4];
+               if (ndof->progress != P_FINISHING) {
+                       const float dt = ndof->dt;
+                       float view_inv[4];
 #if 0 // ------------------------------------------- zoom with Z
-               // tune these until everything feels right
-               const float zoom_sensitivity = 1.f;
-               const float pan_sensitivity = 1.f;
-
-               float pan_vec[3] = {
-                       ndof->tx, ndof->ty, 0
-                       };
-
-               // "zoom in" or "translate"? depends on zoom mode in user settings?
-               if (ndof->tz) {
-                       float zoom_distance = zoom_sensitivity * rv3d->dist * dt * ndof->tz;
-                       rv3d->dist += zoom_distance;
-               }
-       
-               mul_v3_fl(pan_vec, pan_sensitivity * rv3d->dist * dt);
+                       // tune these until everything feels right
+                       const float zoom_sensitivity = 1.f;
+                       const float pan_sensitivity = 1.f;
+
+                       float pan_vec[3] = {
+                               ndof->tx, ndof->ty, 0
+                               };
+
+                       // "zoom in" or "translate"? depends on zoom mode in user settings?
+                       if (ndof->tz) {
+                               float zoom_distance = zoom_sensitivity * rv3d->dist * dt * ndof->tz;
+                               rv3d->dist += zoom_distance;
+                       }
+               
+                       mul_v3_fl(pan_vec, pan_sensitivity * rv3d->dist * dt);
 #else // ------------------------------------------------------- dolly with Z
-               float speed = 10.f; // blender units per second
-               // ^^ this is ok for default cube scene, but should scale with.. something
+                       float speed = 10.f; // blender units per second
+                       // ^^ this is ok for default cube scene, but should scale with.. something
 
-               // tune these until everything feels right
-               const float forward_sensitivity = 1.f;
-               const float vertical_sensitivity = 0.4f;
-               const float lateral_sensitivity = 0.6f;
+                       // tune these until everything feels right
+                       const float forward_sensitivity = 1.f;
+                       const float vertical_sensitivity = 0.4f;
+                       const float lateral_sensitivity = 0.6f;
 
-               float pan_vec[3] = {lateral_sensitivity * ndof->tvec[0],
-                                   vertical_sensitivity * ndof->tvec[1],
-                                   forward_sensitivity * ndof->tvec[2]
-                                  };
+                       float pan_vec[3] = {lateral_sensitivity * ndof->tvec[0],
+                                                               vertical_sensitivity * ndof->tvec[1],
+                                                               forward_sensitivity * ndof->tvec[2]
+                                                          };
 
-               mul_v3_fl(pan_vec, speed * dt);
+                       mul_v3_fl(pan_vec, speed * dt);
 #endif
-               /* transform motion from view to world coordinates */
-               invert_qt_qt(view_inv, rv3d->viewquat);
-               mul_qt_v3(view_inv, pan_vec);
+                       /* 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);
-       }
+                       /* move center of view opposite of hand motion (this is camera mode, not object mode) */
+                       sub_v3_v3(rv3d->ofs, pan_vec);
+               }
 
-       ED_region_tag_redraw(CTX_wm_region(C));
+               ED_region_tag_redraw(CTX_wm_region(C));
 
-       return OPERATOR_FINISHED;
+               return OPERATOR_FINISHED;
+       }
 }
 
 void VIEW3D_OT_ndof_pan(struct wmOperatorType *ot)