now using blender view coordinates for ndof input -- core and Linux in place

This commit is contained in:
Mike Erwin
2011-06-27 20:12:10 +00:00
parent b8e8f8064d
commit edd5980436
5 changed files with 43 additions and 63 deletions

View File

@@ -307,17 +307,16 @@ bool GHOST_NDOFManager::sendMotionEvent()
GHOST_EventNDOFMotion* event = new GHOST_EventNDOFMotion(m_motionTime, window);
GHOST_TEventNDOFMotionData* data = (GHOST_TEventNDOFMotionData*) event->getData();
const float scale = 1.f / 350.f; // SpaceNavigator sends +/- 350 usually
// 350 according to their developer's guide; others recommend 500 as comfortable
const float scale = 1.f / 350.f; // 3Dconnexion devices send +/- 350 usually
// possible future enhancement
// scale *= m_sensitivity;
data->tx = -scale * m_translation[0];
data->tx = scale * m_translation[0];
data->ty = scale * m_translation[1];
data->tz = scale * m_translation[2];
data->rx = -scale * m_rotation[0];
data->rx = scale * m_rotation[0];
data->ry = scale * m_rotation[1];
data->rz = scale * m_rotation[2];

View File

@@ -29,7 +29,7 @@
// --- 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;
@@ -93,6 +93,14 @@ public:
void setDevice(unsigned short vendor_id, unsigned short product_id);
// the latest raw axis data from the device
// NOTE: axis data should be in blender view coordinates
// +X is to the right
// +Y is up
// +Z is out of the screen
// for rotations, look from origin to each +axis
// rotations are + when CCW, - when CW
// each platform is responsible for getting axis data into this form
// these values should not be scaled (just shuffled or flipped)
void updateTranslation(short t[3], GHOST_TUns64 time);
void updateRotation(short r[3], GHOST_TUns64 time);

View File

