NDOF: Fix for fly/walk mode ignoring axis invert options
authorCampbell Barton <ideasman42@gmail.com>
Tue, 18 Feb 2014 12:51:11 +0000 (23:51 +1100)
committerCampbell Barton <ideasman42@gmail.com>
Tue, 18 Feb 2014 12:55:58 +0000 (23:55 +1100)
14 files changed:
release/scripts/startup/bl_ui/space_userpref.py
source/blender/editors/interface/interface_handlers.c
source/blender/editors/interface/view2d_ops.c
source/blender/editors/space_clip/clip_ops.c
source/blender/editors/space_image/image_ops.c
source/blender/editors/space_view3d/view3d_edit.c
source/blender/editors/space_view3d/view3d_fly.c
source/blender/editors/space_view3d/view3d_intern.h
source/blender/editors/space_view3d/view3d_walk.c
source/blender/makesdna/DNA_userdef_types.h
source/blender/makesrna/intern/rna_userdef.c
source/blender/windowmanager/WM_api.h
source/blender/windowmanager/WM_types.h
source/blender/windowmanager/intern/wm_event_system.c

index fbaa06f7aa333cdeeb409e4e132247d2961bbd90..2f1c411e75cf1bc0ba8ff9fe134122ff805f0062 100644 (file)
@@ -962,9 +962,9 @@ class USERPREF_MT_ndof_settings(Menu):
             layout.separator()
             layout.label(text="Orbit options")
             layout.row().prop(input_prefs, "ndof_view_rotate_method", text="")
-            layout.prop(input_prefs, "ndof_roll_invert_axis")
-            layout.prop(input_prefs, "ndof_tilt_invert_axis")
-            layout.prop(input_prefs, "ndof_rotate_invert_axis")
+            layout.prop(input_prefs, "ndof_rotx_invert_axis")
+            layout.prop(input_prefs, "ndof_roty_invert_axis")
+            layout.prop(input_prefs, "ndof_rotz_invert_axis")
 
 
         # view2d use pan/zoom
index a7f179581db4ec29a2d14e23e7533eead22461e7..9df6b7b24ab363d59b8de8c64680e4e194f99e3a 100644 (file)
@@ -4648,14 +4648,14 @@ static void ui_ndofedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data,
        v[1] = r * sinf(phi);
        
        /* Use ndof device y and x rotation to move the vector in 2d space */
-       v[0] += ndof->rz * sensitivity;
-       v[1] += ndof->rx * sensitivity;
+       v[0] += ndof->rvec[2] * sensitivity;
+       v[1] += ndof->rvec[0] * sensitivity;
 
        /* convert back to polar coords on circle */
        phi = atan2f(v[0], v[1]) / (2.0f * (float)M_PI) + 0.5f;
        
-       /* use ndof z rotation to additionally rotate hue */
-       phi += ndof->ry * sensitivity * 0.5f;
+       /* use ndof Y rotation to additionally rotate hue */
+       phi += ndof->rvec[1] * sensitivity * 0.5f;
        r = len_v2(v);
 
        /* convert back to hsv values, in range [0,1] */
