Revision: 38405
          
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=38405
Author:   merwin
Date:     2011-07-14 21:20:45 +0000 (Thu, 14 Jul 2011)
Log Message:
-----------
more consistent and modal-friendly ndof events, fly mode v1

Modified Paths:
--------------
    branches/merwin-spacenav/intern/ghost/GHOST_Types.h
    branches/merwin-spacenav/intern/ghost/intern/GHOST_NDOFManager.cpp
    branches/merwin-spacenav/intern/ghost/intern/GHOST_NDOFManager.h
    branches/merwin-spacenav/source/blender/editors/space_view3d/view3d_edit.c
    branches/merwin-spacenav/source/blender/editors/space_view3d/view3d_fly.c
    branches/merwin-spacenav/source/blender/editors/space_view3d/view3d_intern.h
    branches/merwin-spacenav/source/blender/windowmanager/WM_types.h
    
branches/merwin-spacenav/source/blender/windowmanager/intern/wm_event_system.c

Modified: branches/merwin-spacenav/intern/ghost/GHOST_Types.h
===================================================================
--- branches/merwin-spacenav/intern/ghost/GHOST_Types.h 2011-07-14 20:41:52 UTC 
(rev 38404)
+++ branches/merwin-spacenav/intern/ghost/GHOST_Types.h 2011-07-14 21:20:45 UTC 
(rev 38405)
@@ -434,14 +434,24 @@
        GHOST_TUns8 **strings;
 } GHOST_TStringArray;
 
+typedef enum {
+       GHOST_kNotStarted,
+       GHOST_kStarting,
+       GHOST_kInProgress,
+       GHOST_kFinishing,
+       GHOST_kFinished
+       } GHOST_TProgress;
+
 typedef struct {
-       /** N-degree of freedom device data v3 [GSoC 2010]*/
-       /* Each component normally ranges from -1 to +1, but can exceed that. */
-       float tx, ty, tz; /* translation: -x left, +y forward, -z up */
-       float rx, ry, rz; /* 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 (or zero if this is 
the first)
+       /** N-degree of freedom device data v3 [GSoC 2010] */
+       // 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.
+       float tx, ty, tz; // translation
+       float rx, ry, rz; // 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
+       GHOST_TProgress progress; // Starting, InProgress or Finishing (for 
modal handlers)
 } GHOST_TEventNDOFMotionData;
 
 typedef enum { GHOST_kPress, GHOST_kRelease } GHOST_TButtonAction;

Modified: branches/merwin-spacenav/intern/ghost/intern/GHOST_NDOFManager.cpp
===================================================================
--- branches/merwin-spacenav/intern/ghost/intern/GHOST_NDOFManager.cpp  
2011-07-14 20:41:52 UTC (rev 38404)
+++ branches/merwin-spacenav/intern/ghost/intern/GHOST_NDOFManager.cpp  
2011-07-14 21:20:45 UTC (rev 38405)
@@ -29,6 +29,12 @@
 #include <stdio.h> // for error/info reporting
 #include <math.h>
 
+#ifdef DEBUG_NDOF_MOTION
+// printable version of each GHOST_TProgress value
+static const char* progress_string[] =
+       {"not started","starting","in progress","finishing","finished"};
+#endif
+
 #ifdef DEBUG_NDOF_BUTTONS
 static const char* ndof_button_names[] = {
        // used internally, never sent
@@ -139,9 +145,10 @@
        , m_buttonCount(0)
        , m_buttonMask(0)
        , m_buttons(0)
-       , m_motionTime(1000) // one full second (operators should filter out 
such large time deltas)
+       , m_motionTime(0)
        , m_prevMotionTime(0)
