NDOF navigation support for clip editor
[blender.git] / source / blender / editors / space_clip / clip_ops.c
index b8657f9e688bc88c4591be183587027654095ed8..9b4f3fcdd68ff650ab6e8b48428ffb11b06f61ed 100644 (file)
@@ -1111,6 +1111,65 @@ void CLIP_OT_mode_set(wmOperatorType *ot)
        RNA_def_enum(ot->srna, "mode", clip_editor_mode_items, SC_MODE_TRACKING, "Mode", "");
 }
 
+/********************** NDOF operator *********************/
+
+/* Combined pan/zoom from a 3D mouse device.
+ * Z zooms, XY pans
+ * "view" (not "paper") control -- user moves the viewpoint, not the image being viewed
+ * that explains the negative signs in the code below
+ */
+
+static int clip_view_ndof_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+{
+       if (event->type != NDOF_MOTION)
+               return OPERATOR_CANCELLED;
+       else {
+               SpaceClip *sc = CTX_wm_space_clip(C);
+               ARegion *ar = CTX_wm_region(C);
+
+               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.0f; /* screen pixels per second */
+
+               float pan_x = pan_sensitivity * dt * ndof->tvec[0] / sc->zoom;
+               float pan_y = pan_sensitivity * dt * ndof->tvec[1] / sc->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.0f + zoom_sensitivity * dt * - ndof->tvec[2];
+
+               if (U.ndof_flag & NDOF_ZOOM_INVERT)
+                       zoom_factor = -zoom_factor;
+
+               sclip_zoom_set_factor(C, zoom_factor, NULL);
+               sc->xof += pan_x;
+               sc->yof += pan_y;
+
+               ED_region_tag_redraw(ar);
+
+               return OPERATOR_FINISHED;
+       }
+}
+
+void CLIP_OT_view_ndof(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "NDOF Pan/Zoom";
+       ot->idname = "CLIP_OT_view_ndof";
+       ot->description = "Use a 3D mouse device to pan/zoom the view";
+
+       /* api callbacks */
+       ot->invoke = clip_view_ndof_invoke;
+}
+
 /********************** macroses *********************/
 
 void ED_operatormacros_clip(void)