Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Erwin <significant.bit@gmail.com>2011-07-15 01:20:45 +0400
committerMike Erwin <significant.bit@gmail.com>2011-07-15 01:20:45 +0400
commitcc1ba4569ccdb77a9371140def316caecac71da5 (patch)
treecc1329237f33e5c586177f60e46000943ebc99f6 /intern/ghost
parent44d2e6eb109889f49fb9935d05ef201127d15805 (diff)
more consistent and modal-friendly ndof events, fly mode v1
Diffstat (limited to 'intern/ghost')
-rw-r--r--intern/ghost/GHOST_Types.h24
-rw-r--r--intern/ghost/intern/GHOST_NDOFManager.cpp96
-rw-r--r--intern/ghost/intern/GHOST_NDOFManager.h9
3 files changed, 98 insertions, 31 deletions
diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h
index bc731a43ae7..85f73a25b47 100644
--- a/intern/ghost/GHOST_Types.h
+++ b/intern/ghost/GHOST_Types.h
@@ -434,14 +434,24 @@ typedef struct {
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;
diff --git a/intern/ghost/intern/GHOST_NDOFManager.cpp b/intern/ghost/intern/GHOST_NDOFManager.cpp
index 4d2f06f8191..e001540aa95 100644
--- a/intern/ghost/intern/GHOST_NDOFManager.cpp
+++ b/intern/ghost/intern/GHOST_NDOFManager.cpp
@@ -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 @@ GHOST_NDOFManager::GHOST_NDOFManager(GHOST_System& sys)
, 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 @@ void GHOST_NDOFManager::setDevice(unsigned short vendor_id, unsigned short produ
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 @@ void GHOST_NDOFManager::setDevice(unsigned short vendor_id, unsigned short produ
#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 @@ void GHOST_NDOFManager::updateButtons(int button_bits, GHOST_TUns64 time)
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 @@ void GHOST_NDOFManager::updateButtons(int button_bits, GHOST_TUns64 time)
}
}
-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 @@ bool GHOST_NDOFManager::sendMotionEvent()
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 @@ bool GHOST_NDOFManager::sendMotionEvent()
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);
-
- // 'at rest' test goes at the end so that the first 'rest' event gets sent
- m_atRest = atHomePosition(data, 0.05f);
+ m_motionEventPending = false;
return true;
}
diff --git a/intern/ghost/intern/GHOST_NDOFManager.h b/intern/ghost/intern/GHOST_NDOFManager.h
index 155510d6d7f..cabff22fca7 100644
--- a/intern/ghost/intern/GHOST_NDOFManager.h
+++ b/intern/ghost/intern/GHOST_NDOFManager.h
@@ -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,7 +118,7 @@ protected:
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;
@@ -132,7 +130,8 @@ private:
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