index 95859be1ac045c96ced0ae06ae8b8e682606c523..a8f01b7aa5a46b563ba97aa57cd615eee6f74585 100644 (file)
@@ -1274,10 +1274,9 @@ static int view2d_ndof_invoke(bContext *C, wmOperator *op, const wmEvent *event)
                if (has_translate) {
                        if (view_pan_init(C, op)) {
                                v2dViewPanData *vpd;
-                               float pan_vec[2];
+                               float pan_vec[3];
 
-                               pan_vec[0] = ndof->tvec[0] * ((U.ndof_flag & NDOF_PANX_INVERT_AXIS) ? -1.0f : 1.0f);
-                               pan_vec[1] = ndof->tvec[1] * ((U.ndof_flag & NDOF_PANY_INVERT_AXIS) ? -1.0f : 1.0f);
+                               WM_event_ndof_pan_get(ndof, pan_vec, false);
 
                                pan_vec[0] *= pan_sensitivity;
                                pan_vec[1] *= pan_sensitivity;
index 64d96152ba5a04d94a6ca8b671fb2cd18bc8e16b..6767f92d338d7a74f9dba6781d0bded9710d5a7d 100644 (file)
@@ -1333,14 +1333,14 @@ static int clip_view_ndof_invoke(bContext *C, wmOperator *UNUSED(op), const wmEv
        else {
                SpaceClip *sc = CTX_wm_space_clip(C);
                ARegion *ar = CTX_wm_region(C);
-               float pan_vec[2];
+               float pan_vec[3];
 
                wmNDOFMotionData *ndof = (wmNDOFMotionData *) event->customdata;
 
                float dt = ndof->dt;
 
                /* tune these until it feels right */
-               const float pan_sensitivity = 300.0f; /* screen pixels per second */
+               const float pan_sensitivity = 300.0f;  /* screen pixels per second */
 
                /* "mouse zoom" factor = 1 + (dx + dy) / 300
                 * what about "ndof zoom" factor? should behave like this:
@@ -1348,17 +1348,13 @@ static int clip_view_ndof_invoke(bContext *C, wmOperator *UNUSED(op), const wmEv
                 * move forward -> factor > 1
                 * move backward -> factor < 1
                 */
-               float zoom_factor = dt * - ndof->tvec[2];
 
-               pan_vec[0] = ndof->tvec[0] * ((U.ndof_flag & NDOF_PANX_INVERT_AXIS) ? -1.0f : 1.0f);
-               pan_vec[1] = ndof->tvec[1] * ((U.ndof_flag & NDOF_PANY_INVERT_AXIS) ? -1.0f : 1.0f);
+               WM_event_ndof_pan_get(ndof, pan_vec, true);
 
                mul_v2_fl(pan_vec, (pan_sensitivity * dt) / sc->zoom);
+               pan_vec[2] *= -dt;
 
-               if (U.ndof_flag & NDOF_ZOOM_INVERT)
-                       zoom_factor = -zoom_factor;
-
-               sclip_zoom_set_factor(C, 1.0f + zoom_factor, NULL);
+               sclip_zoom_set_factor(C, 1.0f + pan_vec[2], NULL);
                sc->xof += pan_vec[0];
                sc->yof += pan_vec[1];
 
index d8159955af91fe0faafa17c882288e505329831e..29448a2c5cdea097337800eb38c0f9c7e9d21480 100644 (file)
@@ -599,13 +599,14 @@ static int image_view_ndof_invoke(bContext *C, wmOperator *UNUSED(op), const wmE
        else {
                SpaceImage *sima = CTX_wm_space_image(C);
                ARegion *ar = CTX_wm_region(C);
-               float pan_vec[2];
+               float pan_vec[3];
 
                wmNDOFMotionData *ndof = (wmNDOFMotionData *) event->customdata;
 
                float dt = ndof->dt;
+
                /* tune these until it feels right */
-               const float pan_sensitivity = 300.f; // screen pixels per second
+               const float pan_sensitivity = 300.0f;  /* screen pixels per second */
 
                /* "mouse zoom" factor = 1 + (dx + dy) / 300
                 * what about "ndof zoom" factor? should behave like this:
@@ -613,17 +614,13 @@ static int image_view_ndof_invoke(bContext *C, wmOperator *UNUSED(op), const wmE
                 * move forward -> factor > 1
                 * move backward -> factor < 1
                 */
-               float zoom_factor = dt * -ndof->tvec[2];
 
-               pan_vec[0] = ndof->tvec[0] * ((U.ndof_flag & NDOF_PANX_INVERT_AXIS) ? -1.0f : 1.0f);
-               pan_vec[1] = ndof->tvec[1] * ((U.ndof_flag & NDOF_PANY_INVERT_AXIS) ? -1.0f : 1.0f);
+               WM_event_ndof_pan_get(ndof, pan_vec, true);
 
                mul_v2_fl(pan_vec, (pan_sensitivity * dt) / sima->zoom);
+               pan_vec[2] *= -dt;
 
-               if (U.ndof_flag & NDOF_ZOOM_INVERT)
-                       zoom_factor = -zoom_factor;
-
-               sima_zoom_set_factor(sima, ar, 1.0f + zoom_factor, NULL);
+               sima_zoom_set_factor(sima, ar, 1.0f + pan_vec[2], NULL);
                sima->xof += pan_vec[0];
                sima->yof += pan_vec[1];
 
index 0c4e2bd541a0405d0145427931a46f94b412393e..bcf096217481d3cd6dc361eeba164c4c676ec25e 100644 (file)
@@ -1151,20 +1151,6 @@ void VIEW3D_OT_rotate(wmOperatorType *ot)
 #define NDOF_HAS_TRANSLATE ((!view3d_operator_offset_lock_check(C, op)) && !is_zero_v3(ndof->tvec))
 #define NDOF_HAS_ROTATE    (((rv3d->viewlock & RV3D_LOCKED) == 0) && !is_zero_v3(ndof->rvec))
 
-float ndof_to_axis_angle(const struct wmNDOFMotionData *ndof, float axis[3])
-{
-       return ndof->dt * normalize_v3_v3(axis, ndof->rvec);
-}
-
-void ndof_to_quat(const struct wmNDOFMotionData *ndof, float q[4])
-{
-       float axis[3];
-       float angle;
-
-       angle = ndof_to_axis_angle(ndof, axis);
-       axis_angle_to_quat(q, axis, angle);
-}
-
 /**
  * Zoom and pan in the same function since sometimes zoom is interpreted as dolly (pan forward).
  *
@@ -1182,9 +1168,7 @@ static void view3d_ndof_pan_zoom(const struct wmNDOFMotionData *ndof, ScrArea *s
                return;
        }
 
-       pan_vec[0] = ndof->tvec[0] * ((U.ndof_flag & NDOF_PANX_INVERT_AXIS) ? -1.0f : 1.0f);
-       pan_vec[1] = ndof->tvec[1] * ((U.ndof_flag & NDOF_PANY_INVERT_AXIS) ? -1.0f : 1.0f);
-       pan_vec[2] = ndof->tvec[2] * ((U.ndof_flag & NDOF_PANZ_INVERT_AXIS) ? -1.0f : 1.0f);
+       WM_event_ndof_pan_get(ndof, pan_vec, false);
 
        if (has_zoom) {
                /* zoom with Z */
@@ -1195,14 +1179,11 @@ static void view3d_ndof_pan_zoom(const struct wmNDOFMotionData *ndof, ScrArea *s
                 * proportional to arclength = radius * angle
                 */
 
-               /* tune these until everything feels right */
-               const float zoom_sensitivity = 1.f;
-
                pan_vec[2] = 0.0f;
 
                /* "zoom in" or "translate"? depends on zoom mode in user settings? */
-               if (ndof->tz) {
-                       float zoom_distance = zoom_sensitivity * rv3d->dist * dt * ndof->tz;
+               if (ndof->tvec[2]) {
+                       float zoom_distance = rv3d->dist * dt * ndof->tvec[2];
 
                        if (U.ndof_flag & NDOF_ZOOM_INVERT)
                                zoom_distance = -zoom_distance;
@@ -1242,7 +1223,6 @@ static void view3d_ndof_orbit(const struct wmNDOFMotionData *ndof, RegionView3D
                               /* optional, can be NULL*/
                               ViewOpsData *vod)
 {
-       const float rot_sensitivity = 1.0f;
        float view_inv[4];
 
        BLI_assert((rv3d->viewlock & RV3D_LOCKED) == 0);
@@ -1254,26 +1234,26 @@ static void view3d_ndof_orbit(const struct wmNDOFMotionData *ndof, RegionView3D
        invert_qt_qt(view_inv, rv3d->viewquat);
 
        if (U.ndof_flag & NDOF_TURNTABLE) {
+               float rot[3];
 
                /* turntable view code by John Aughey, adapted for 3D mouse by [mce] */
-               float angle, rot[4];
+               float angle, quat[4];
                float xvec[3] = {1, 0, 0};
 
+               /* only use XY, ignore Z */
+               WM_event_ndof_rotate_get(ndof, rot);
+
                /* 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 (U.ndof_flag & NDOF_TILT_INVERT_AXIS)
-                       angle = -angle;
-               rot[0] = cosf(angle);
-               mul_v3_v3fl(rot + 1, xvec, sin(angle));
-               mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot);
+               angle = dt * rot[0];
+               quat[0] = cosf(angle);
+               mul_v3_v3fl(quat + 1, xvec, sin(angle));
+               mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, quat);
 
                /* Perform the orbital rotation */
-               angle = rot_sensitivity * dt * ndof->ry;
-               if (U.ndof_flag & NDOF_ROTATE_INVERT_AXIS)
-                       angle = -angle;
+               angle = dt * rot[1];
 
                /* update the onscreen doo-dad */
                rv3d->rot_angle = angle;
@@ -1281,21 +1261,17 @@ static void view3d_ndof_orbit(const struct wmNDOFMotionData *ndof, RegionView3D
                rv3d->rot_axis[1] = 0;
                rv3d->rot_axis[2] = 1;
 
-               rot[0] = cosf(angle);
-               rot[1] = rot[2] = 0.0;
-               rot[3] = sinf(angle);
-               mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot);
+               quat[0] = cosf(angle);
+               quat[1] = 0.0f;
+               quat[2] = 0.0f;
+               quat[3] = sinf(angle);
+               mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, quat);
 
        }
        else {
-               float rot[4];
+               float quat[4];
                float axis[3];
-               float angle = rot_sensitivity * ndof_to_axis_angle(ndof, axis);
-
-               if (U.ndof_flag & NDOF_ROLL_INVERT_AXIS)   axis[2] = -axis[2];
-               if (U.ndof_flag & NDOF_TILT_INVERT_AXIS)   axis[0] = -axis[0];
-               if (U.ndof_flag & NDOF_ROTATE_INVERT_AXIS) axis[1] = -axis[1];
-
+               float angle = WM_event_ndof_to_axis_angle(ndof, axis);
 
                /* transform rotation axis from view to world coordinates */
                mul_qt_v3(view_inv, axis);
@@ -1304,10 +1280,10 @@ static void view3d_ndof_orbit(const struct wmNDOFMotionData *ndof, RegionView3D
                rv3d->rot_angle = angle;
                copy_v3_v3(rv3d->rot_axis, axis);
 
-               axis_angle_to_quat(rot, axis, angle);
+               axis_angle_to_quat(quat, axis, angle);
 
                /* apply rotation */
-               mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot);
+               mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, quat);
        }
 
        /* rotate around custom center */
index 813404a5bf9b559b523e6f99a294bfbddefd372d..4933e0048557efb00ac879f01a416e6b007d5fba 100644 (file)
@@ -959,19 +959,21 @@ static int flyApply_ndof(bContext *C, FlyInfo *fly)
 
        if (do_translate) {
                float speed = 10.0f; /* blender units per second */
-               float trans[3];
+               float trans[3], trans_orig_y;
                /* ^^ this is ok for default cube scene, but should scale with.. something */
                if (fly->use_precision)
                        speed *= 0.2f;
 
-               mul_v3_v3fl(trans, ndof->tvec, speed * dt);
+               WM_event_ndof_pan_get(ndof, trans, false);
+               mul_v3_fl(trans, speed * dt);
+               trans_orig_y = trans[1];
 
                /* transform motion from view to world coordinates */
                mul_qt_v3(view_inv, trans);
 
                if (flag & NDOF_FLY_HELICOPTER) {
                        /* replace world z component with device y (yes it makes sense) */
-                       trans[2] = speed * dt * ndof->tvec[1];
+                       trans[2] = trans_orig_y;
                }
 
                if (rv3d->persp == RV3D_CAMOB) {
@@ -997,7 +999,7 @@ static int flyApply_ndof(bContext *C, FlyInfo *fly)
 
                float rotation[4];
                float axis[3];
-               float angle = turn_sensitivity * ndof_to_axis_angle(ndof, axis);
+               float angle = turn_sensitivity * WM_event_ndof_to_axis_angle(ndof, axis);
 
                if (fabsf(angle) > 0.0001f) {
                        do_rotate = true;
index 0317775f62b528847c57403e392d346c2a82489a..86b1891074d3ca114e8a750c9b82b5e8153a2676 100644 (file)
@@ -106,8 +106,6 @@ void VIEW3D_OT_clear_render_border(struct wmOperatorType *ot);
 void VIEW3D_OT_zoom_border(struct wmOperatorType *ot);
 
 void view3d_boxview_copy(ScrArea *sa, ARegion *ar);
-void ndof_to_quat(const struct wmNDOFMotionData *ndof, float q[4]);
-float ndof_to_axis_angle(const struct wmNDOFMotionData *ndof, float axis[3]);
 
 /* view3d_fly.c */
 void view3d_keymap(struct wmKeyConfig *keyconf);
index 426a9a69f07ec8119c790b9920ca1fbc6d5c6cb7..b49e26241b87cb90dec592610e9b53fd46f58e23 100644 (file)
@@ -1239,19 +1239,21 @@ static int walkApply_ndof(bContext *C, WalkInfo *walk)
 
        if (do_translate) {
                float speed = 10.0f; /* blender units per second */
-               float trans[3];
+               float trans[3], trans_orig_y;
                /* ^^ this is ok for default cube scene, but should scale with.. something */
                if (walk->is_slow)
                        speed *= 0.2f;
 
-               mul_v3_v3fl(trans, ndof->tvec, speed * dt);
+               WM_event_ndof_pan_get(ndof, trans, false);
+               mul_v3_fl(trans, speed * dt);
+               trans_orig_y = trans[1];
 
                /* transform motion from view to world coordinates */
                mul_qt_v3(view_inv, trans);
 
                if (flag & NDOF_FLY_HELICOPTER) {
                        /* replace world z component with device y (yes it makes sense) */
-                       trans[2] = speed * dt * ndof->tvec[1];
+                       trans[2] = trans_orig_y;
                }
 
                if (rv3d->persp == RV3D_CAMOB) {
@@ -1277,7 +1279,7 @@ static int walkApply_ndof(bContext *C, WalkInfo *walk)
 
                float rotation[4];
                float axis[3];
-               float angle = turn_sensitivity * ndof_to_axis_angle(ndof, axis);
+               float angle = turn_sensitivity * WM_event_ndof_to_axis_angle(ndof, axis);
 
                if (fabsf(angle) > 0.0001f) {
                        do_rotate = true;
index ffc1c489d1e621daaa2cf5e348c9cde0ae08d00c..1705a0d16c5bd70012194da4251ecea7a4418636 100644 (file)
@@ -795,9 +795,9 @@ typedef enum eNdof_Flag {
        /* zoom is up/down if this flag is set (otherwise forward/backward) */
        NDOF_PAN_YZ_SWAP_AXIS   = (1 << 7),
        NDOF_ZOOM_INVERT        = (1 << 8),
-       NDOF_ROTATE_INVERT_AXIS = (1 << 9),
-       NDOF_TILT_INVERT_AXIS   = (1 << 10),
-       NDOF_ROLL_INVERT_AXIS   = (1 << 11),
+       NDOF_ROTX_INVERT_AXIS   = (1 << 9),
+       NDOF_ROTY_INVERT_AXIS   = (1 << 10),
+       NDOF_ROTZ_INVERT_AXIS   = (1 << 11),
        NDOF_PANX_INVERT_AXIS   = (1 << 12),
        NDOF_PANY_INVERT_AXIS   = (1 << 13),
        NDOF_PANZ_INVERT_AXIS   = (1 << 14),
index 54e1b0b78ddc2cd40834519f6d5e10c9206dc534..0910ee65d6b946edf9eda86b1ba60471c32a9a7e 100644 (file)
@@ -4067,35 +4067,35 @@ static void rna_def_userdef_input(BlenderRNA *brna)
        RNA_def_property_enum_items(prop, ndof_view_rotation_items);
        RNA_def_property_ui_text(prop, "NDOF View Rotation", "Rotation style in the viewport");
 
-       /* 3D view: roll */
-       prop = RNA_def_property(srna, "ndof_roll_invert_axis", PROP_BOOLEAN, PROP_NONE);
-       RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_ROLL_INVERT_AXIS);
-       RNA_def_property_ui_text(prop, "Invert roll Axis", "Invert roll axis");
+       /* 3D view: yaw */
+       prop = RNA_def_property(srna, "ndof_rotx_invert_axis", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_ROTX_INVERT_AXIS);
+       RNA_def_property_ui_text(prop, "Invert Yaw (X) Axis", "");
 
-       /* 3D view: tilt */
-       prop = RNA_def_property(srna, "ndof_tilt_invert_axis", PROP_BOOLEAN, PROP_NONE);
-       RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_TILT_INVERT_AXIS);
-       RNA_def_property_ui_text(prop, "Invert tilt Axis", "Invert tilt axis");
+       /* 3D view: pitch */
+       prop = RNA_def_property(srna, "ndof_roty_invert_axis", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_ROTY_INVERT_AXIS);
+       RNA_def_property_ui_text(prop, "Invert Pitch (Y) Axis", "");
 
-       /* 3D view: rotate */
-       prop = RNA_def_property(srna, "ndof_rotate_invert_axis", PROP_BOOLEAN, PROP_NONE);
-       RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_ROTATE_INVERT_AXIS);
-       RNA_def_property_ui_text(prop, "Invert rotation Axis", "Invert rotation axis");
+       /* 3D view: roll */
+       prop = RNA_def_property(srna, "ndof_rotz_invert_axis", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_ROTZ_INVERT_AXIS);
+       RNA_def_property_ui_text(prop, "Invert Roll (Z) Axis", "");
 
        /* 3D view: pan x */
        prop = RNA_def_property(srna, "ndof_panx_invert_axis", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_PANX_INVERT_AXIS);
-       RNA_def_property_ui_text(prop, "Invert x Axis", "Invert x axis");
+       RNA_def_property_ui_text(prop, "Invert X Axis", "");
 
        /* 3D view: pan y */
        prop = RNA_def_property(srna, "ndof_pany_invert_axis", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_PANY_INVERT_AXIS);
-       RNA_def_property_ui_text(prop, "Invert y Axis", "Invert y axis");
+       RNA_def_property_ui_text(prop, "Invert Y Axis", "");
 
        /* 3D view: pan z */
        prop = RNA_def_property(srna, "ndof_panz_invert_axis", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_PANZ_INVERT_AXIS);
-       RNA_def_property_ui_text(prop, "Invert z Axis", "Invert z axis");
+       RNA_def_property_ui_text(prop, "Invert Z Axis", "");
 
        /* 3D view: fly */
        prop = RNA_def_property(srna, "ndof_lock_horizon", PROP_BOOLEAN, PROP_NONE);
index 8a13decea42b06010c41921a51a9d9787adf23ff..c88c5496ea61c4b84dfb08b3e061c57465c2221d 100644 (file)
@@ -65,6 +65,7 @@ struct wmDrag;
 struct ImBuf;
 struct ImageFormatData;
 struct ARegion;
+struct wmNDOFMotionData;
 
 typedef struct wmJob wmJob;
 
@@ -435,6 +436,12 @@ bool write_crash_blend(void);
                        /* Lock the interface for any communication */
 void        WM_set_locked_interface(struct wmWindowManager *wm, bool lock);
 
+void        WM_event_ndof_pan_get(const struct wmNDOFMotionData *ndof, float r_pan[3], const bool use_zoom);
+void        WM_event_ndof_rotate_get(const struct wmNDOFMotionData *ndof, float r_rot[3]);
+
+float       WM_event_ndof_to_axis_angle(const struct wmNDOFMotionData *ndof, float axis[3]);
+void        WM_event_ndof_to_quat(const struct wmNDOFMotionData *ndof, float q[4]);
+
 #ifdef __cplusplus
 }
 #endif
index 8bbdd7bd736b7da183bf86e7098900af2c9096a1..c93ed89d78f624debf3980b64f66e803d7f1f152 100644 (file)
@@ -481,14 +481,8 @@ typedef struct wmNDOFMotionData {
        /* awfully similar to GHOST_TEventNDOFMotionData... */
        /* Each component normally ranges from -1 to +1, but can exceed that.
         * These use blender standard view coordinates, with positive rotations being CCW about the axis. */
-       union {
-               float tvec[3]; /* translation */
-               struct { float tx, ty, tz; };
-       };
-       union {
-               float rvec[3]; /* rotation: */
-               struct { float rx, ry, rz; };
-       };
+       float tvec[3]; /* translation */
+       float rvec[3]; /* rotation: */
        /* axis = (rx,ry,rz).normalized */
        /* amount = (rx,ry,rz).magnitude [in revolutions, 1.0 = 360 deg] */
        float dt; /* time since previous NDOF Motion event */
index 47fdb37d40358c720296153a2aa6564fb6f7d49f..5254bff99cd4257b5ceed664fe7eee02d93b4dc0 100644 (file)
@@ -3322,3 +3322,49 @@ void WM_set_locked_interface(wmWindowManager *wm, bool lock)
         */
        BKE_spacedata_draw_locks(lock);
 }
+
+
+/* -------------------------------------------------------------------- */
+/* NDOF */
+
+/** \name NDOF Utility Functions
+ * \{ */
+
+
+void WM_event_ndof_pan_get(const wmNDOFMotionData *ndof, float r_pan[3], const bool use_zoom)
+{
+       int z_flag = use_zoom ? NDOF_ZOOM_INVERT : NDOF_PANZ_INVERT_AXIS;
+       r_pan[0] = ndof->tvec[0] * ((U.ndof_flag & NDOF_PANX_INVERT_AXIS) ? -1.0f : 1.0f);
+       r_pan[1] = ndof->tvec[1] * ((U.ndof_flag & NDOF_PANY_INVERT_AXIS) ? -1.0f : 1.0f);
+       r_pan[2] = ndof->tvec[2] * ((U.ndof_flag & z_flag)                ? -1.0f : 1.0f);
+}
+
+void WM_event_ndof_rotate_get(const wmNDOFMotionData *ndof, float r_rot[3])
+{
+       r_rot[0] = ndof->rvec[0] * ((U.ndof_flag & NDOF_ROTX_INVERT_AXIS) ? -1.0f : 1.0f);
+       r_rot[1] = ndof->rvec[1] * ((U.ndof_flag & NDOF_ROTY_INVERT_AXIS) ? -1.0f : 1.0f);
+       r_rot[2] = ndof->rvec[2] * ((U.ndof_flag & NDOF_ROTZ_INVERT_AXIS) ? -1.0f : 1.0f);
+}
+
+float WM_event_ndof_to_axis_angle(const struct wmNDOFMotionData *ndof, float axis[3])
+{
+       float angle;
+       angle = normalize_v3_v3(axis, ndof->rvec);
+
+       axis[0] = axis[0] * ((U.ndof_flag & NDOF_ROTX_INVERT_AXIS) ? -1.0f : 1.0f);
+       axis[1] = axis[1] * ((U.ndof_flag & NDOF_ROTY_INVERT_AXIS) ? -1.0f : 1.0f);
+       axis[2] = axis[2] * ((U.ndof_flag & NDOF_ROTZ_INVERT_AXIS) ? -1.0f : 1.0f);
+
+       return ndof->dt * angle;
+}
+
+void WM_event_ndof_to_quat(const struct wmNDOFMotionData *ndof, float q[4])
+{
+       float axis[3];
+       float angle;
+
+       angle = WM_event_ndof_to_axis_angle(ndof, axis);
+       axis_angle_to_quat(q, axis, angle);
+}
+
+/** \} */