From d56ed8dcd95ba31dc860b01d692a93ccd1ba1fce Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 19 Feb 2014 21:19:13 +1100 Subject: Code cleanup: de-duplicate ndof controls for walk/fly mode --- source/blender/editors/space_view3d/view3d_edit.c | 115 ++++++++++++++++++- source/blender/editors/space_view3d/view3d_fly.c | 124 ++------------------ .../blender/editors/space_view3d/view3d_intern.h | 6 + source/blender/editors/space_view3d/view3d_walk.c | 125 ++------------------- 4 files changed, 139 insertions(+), 231 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index bcf09621748..3d4cee41227 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -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; diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c index fed94d6b6ab..42e74be0460 100644 --- a/source/blender/editors/space_view3d/view3d_fly.c +++ b/source/blender/editors/space_view3d/view3d_fly.c @@ -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; - -#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 - - 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); + Object *lock_ob = ED_view3d_cameracontrol_object_get(fly->v3d_camera_control); + bool has_translate, has_rotate; - if (fabsf(angle) > 0.0001f) { - do_rotate = true; + view3d_ndof_fly(fly->ndof, + fly->v3d, fly->rv3d, + fly->use_precision, lock_ob ? lock_ob->protectflag : 0, + &has_translate, &has_rotate); - 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) diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index 86b1891074d..71bef914e77 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -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); diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c index 9a57fee95f9..c6d0999d077 100644 --- a/source/blender/editors/space_view3d/view3d_walk.c +++ b/source/blender/editors/space_view3d/view3d_walk.c @@ -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; - -#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 - - 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); + Object *lock_ob = ED_view3d_cameracontrol_object_get(walk->v3d_camera_control); + bool has_translate, has_rotate; - if (fabsf(angle) > 0.0001f) { - do_rotate = true; + view3d_ndof_fly(walk->ndof, + walk->v3d, walk->rv3d, + walk->is_slow, lock_ob ? lock_ob->protectflag : 0, + &has_translate, &has_rotate); - 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 ******/ -- cgit v1.2.3