[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [38405] branches/merwin-spacenav: more consistent and modal-friendly ndof events, fly mode v1

Mike Erwin significant.bit at gmail.com
Thu Jul 14 23:20:46 CEST 2011


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. @@



More information about the Bf-blender-cvs mailing list