-       , m_atRest(true)
+       , m_motionState(GHOST_kNotStarted)
+       , m_motionEventPending(false)
        {
        // to avoid the rare situation where one triple is updated and
        // the other is not, initialize them both here:
@@ -179,10 +186,16 @@
                                        break;
 
                                // -- older devices --
-                               case 0xC623: puts("ndof: SpaceTraveler not 
supported, please file a bug report"); break;
-                                       // no buttons?
-                               case 0xC625: puts("ndof: SpacePilot not 
supported, please file a bug report"); break;
-                                       // 21 buttons
+                               // keep unknown device type so rogue button 
events will get discarded
+                               // "mystery device" owners can help build 
another HID_map for their hardware
+                               case 0xC623:
+                                       puts("ndof: SpaceTraveler not 
supported, please file a bug report");
+                                       m_buttonCount = 8;
+                                       break;
+                               case 0xC625:
+                                       puts("ndof: SpacePilot not supported, 
please file a bug report");
+                                       m_buttonCount = 21;
+                                       break;
 
                                default: printf("ndof: unknown Logitech product 
%04hx\n", product_id);
                                }
@@ -198,18 +211,41 @@
        #endif
        }
 
+void GHOST_NDOFManager::updateMotionState()
+       {
+       if (m_motionEventPending)
+               return;
+
+       switch (m_motionState)
+               {
+               case GHOST_kFinished:
+               case GHOST_kNotStarted:
+                       m_motionState = GHOST_kStarting;
+                       break;
+               case GHOST_kStarting:
+                       m_motionState = GHOST_kInProgress;
+                       break;          
+               default:
+                       // InProgress remains InProgress
+                       // should never be Finishing
+                       break;
+               }
+
+       m_motionEventPending = true;
+       }
+
 void GHOST_NDOFManager::updateTranslation(short t[3], GHOST_TUns64 time)
        {
        memcpy(m_translation, t, sizeof(m_translation));
        m_motionTime = time;
-       m_atRest = false;
+       updateMotionState();
        }
 
 void GHOST_NDOFManager::updateRotation(short r[3], GHOST_TUns64 time)
        {
        memcpy(m_rotation, r, sizeof(m_rotation));
        m_motionTime = time;
-       m_atRest = false;
+       updateMotionState();
        }
 
 void GHOST_NDOFManager::sendButtonEvent(NDOF_ButtonT button, bool press, 
GHOST_TUns64 time, GHOST_IWindow* window)
@@ -290,7 +326,7 @@
 
        int diff = m_buttons ^ button_bits;
 
-       for (int button_number = 0; button_number <= 31; ++button_number)
+       for (int button_number = 0; button_number < m_buttonCount; 
++button_number)
                {
                int mask = 1 << button_number;
 
@@ -302,15 +338,21 @@
                }
        }
 
-static bool atHomePosition(GHOST_TEventNDOFMotionData* ndof, float threshold)
+static bool atHomePosition(GHOST_TEventNDOFMotionData* ndof)
        {
-       #define HOME(foo) (fabsf(ndof->foo) < threshold)
+       #define HOME(foo) (ndof->foo == 0)
        return HOME(tx) && HOME(ty) && HOME(tz) && HOME(rx) && HOME(ry) && 
HOME(rz);
        }
 
+static bool nearHomePosition(GHOST_TEventNDOFMotionData* ndof, float threshold)
+       {
+       #define HOME1(foo) (fabsf(ndof->foo) < threshold)
+       return HOME1(tx) && HOME1(ty) && HOME1(tz) && HOME1(rx) && HOME1(ry) && 
HOME1(rz);
+       }
+
 bool GHOST_NDOFManager::sendMotionEvent()
        {
-       if (m_atRest)
+       if (m_motionState == GHOST_kFinished || m_motionState == 
GHOST_kNotStarted)
                return false;
 
        GHOST_IWindow* window = m_system.getWindowManager()->getActiveWindow();
@@ -320,7 +362,7 @@
 
        const float scale = 1.f / 350.f; // 3Dconnexion devices send +/- 350 
usually
 
-       // possible future enhancement
+       // probable future enhancement
        // scale *= m_sensitivity;
 
        data->tx = scale * m_translation[0];
@@ -331,19 +373,35 @@
        data->ry = scale * m_rotation[1];
        data->rz = scale * m_rotation[2];
 
-       data->dt = 0.001f * (m_motionTime - m_prevMotionTime); // in seconds
+       if (m_motionState == GHOST_kStarting)
+               // prev motion time will be ancient, so just make up something 
reasonable
+               data->dt = 0.0125f;
+       else
+               data->dt = 0.001f * (m_motionTime - m_prevMotionTime); // in 
seconds
 
        m_prevMotionTime = m_motionTime;
 
+       // 'at rest' test goes at the end so that the first 'rest' event gets 
sent
+       if (atHomePosition(data))
+//     if (nearHomePosition(data, 0.05f)) // Linux & Windows have trouble w/ 
calibration
+               {
+               data->progress = GHOST_kFinishing;
+               // for internal state, skip Finishing & jump to Finished
+               m_motionState = GHOST_kFinished;
+               }
+       else
+               data->progress = m_motionState; // Starting or InProgress
+
        #ifdef DEBUG_NDOF_MOTION
-       printf("ndof: T=(%.2f,%.2f,%.2f) R=(%.2f,%.2f,%.2f) dt=%.3f\n",
-               data->tx, data->ty, data->tz, data->rx, data->ry, data->rz, 
data->dt);
+       printf("ndof %s: T=(%.2f,%.2f,%.2f) R=(%.2f,%.2f,%.2f) dt=%.3f\n",
+               progress_string[data->progress],
+               data->tx, data->ty, data->tz,
+               data->rx, data->ry, data->rz,
+               data->dt);
        #endif
 
        m_system.pushEvent(event);
+       m_motionEventPending = false;
 
-       // 'at rest' test goes at the end so that the first 'rest' event gets 
sent
-       m_atRest = atHomePosition(data, 0.05f);
-
        return true;
        }

Modified: branches/merwin-spacenav/intern/ghost/intern/GHOST_NDOFManager.h
===================================================================
--- branches/merwin-spacenav/intern/ghost/intern/GHOST_NDOFManager.h    
2011-07-14 20:41:52 UTC (rev 38404)
+++ branches/merwin-spacenav/intern/ghost/intern/GHOST_NDOFManager.h    
2011-07-14 21:20:45 UTC (rev 38405)
@@ -27,9 +27,7 @@
 #include "GHOST_System.h"
 
 
-// --- the following type definitions will find a home somewhere else once 
finished ---
-
-//#define DEBUG_NDOF_MOTION
+#define DEBUG_NDOF_MOTION
 #define DEBUG_NDOF_BUTTONS
 
 typedef enum { NDOF_UnknownDevice, NDOF_SpaceNavigator, NDOF_SpaceExplorer, 
NDOF_SpacePilotPro } NDOF_DeviceT;
@@ -120,8 +118,8 @@
 private:
        void sendButtonEvent(NDOF_ButtonT, bool press, GHOST_TUns64 time, 
GHOST_IWindow*);
        void sendKeyEvent(GHOST_TKey, bool press, GHOST_TUns64 time, 
GHOST_IWindow*);
+       void updateMotionState();
 
-
        NDOF_DeviceT m_deviceType;
        int m_buttonCount;
        int m_buttonMask;
@@ -132,7 +130,8 @@
 
        GHOST_TUns64 m_motionTime; // in milliseconds
        GHOST_TUns64 m_prevMotionTime; // time of most recent Motion event sent
-       bool m_atRest;
+       GHOST_TProgress m_motionState;
+       bool m_motionEventPending;
 };
 
 #endif

Modified: 
branches/merwin-spacenav/source/blender/editors/space_view3d/view3d_edit.c
===================================================================
--- branches/merwin-spacenav/source/blender/editors/space_view3d/view3d_edit.c  
2011-07-14 20:41:52 UTC (rev 38404)
+++ branches/merwin-spacenav/source/blender/editors/space_view3d/view3d_edit.c  
2011-07-14 21:20:45 UTC (rev 38405)
@@ -929,10 +929,30 @@
        ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER;
 }
 
-#if 0 // NDOF utility functions
+// NDOF utility functions
+// (should these functions live in this file?)
+float ndof_to_angle_axis(struct wmNDOFMotionData* ndof, float axis[3])
+       {
+       const float x = ndof->rx;
+       const float y = ndof->ry;
+       const float z = ndof->rz;
+
+       float angular_velocity = sqrtf(x*x + y*y + z*z);
+       float angle = ndof->dt * angular_velocity;
+
+       float scale = 1.f / angular_velocity;
+
+       // normalize 
+       axis[0] = scale * x;
+       axis[1] = scale * y;
+       axis[2] = scale * z;
+
+       return angle;
+       }
+
+#if 0 // unused utility functions
 // returns angular velocity (0..1), fills axis of rotation
-// (shouldn't live in this file!)
-static float ndof_to_angle_axis(const float ndof[3], float axis[3])
+float ndof_to_angle_axis(const float ndof[3], float axis[3])
        {
        const float x = ndof[0];
        const float y = ndof[1];
@@ -960,7 +980,7 @@
        }
 #endif
 
-static void ndof_to_quat(wmNDOFMotionData* ndof, float q[4])
+void ndof_to_quat(struct wmNDOFMotionData* ndof, float q[4])
        {
        const float x = ndof->rx;
        const float y = ndof->ry;
@@ -988,6 +1008,8 @@
        RegionView3D* rv3d = CTX_wm_region_view3d(C);
        wmNDOFMotionData* ndof = (wmNDOFMotionData*) event->customdata;
 
+       const float dt = ndof->dt;
+
        // tune these until everything feels right
        const float rot_sensitivity = 1.f;
        const float zoom_sensitivity = 1.f;
@@ -996,12 +1018,6 @@
        // rather have bool, but...
        int has_rotation = rv3d->viewlock != RV3D_LOCKED && (ndof->rx || 
ndof->ry || ndof->rz);
 
-       float dt = ndof->dt;
-       if (dt > 0.25f)
-               /* this is probably the first event for this motion, so set dt 
to something reasonable */

@@ Diff output truncated at 10240 characters. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to