now using blender view coordinates for ndof input -- core and Linux in place
This commit is contained in:
@@ -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];
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user