@@ -86,8 +86,17 @@ bool GHOST_NDOFManagerX11::processEvents()
{
case SPNAV_EVENT_MOTION:
{
short t[3] = {e.motion.x, e.motion.y, e.motion.z};
short r[3] = {e.motion.rx, e.motion.ry, e.motion.rz};
// "natural" device coords
// short t[3] = {e.motion.x, e.motion.y, e.motion.z};
// short r[3] = {e.motion.rx, e.motion.ry, e.motion.rz};
// blender world coords
// short t[3] = {e.motion.x, e.motion.z, e.motion.y};
// short r[3] = {-e.motion.rx, -e.motion.rz, -e.motion.ry};
// blender view coords
short t[3] = {e.motion.x, e.motion.y, -e.motion.z};
short r[3] = {-e.motion.rx, -e.motion.ry, e.motion.rz};
updateTranslation(t, now);
updateRotation(r, now);

View File

@@ -440,7 +440,7 @@ void IMAGE_OT_view_zoom(wmOperatorType *ot)
/********************** NDOF operator *********************/
/* Combined pan/zoom from a 3D mouse device.
* Y zooms, XZ pans
* 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
*/
@@ -461,8 +461,8 @@ static int view_ndof_invoke(bContext *C, wmOperator *op, wmEvent *event)
const float zoom_sensitivity = 0.5f;
const float pan_sensitivity = 300.f;
float pan_x = pan_sensitivity * dt * -ndof->tx / sima->zoom;
float pan_y = pan_sensitivity * dt * -ndof->tz / sima->zoom;
float pan_x = pan_sensitivity * dt * ndof->tx / sima->zoom;
float pan_y = pan_sensitivity * dt * ndof->ty / sima->zoom;
/* "mouse zoom" factor = 1 + (dx + dy) / 300
* what about "ndof zoom" factor? should behave like this:
@@ -470,7 +470,7 @@ static int view_ndof_invoke(bContext *C, wmOperator *op, wmEvent *event)
* move forward -> factor > 1
* move backward -> factor < 1
*/
float zoom_factor = 1.f + zoom_sensitivity * dt * -ndof->ty;
float zoom_factor = 1.f + zoom_sensitivity * dt * -ndof->tz;
sima_zoom_set_factor(sima, ar, zoom_factor);
sima->xof += pan_x;

View File

@@ -1003,10 +1003,10 @@ static int viewndof_invoke(bContext *C, wmOperator *op, wmEvent *event)
// [got that?]
// proportional to s = r * theta
float zoom_distance = zoom_sensitivity * rv3d->dist * dt * ndof->ty;
float zoom_distance = zoom_sensitivity * rv3d->dist * dt * ndof->tz;
rv3d->dist += zoom_distance;
ED_region_tag_redraw(CTX_wm_region(C));
ED_region_tag_redraw(CTX_wm_region(C));
}
if (has_rotation) {
@@ -1020,13 +1020,7 @@ static int viewndof_invoke(bContext *C, wmOperator *op, wmEvent *event)
ndof_to_quat(ndof, rot);
// scale by rot_sensitivity?
// swap y and z -- not sure why, but it works
{
float temp = -rot[2]; // also invert device y
rot[2] = rot[3];
rot[3] = temp;
}
// mul_qt_fl(rot, rot_sensitivity);
invert_qt_qt(view_inv, rv3d->viewquat);
copy_qt_qt(view_inv_conj, view_inv);
@@ -1043,31 +1037,26 @@ static int viewndof_invoke(bContext *C, wmOperator *op, wmEvent *event)
} else {
/* turntable view code by John Aughey, adapted for 3D mouse by [mce] */
float phi, q1[4];
float m[3][3];
float m_inv[3][3];
float angle, rot[4];
float xvec[3] = {1,0,0};
/* Get the 3x3 matrix and its inverse from the quaternion */
quat_to_mat3(m,rv3d->viewquat);
invert_m3_m3(m_inv,m);
/* Determine the direction of the x vector (for rotating up and down) */
/* This can likely be computed directly from the quaternion. */
mul_m3_v3(m_inv,xvec);
float view_inv[4]/*, view_inv_conj[4]*/;
invert_qt_qt(view_inv, rv3d->viewquat);
mul_qt_v3(view_inv, xvec);
/* Perform the up/down rotation */
phi = rot_sensitivity * dt * ndof->rx;
q1[0] = cos(phi);
mul_v3_v3fl(q1+1, xvec, sin(phi));
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, q1);
angle = rot_sensitivity * dt * ndof->rx;
rot[0] = cos(angle);
mul_v3_v3fl(rot+1, xvec, sin(angle));
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot);
/* Perform the orbital rotation */
phi = rot_sensitivity * dt * ndof->rz;
q1[0] = cos(phi);
q1[1] = q1[2] = 0.0;
q1[3] = sin(phi);
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, q1);
angle = rot_sensitivity * dt * ndof->ry;
rot[0] = cos(angle);
rot[1] = rot[2] = 0.0;
rot[3] = sin(angle);
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot);
ED_region_tag_redraw(CTX_wm_region(C));
}
@@ -1161,31 +1150,6 @@ static int viewndof_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
#endif
#if 0
static int viewndof_invoke_1st_try(bContext *C, wmOperator *op, wmEvent *event)
{
wmNDOFMotionData* ndof = (wmNDOFMotionData*) event->customdata;
float dt = ndof->dt;
RegionView3D *rv3d= CTX_wm_region_view3d(C);
if (dt > 0.25f)
/* this is probably the first event for this motion, so set dt to something reasonable */
dt = 0.0125f;
/* very simple for now, move viewpoint along world axes */
rv3d->ofs[0] += dt * ndof->tx;
rv3d->ofs[1] += dt * ndof->ty;
rv3d->ofs[2] += dt * ndof->tz;
// request_depth_update(CTX_wm_region_view3d(C)); /* need this? */
ED_region_tag_redraw(CTX_wm_region(C));
return OPERATOR_FINISHED;
}
#endif
void VIEW3D_OT_ndof(struct wmOperatorType *ot)
{
/* identifiers */