small fix to turntable mode, first attempt at trackball code, ndof now respects view locking and updates 'User Persp' etc.

This commit is contained in:
Mike Erwin 2011-06-20 01:54:49 +00:00
parent 85051eff69
commit 015b0ea00a
2 changed files with 81 additions and 30 deletions

@ -175,7 +175,9 @@ void GHOST_NDOFManager::setDevice(unsigned short vendor_id, unsigned short produ
// -- 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
default: printf("ndof: unknown Logitech product %04hx\n", product_id);
}
@ -185,7 +187,10 @@ void GHOST_NDOFManager::setDevice(unsigned short vendor_id, unsigned short produ
}
m_buttonMask = ~(-1 << m_buttonCount);
printf("ndof: %d buttons -> %X\n", m_buttonCount, m_buttonMask);
#ifdef DEBUG_NDOF_BUTTONS
printf("ndof: %d buttons -> hex:%X\n", m_buttonCount, m_buttonMask);
#endif
}
void GHOST_NDOFManager::updateTranslation(short t[3], GHOST_TUns64 time)
@ -312,7 +317,7 @@ bool GHOST_NDOFManager::sendMotionEvent()
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];

@ -954,47 +954,93 @@ static int viewndof_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
wmNDOFMotionData* ndof = (wmNDOFMotionData*) event->customdata;
float sensitivity = 1.f; /* ooh, magic number!
const float sensitivity = 0.035; /* ooh, magic number!
there will be several of these as interactions get tuned */
float dt = ndof->dt;
if (dt > 0.25f)
/* this is probably the first event for this motion, so set dt to something reasonable */
/* TODO: replace such guesswork with a flag or field from the NDOF manager */
dt = 0.0125f;
RegionView3D* rv3d = CTX_wm_region_view3d(C);
/* 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 xvec[3] = {1,0,0};
int /* bool */ has_rotation = rv3d->viewlock != RV3D_LOCKED && (ndof->rx || ndof->ry || ndof->rz);
if (has_rotation)
rv3d->view = RV3D_VIEW_USER;
const float sensitivity = 0.035;
if (has_rotation) {
if (U.flag & USER_TRACKBALL) {
/* TODO: write trackball code! */
if (dt > 0.25f)
/* this is probably the first event for this motion, so set dt to something reasonable */
dt = 0.0125f;
float axis[3] = {ndof->rx, ndof->ry, ndof->rz};
float angle = sensitivity * dt * ndof_to_angle_axis(axis, axis);
float rotation[4], rotationconj[4];
float view[4], viewconj[4];
/* Get the 3x3 matrix and its inverse from the quaternion */
quat_to_mat3(m,rv3d->viewquat);
invert_m3_m3(m_inv,m);
// convert to quaternion
axis_angle_to_quat(rotation, axis, angle);
/* 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);
// extract rotation component of viewquat
copy_qt_qt(view, rv3d->viewquat);
invert_qt(view);
normalize_qt(view);
copy_qt_qt(viewconj, view);
conjugate_qt(viewconj);
/* Perform the up/down rotation */
phi = sensitivity * -ndof->rx;
q1[0] = cos(phi);
mul_v3_v3fl(q1+1, xvec, sin(phi));
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, q1);
// transform device rotation into view's frame of reference
// rotation(view) = view * rotation(world) * viewconj
mul_qt_qtqt(rotation, rotation, viewconj);
mul_qt_qtqt(rotation, view, rotation);
/* Perform the orbital rotation */
phi = sensitivity * ndof->rz;
q1[0] = cos(phi);
q1[1] = q1[2] = 0.0;
q1[3] = sin(phi);
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, q1);
// apply rotation to obtain new viewpoint
// copy_qt_qt(rotationconj, rotation);
// conjugate_qt(rotationconj);
// mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rotationconj);
// mul_qt_qtqt(rv3d->viewquat, rotation, rv3d->viewquat);
mul_qt_qtqt(rv3d->viewquat, rotation, rv3d->viewquat);
ED_region_tag_redraw(CTX_wm_region(C));
return OPERATOR_FINISHED;
// this is *close* to trackball behavior
// rotation axis needs to remain fixed relative to viewpoint, not world coordinates
ED_region_tag_redraw(CTX_wm_region(C));
} 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 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);
/* Perform the up/down rotation */
phi = sensitivity * dt * ndof->rx;
q1[0] = cos(phi);
mul_v3_v3fl(q1+1, xvec, sin(phi));
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, q1);
/* Perform the orbital rotation */
phi = 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);
ED_region_tag_redraw(CTX_wm_region(C));
}
}
return OPERATOR_FINISHED;
}
// Tom's version
#if 0
static int viewndof_invoke(bContext *C, wmOperator *op, wmEvent *event)