Code cleanup: de-duplicate ndof controls for walk/fly mode
This commit is contained in:
@@ -1148,7 +1148,7 @@ void VIEW3D_OT_rotate(wmOperatorType *ot)
|
||||
* (should these functions live in this file?)
|
||||
*/
|
||||
|
||||
#define NDOF_HAS_TRANSLATE ((!view3d_operator_offset_lock_check(C, op)) && !is_zero_v3(ndof->tvec))
|
||||
#define NDOF_HAS_TRANSLATE ((!ED_view3d_offset_lock_check(v3d, rv3d)) && !is_zero_v3(ndof->tvec))
|
||||
#define NDOF_HAS_ROTATE (((rv3d->viewlock & RV3D_LOCKED) == 0) && !is_zero_v3(ndof->rvec))
|
||||
|
||||
/**
|
||||
@@ -1302,6 +1302,117 @@ static void view3d_ndof_orbit(const struct wmNDOFMotionData *ndof, RegionView3D
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from both fly mode and walk mode,
|
||||
*/
|
||||
void view3d_ndof_fly(
|
||||
const wmNDOFMotionData *ndof,
|
||||
View3D *v3d, RegionView3D *rv3d,
|
||||
const bool use_precision, const short protectflag,
|
||||
bool *r_has_translate, bool *r_has_rotate)
|
||||
{
|
||||
/* shorthand for oft-used variables */
|
||||
const float dt = ndof->dt;
|
||||
|
||||
bool has_translate = NDOF_HAS_TRANSLATE;
|
||||
bool has_rotate = NDOF_HAS_ROTATE;
|
||||
|
||||
float view_inv[4];
|
||||
invert_qt_qt(view_inv, rv3d->viewquat);
|
||||
|
||||
rv3d->rot_angle = 0.0f; /* disable onscreen rotation doo-dad */
|
||||
|
||||
if (has_translate) {
|
||||
float speed = 10.0f; /* blender units per second */
|
||||
float trans[3], trans_orig_y;
|
||||
/* ^^ this is ok for default cube scene, but should scale with.. something */
|
||||
if (use_precision)
|
||||
speed *= 0.2f;
|
||||
|
||||
WM_event_ndof_pan_get(ndof, trans, false);
|
||||
mul_v3_fl(trans, speed * dt);
|
||||
trans_orig_y = trans[1];
|
||||
|
||||
/* transform motion from view to world coordinates */
|
||||
mul_qt_v3(view_inv, trans);
|
||||
|
||||
if (U.ndof_flag & NDOF_FLY_HELICOPTER) {
|
||||
/* replace world z component with device y (yes it makes sense) */
|
||||
trans[2] = trans_orig_y;
|
||||
}
|
||||
|
||||
if (rv3d->persp == RV3D_CAMOB) {
|
||||
/* respect camera position locks */
|
||||
if (protectflag & OB_LOCK_LOCX) trans[0] = 0.0f;
|
||||
if (protectflag & OB_LOCK_LOCY) trans[1] = 0.0f;
|
||||
if (protectflag & OB_LOCK_LOCZ) trans[2] = 0.0f;
|
||||
}
|
||||
|
||||
if (!is_zero_v3(trans)) {
|
||||
/* move center of view opposite of hand motion (this is camera mode, not object mode) */
|
||||
sub_v3_v3(rv3d->ofs, trans);
|
||||
has_translate = true;
|
||||
}
|
||||
else {
|
||||
has_translate = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (has_rotate) {
|
||||
const float turn_sensitivity = 1.0f;
|
||||
|
||||
float rotation[4];
|
||||
float axis[3];
|
||||
float angle = turn_sensitivity * WM_event_ndof_to_axis_angle(ndof, axis);
|
||||
|
||||
if (fabsf(angle) > 0.0001f) {
|
||||
has_rotate = true;
|
||||
|
||||
if (use_precision)
|
||||
angle *= 0.2f;
|
||||
|
||||
/* transform rotation axis from view to world coordinates */
|
||||
mul_qt_v3(view_inv, axis);
|
||||
|
||||
/* apply rotation to view */
|
||||
axis_angle_to_quat(rotation, axis, angle);
|
||||
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rotation);
|
||||
|
||||
if (U.ndof_flag & NDOF_LOCK_HORIZON) {
|
||||
/* force an upright viewpoint
|
||||
* TODO: make this less... sudden */
|
||||
float view_horizon[3] = {1.0f, 0.0f, 0.0f}; /* view +x */
|
||||
float view_direction[3] = {0.0f, 0.0f, -1.0f}; /* view -z (into screen) */
|
||||
|
||||
/* find new inverse since viewquat has changed */
|
||||
invert_qt_qt(view_inv, rv3d->viewquat);
|
||||
/* could apply reverse rotation to existing view_inv to save a few cycles */
|
||||
|
||||
/* transform view vectors to world coordinates */
|
||||
mul_qt_v3(view_inv, view_horizon);
|
||||
mul_qt_v3(view_inv, view_direction);
|
||||
|
||||
|
||||
/* find difference between view & world horizons
|
||||
* true horizon lives in world xy plane, so look only at difference in z */
|
||||
angle = -asinf(view_horizon[2]);
|
||||
|
||||
/* rotate view so view horizon = world horizon */
|
||||
axis_angle_to_quat(rotation, view_direction, angle);
|
||||
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rotation);
|
||||
}
|
||||
|
||||
rv3d->view = RV3D_VIEW_USER;
|
||||
}
|
||||
else {
|
||||
has_rotate = false;
|
||||
}
|
||||
}
|
||||
|
||||
*r_has_translate = has_translate;
|
||||
*r_has_rotate = has_rotate;
|
||||
}
|
||||
|
||||
/* -- "orbit" navigation (trackball/turntable)
|
||||
* -- zooming
|
||||
* -- panning in rotationally-locked views
|
||||
@@ -1440,7 +1551,7 @@ void VIEW3D_OT_ndof_orbit_zoom(struct wmOperatorType *ot)
|
||||
/* -- "pan" navigation
|
||||
* -- zoom or dolly?
|
||||
*/
|
||||
static int ndof_pan_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
static int ndof_pan_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
|
||||
{
|
||||
if (event->type != NDOF_MOTION) {
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
@@ -944,127 +944,23 @@ static int flyApply(bContext *C, FlyInfo *fly)
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static int flyApply_ndof(bContext *C, FlyInfo *fly)
|
||||
static void flyApply_ndof(bContext *C, FlyInfo *fly)
|
||||
{
|
||||
/* shorthand for oft-used variables */
|
||||
wmNDOFMotionData *ndof = fly->ndof;
|
||||
const float dt = ndof->dt;
|
||||
RegionView3D *rv3d = fly->rv3d;
|
||||
const int flag = U.ndof_flag;
|
||||
Object *lock_ob = ED_view3d_cameracontrol_object_get(fly->v3d_camera_control);
|
||||
bool has_translate, has_rotate;
|
||||
|
||||
#if 0
|
||||
bool do_rotate = (flag & NDOF_SHOULD_ROTATE) && (fly->pan_view == false);
|
||||
bool do_translate = (flag & (NDOF_SHOULD_PAN | NDOF_SHOULD_ZOOM)) != 0;
|
||||
#endif
|
||||
view3d_ndof_fly(fly->ndof,
|
||||
fly->v3d, fly->rv3d,
|
||||
fly->use_precision, lock_ob ? lock_ob->protectflag : 0,
|
||||
&has_translate, &has_rotate);
|
||||
|
||||
bool do_rotate = (fly->pan_view == false);
|
||||
bool do_translate = true;
|
||||
|
||||
float view_inv[4];
|
||||
invert_qt_qt(view_inv, rv3d->viewquat);
|
||||
|
||||
rv3d->rot_angle = 0.0f; /* disable onscreen rotation doo-dad */
|
||||
|
||||
if (do_translate) {
|
||||
float speed = 10.0f; /* blender units per second */
|
||||
float trans[3], trans_orig_y;
|
||||
/* ^^ this is ok for default cube scene, but should scale with.. something */
|
||||
if (fly->use_precision)
|
||||
speed *= 0.2f;
|
||||
|
||||
WM_event_ndof_pan_get(ndof, trans, false);
|
||||
mul_v3_fl(trans, speed * dt);
|
||||
trans_orig_y = trans[1];
|
||||
|
||||
/* transform motion from view to world coordinates */
|
||||
mul_qt_v3(view_inv, trans);
|
||||
|
||||
if (flag & NDOF_FLY_HELICOPTER) {
|
||||
/* replace world z component with device y (yes it makes sense) */
|
||||
trans[2] = trans_orig_y;
|
||||
}
|
||||
|
||||
if (rv3d->persp == RV3D_CAMOB) {
|
||||
/* respect camera position locks */
|
||||
Object *lock_ob = ED_view3d_cameracontrol_object_get(fly->v3d_camera_control);
|
||||
if (lock_ob->protectflag & OB_LOCK_LOCX) trans[0] = 0.0f;
|
||||
if (lock_ob->protectflag & OB_LOCK_LOCY) trans[1] = 0.0f;
|
||||
if (lock_ob->protectflag & OB_LOCK_LOCZ) trans[2] = 0.0f;
|
||||
}
|
||||
|
||||
if (!is_zero_v3(trans)) {
|
||||
/* move center of view opposite of hand motion (this is camera mode, not object mode) */
|
||||
sub_v3_v3(rv3d->ofs, trans);
|
||||
do_translate = true;
|
||||
}
|
||||
else {
|
||||
do_translate = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (do_rotate) {
|
||||
const float turn_sensitivity = 1.0f;
|
||||
|
||||
float rotation[4];
|
||||
float axis[3];
|
||||
float angle = turn_sensitivity * WM_event_ndof_to_axis_angle(ndof, axis);
|
||||
|
||||
if (fabsf(angle) > 0.0001f) {
|
||||
do_rotate = true;
|
||||
|
||||
if (fly->use_precision)
|
||||
angle *= 0.2f;
|
||||
|
||||
/* transform rotation axis from view to world coordinates */
|
||||
mul_qt_v3(view_inv, axis);
|
||||
|
||||
/* apply rotation to view */
|
||||
axis_angle_to_quat(rotation, axis, angle);
|
||||
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rotation);
|
||||
|
||||
if (flag & NDOF_LOCK_HORIZON) {
|
||||
/* force an upright viewpoint
|
||||
* TODO: make this less... sudden */
|
||||
float view_horizon[3] = {1.0f, 0.0f, 0.0f}; /* view +x */
|
||||
float view_direction[3] = {0.0f, 0.0f, -1.0f}; /* view -z (into screen) */
|
||||
|
||||
/* find new inverse since viewquat has changed */
|
||||
invert_qt_qt(view_inv, rv3d->viewquat);
|
||||
/* could apply reverse rotation to existing view_inv to save a few cycles */
|
||||
|
||||
/* transform view vectors to world coordinates */
|
||||
mul_qt_v3(view_inv, view_horizon);
|
||||
mul_qt_v3(view_inv, view_direction);
|
||||
|
||||
/* find difference between view & world horizons
|
||||
* true horizon lives in world xy plane, so look only at difference in z */
|
||||
angle = -asinf(view_horizon[2]);
|
||||
|
||||
#ifdef NDOF_FLY_DEBUG
|
||||
printf("lock horizon: adjusting %.1f degrees\n\n", RAD2DEG(angle));
|
||||
#endif
|
||||
|
||||
/* rotate view so view horizon = world horizon */
|
||||
axis_angle_to_quat(rotation, view_direction, angle);
|
||||
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rotation);
|
||||
}
|
||||
|
||||
rv3d->view = RV3D_VIEW_USER;
|
||||
}
|
||||
else {
|
||||
do_rotate = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (do_translate || do_rotate) {
|
||||
if (has_translate || has_rotate) {
|
||||
fly->redraw = true;
|
||||
|
||||
if (rv3d->persp == RV3D_CAMOB) {
|
||||
flyMoveCamera(C, fly, do_rotate, do_translate);
|
||||
if (fly->rv3d->persp == RV3D_CAMOB) {
|
||||
flyMoveCamera(C, fly, has_rotate, has_translate);
|
||||
}
|
||||
}
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static int fly_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
|
||||
@@ -107,6 +107,12 @@ void VIEW3D_OT_zoom_border(struct wmOperatorType *ot);
|
||||
|
||||
void view3d_boxview_copy(ScrArea *sa, ARegion *ar);
|
||||
|
||||
void view3d_ndof_fly(
|
||||
const struct wmNDOFMotionData *ndof,
|
||||
struct View3D *v3d, struct RegionView3D *rv3d,
|
||||
const bool use_precision, const short protectflag,
|
||||
bool *r_has_translate, bool *r_has_rotate);
|
||||
|
||||
/* view3d_fly.c */
|
||||
void view3d_keymap(struct wmKeyConfig *keyconf);
|
||||
void VIEW3D_OT_fly(struct wmOperatorType *ot);
|
||||
|
||||
@@ -1217,128 +1217,23 @@ static int walkApply(bContext *C, WalkInfo *walk)
|
||||
#undef WALK_BOOST_FACTOR
|
||||
}
|
||||
|
||||
static int walkApply_ndof(bContext *C, WalkInfo *walk)
|
||||
static void walkApply_ndof(bContext *C, WalkInfo *walk)
|
||||
{
|
||||
/* shorthand for oft-used variables */
|
||||
wmNDOFMotionData *ndof = walk->ndof;
|
||||
const float dt = ndof->dt;
|
||||
RegionView3D *rv3d = walk->rv3d;
|
||||
const int flag = U.ndof_flag;
|
||||
Object *lock_ob = ED_view3d_cameracontrol_object_get(walk->v3d_camera_control);
|
||||
bool has_translate, has_rotate;
|
||||
|
||||
#if 0
|
||||
bool do_rotate = (flag & NDOF_SHOULD_ROTATE) && (walk->pan_view == false);
|
||||
bool do_translate = (flag & (NDOF_SHOULD_PAN | NDOF_SHOULD_ZOOM)) != 0;
|
||||
#endif
|
||||
view3d_ndof_fly(walk->ndof,
|
||||
walk->v3d, walk->rv3d,
|
||||
walk->is_slow, lock_ob ? lock_ob->protectflag : 0,
|
||||
&has_translate, &has_rotate);
|
||||
|
||||
bool do_rotate = true;
|
||||
bool do_translate = true;
|
||||
|
||||
float view_inv[4];
|
||||
invert_qt_qt(view_inv, rv3d->viewquat);
|
||||
|
||||
rv3d->rot_angle = 0.0f; /* disable onscreen rotation doo-dad */
|
||||
|
||||
if (do_translate) {
|
||||
float speed = 10.0f; /* blender units per second */
|
||||
float trans[3], trans_orig_y;
|
||||
/* ^^ this is ok for default cube scene, but should scale with.. something */
|
||||
if (walk->is_slow)
|
||||
speed *= 0.2f;
|
||||
|
||||
WM_event_ndof_pan_get(ndof, trans, false);
|
||||
mul_v3_fl(trans, speed * dt);
|
||||
trans_orig_y = trans[1];
|
||||
|
||||
/* transform motion from view to world coordinates */
|
||||
mul_qt_v3(view_inv, trans);
|
||||
|
||||
if (flag & NDOF_FLY_HELICOPTER) {
|
||||
/* replace world z component with device y (yes it makes sense) */
|
||||
trans[2] = trans_orig_y;
|
||||
}
|
||||
|
||||
if (rv3d->persp == RV3D_CAMOB) {
|
||||
/* respect camera position locks */
|
||||
Object *lock_ob = ED_view3d_cameracontrol_object_get(walk->v3d_camera_control);
|
||||
if (lock_ob->protectflag & OB_LOCK_LOCX) trans[0] = 0.0f;
|
||||
if (lock_ob->protectflag & OB_LOCK_LOCY) trans[1] = 0.0f;
|
||||
if (lock_ob->protectflag & OB_LOCK_LOCZ) trans[2] = 0.0f;
|
||||
}
|
||||
|
||||
if (!is_zero_v3(trans)) {
|
||||
/* move center of view opposite of hand motion (this is camera mode, not object mode) */
|
||||
sub_v3_v3(rv3d->ofs, trans);
|
||||
do_translate = true;
|
||||
}
|
||||
else {
|
||||
do_translate = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (do_rotate) {
|
||||
const float turn_sensitivity = 1.0f;
|
||||
|
||||
float rotation[4];
|
||||
float axis[3];
|
||||
float angle = turn_sensitivity * WM_event_ndof_to_axis_angle(ndof, axis);
|
||||
|
||||
if (fabsf(angle) > 0.0001f) {
|
||||
do_rotate = true;
|
||||
|
||||
if (walk->is_slow)
|
||||
angle *= 0.2f;
|
||||
|
||||
/* transform rotation axis from view to world coordinates */
|
||||
mul_qt_v3(view_inv, axis);
|
||||
|
||||
/* apply rotation to view */
|
||||
axis_angle_to_quat(rotation, axis, angle);
|
||||
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rotation);
|
||||
|
||||
if (flag & NDOF_LOCK_HORIZON) {
|
||||
/* force an upright viewpoint
|
||||
* TODO: make this less... sudden */
|
||||
float view_horizon[3] = {1.0f, 0.0f, 0.0f}; /* view +x */
|
||||
float view_direction[3] = {0.0f, 0.0f, -1.0f}; /* view -z (into screen) */
|
||||
|
||||
/* find new inverse since viewquat has changed */
|
||||
invert_qt_qt(view_inv, rv3d->viewquat);
|
||||
/* could apply reverse rotation to existing view_inv to save a few cycles */
|
||||
|
||||
/* transform view vectors to world coordinates */
|
||||
mul_qt_v3(view_inv, view_horizon);
|
||||
mul_qt_v3(view_inv, view_direction);
|
||||
|
||||
|
||||
/* find difference between view & world horizons
|
||||
* true horizon lives in world xy plane, so look only at difference in z */
|
||||
angle = -asinf(view_horizon[2]);
|
||||
|
||||
#ifdef NDOF_WALK_DEBUG
|
||||
printf("lock horizon: adjusting %.1f degrees\n\n", RAD2DEG(angle));
|
||||
#endif
|
||||
|
||||
/* rotate view so view horizon = world horizon */
|
||||
axis_angle_to_quat(rotation, view_direction, angle);
|
||||
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rotation);
|
||||
}
|
||||
|
||||
rv3d->view = RV3D_VIEW_USER;
|
||||
}
|
||||
else {
|
||||
do_rotate = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (do_translate || do_rotate) {
|
||||
if (has_translate || has_rotate) {
|
||||
walk->redraw = true;
|
||||
|
||||
if (rv3d->persp == RV3D_CAMOB) {
|
||||
walkMoveCamera(C, walk, do_rotate, do_translate);
|
||||
if (walk->rv3d->persp == RV3D_CAMOB) {
|
||||
walkMoveCamera(C, walk, has_rotate, has_translate);
|
||||
}
|
||||
}
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
/****** walk operator ******/
|
||||
|
||||
Reference in New Issue
Block a user