diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2012-08-19 17:52:36 +0400 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2012-08-19 17:52:36 +0400 |
commit | adec7cdea2ea3404577be1957e222ec42604c469 (patch) | |
tree | f02a7e95d41518d3324df9522f60dcbc03169f7c | |
parent | d36da8a8a1079d35aae445b76027a37c46f027be (diff) |
Patch #32326: NDOF support of rotation and panning the view at the same time
Additional changes:
- Option to the ndof menu letting you pick turntable/trackball independently
of the mouse viewport navigation style
- Option to change the rotation sensitivity separate from the panning
Holding shift + moving the ndof does just as before locking it to panning
Holding ctrl + moving will lock it to only rotation
Patch by Fredrik Hansson, thanks!
Reviewed by self and Mike Erwin.
-rw-r--r-- | release/scripts/startup/bl_ui/space_userpref.py | 7 | ||||
-rw-r--r-- | source/blender/editors/interface/resources.c | 4 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_edit.c | 223 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_intern.h | 1 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_ops.c | 4 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_userdef_types.h | 3 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_userdef.c | 11 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 7 |
8 files changed, 210 insertions, 50 deletions
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index e7dd9fb4751..b0b587056b1 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -858,6 +858,7 @@ class USERPREF_MT_ndof_settings(Menu): layout.separator() layout.prop(input_prefs, "ndof_sensitivity") + layout.prop(input_prefs, "ndof_orbit_sensitivity") if context.space_data.type == 'VIEW_3D': layout.separator() @@ -865,11 +866,10 @@ class USERPREF_MT_ndof_settings(Menu): layout.separator() layout.label(text="Orbit options") - if input_prefs.view_rotate_method == 'TRACKBALL': - layout.prop(input_prefs, "ndof_roll_invert_axis") + layout.prop(input_prefs, "ndof_turntable") + layout.prop(input_prefs, "ndof_roll_invert_axis") layout.prop(input_prefs, "ndof_tilt_invert_axis") layout.prop(input_prefs, "ndof_rotate_invert_axis") - layout.prop(input_prefs, "ndof_zoom_invert") layout.separator() layout.label(text="Pan options") @@ -878,6 +878,7 @@ class USERPREF_MT_ndof_settings(Menu): layout.prop(input_prefs, "ndof_panz_invert_axis") layout.label(text="Zoom options") + layout.prop(input_prefs, "ndof_zoom_invert") layout.prop(input_prefs, "ndof_zoom_updown") layout.separator() diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 20e4360b791..ed6b2e00119 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -1967,6 +1967,10 @@ void init_userdef_do_versions(void) U.ndof_flag = NDOF_LOCK_HORIZON | NDOF_SHOULD_PAN | NDOF_SHOULD_ZOOM | NDOF_SHOULD_ROTATE; } + + if (U.ndof_orbit_sensitivity == 0.0f) { + U.ndof_orbit_sensitivity = 1.0f; + } if (U.tweak_threshold == 0) U.tweak_threshold = 10; diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 310630a65ad..b262819474b 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -1036,20 +1036,6 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event ndof->tx, ndof->ty, ndof->tz, ndof->rx, ndof->ry, ndof->rz, ndof->dt); #endif - if (ndof->tz) { - /* Zoom! - * velocity should be proportional to the linear velocity attained by rotational motion of same strength - * [got that?] - * proportional to arclength = radius * angle - */ - float zoom_distance = zoom_sensitivity * rv3d->dist * dt * ndof->tz; - - if (U.ndof_flag & NDOF_ZOOM_INVERT) - zoom_distance = -zoom_distance; - - rv3d->dist += zoom_distance; - } - if (rv3d->viewlock == RV3D_LOCKED) { /* rotation not allowed -- explore panning options instead */ float pan_vec[3] = {ndof->tx, ndof->ty, 0.0f}; @@ -1067,34 +1053,7 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event rv3d->view = RV3D_VIEW_USER; - if (U.flag & USER_TRACKBALL) { - float rot[4]; - float axis[3]; - float angle = rot_sensitivity * ndof_to_axis_angle(ndof, axis); - - if (U.ndof_flag & NDOF_ROLL_INVERT_AXIS) - axis[2] = -axis[2]; - - if (U.ndof_flag & NDOF_TILT_INVERT_AXIS) - axis[0] = -axis[0]; - - if (U.ndof_flag & NDOF_ROTATE_INVERT_AXIS) - axis[1] = -axis[1]; - - /* transform rotation axis from view to world coordinates */ - mul_qt_v3(view_inv, axis); - - /* update the onscreen doo-dad */ - rv3d->rot_angle = angle; - copy_v3_v3(rv3d->rot_axis, axis); - - axis_angle_to_quat(rot, axis, angle); - - /* apply rotation */ - mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot); - - } - else { + if (U.ndof_flag & NDOF_TURNTABLE) { /* turntable view code by John Aughey, adapted for 3D mouse by [mce] */ float angle, rot[4]; @@ -1127,6 +1086,33 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event rot[3] = sin(angle); mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot); } + else { + float rot[4]; + float axis[3]; + float angle = rot_sensitivity * ndof_to_axis_angle(ndof, axis); + + if (U.ndof_flag & NDOF_ROLL_INVERT_AXIS) + axis[2] = -axis[2]; + + if (U.ndof_flag & NDOF_TILT_INVERT_AXIS) + axis[0] = -axis[0]; + + if (U.ndof_flag & NDOF_ROTATE_INVERT_AXIS) + axis[1] = -axis[1]; + + /* transform rotation axis from view to world coordinates */ + mul_qt_v3(view_inv, axis); + + /* update the onscreen doo-dad */ + rv3d->rot_angle = angle; + copy_v3_v3(rv3d->rot_axis, axis); + + axis_angle_to_quat(rot, axis, angle); + + /* apply rotation */ + mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot); + + } } } @@ -1247,6 +1233,159 @@ void VIEW3D_OT_ndof_pan(struct wmOperatorType *ot) ot->flag = 0; } + +/* +* this is basically just the pan only code + the rotate only code crammed into one function that does both +*/ +static int ndof_all_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + if (event->type != NDOF_MOTION) + return OPERATOR_CANCELLED; + else { + + ViewOpsData *vod; + RegionView3D *rv3d; + + View3D *v3d = CTX_wm_view3d(C); + wmNDOFMotionData *ndof = (wmNDOFMotionData *) event->customdata; + + ED_view3d_camera_lock_init(v3d, rv3d); + + viewops_data_create(C, op, event); + vod = op->customdata; + rv3d = vod->rv3d; + + + if (ndof->progress != P_FINISHING) { + + const float dt = ndof->dt; + float view_inv[4]; + + float speed = 10.f; /* blender units per second */ + /* ^^ this is ok for default cube scene, but should scale with.. something */ + + /* tune these until everything feels right */ + const float forward_sensitivity = 1.f; + const float vertical_sensitivity = 0.4f; + const float lateral_sensitivity = 0.6f; + + float pan_vec[3]; + const float rot_sensitivity = 1.f; + const float zoom_sensitivity = 1.f; + const float pan_sensitivity = 1.f; + float rot[4]; + float axis[3]; + float angle = rot_sensitivity * ndof_to_axis_angle(ndof, axis); + + if (U.ndof_flag & NDOF_PANX_INVERT_AXIS) + pan_vec[0] = -lateral_sensitivity * ndof->tvec[0]; + else + pan_vec[0] = lateral_sensitivity * ndof->tvec[0]; + + if (U.ndof_flag & NDOF_PANZ_INVERT_AXIS) + pan_vec[1] = -vertical_sensitivity * ndof->tvec[1]; + else + pan_vec[1] = vertical_sensitivity * ndof->tvec[1]; + + if (U.ndof_flag & NDOF_PANY_INVERT_AXIS) + pan_vec[2] = -forward_sensitivity * ndof->tvec[2]; + else + pan_vec[2] = forward_sensitivity * ndof->tvec[2]; + + mul_v3_fl(pan_vec, speed * dt); + + /* transform motion from view to world coordinates */ + invert_qt_qt(view_inv, rv3d->viewquat); + mul_qt_v3(view_inv, pan_vec); + + /* move center of view opposite of hand motion (this is camera mode, not object mode) */ + sub_v3_v3(rv3d->ofs, pan_vec); + + if (U.ndof_flag & NDOF_TURNTABLE) { + /* turntable view code by John Aughey, adapted for 3D mouse by [mce] */ + float angle, rot[4]; + float xvec[3] = {1, 0, 0}; + + /* Determine the direction of the x vector (for rotating up and down) */ + mul_qt_v3(view_inv, xvec); + + /* Perform the up/down rotation */ + angle = rot_sensitivity * dt * ndof->rx; + if (U.ndof_flag & NDOF_TILT_INVERT_AXIS) + angle = -angle; + rot[0] = cos(angle); + mul_v3_v3fl(rot + 1, xvec, sin(angle)); + mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot); + + /* Perform the orbital rotation */ + angle = rot_sensitivity * dt * ndof->ry; + if (U.ndof_flag & NDOF_ROTATE_INVERT_AXIS) + angle = -angle; + + /* update the onscreen doo-dad */ + rv3d->rot_angle = angle; + rv3d->rot_axis[0] = 0; + rv3d->rot_axis[1] = 0; + rv3d->rot_axis[2] = 1; + + rot[0] = cos(angle); + rot[1] = rot[2] = 0.0; + rot[3] = sin(angle); + mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot); + + } + else { + + float rot[4]; + float axis[3]; + float angle = rot_sensitivity * ndof_to_axis_angle(ndof, axis); + + if (U.ndof_flag & NDOF_ROLL_INVERT_AXIS) + axis[2] = -axis[2]; + + if (U.ndof_flag & NDOF_TILT_INVERT_AXIS) + axis[0] = -axis[0]; + + if (U.ndof_flag & NDOF_ROTATE_INVERT_AXIS) + axis[1] = -axis[1]; + + /* transform rotation axis from view to world coordinates */ + mul_qt_v3(view_inv, axis); + + /* update the onscreen doo-dad */ + rv3d->rot_angle = angle; + copy_v3_v3(rv3d->rot_axis, axis); + + axis_angle_to_quat(rot, axis, angle); + + /* apply rotation */ + mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot); + + } + } + ED_view3d_camera_lock_sync(v3d, rv3d); + + ED_region_tag_redraw(CTX_wm_region(C)); + viewops_data_free(C, op); + return OPERATOR_FINISHED; + } +} + +void VIEW3D_OT_ndof_all(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "NDOF move View"; + ot->description = "Position your viewpoint with the 3D mouse"; + ot->idname = "VIEW3D_OT_ndof_all"; + + /* api callbacks */ + ot->invoke = ndof_all_invoke; + ot->poll = ED_operator_view3d_active; + + /* flags */ + ot->flag = 0; +} + /* ************************ viewmove ******************************** */ diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index 8b51e6cf226..71e87e73747 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -79,6 +79,7 @@ void VIEW3D_OT_move(struct wmOperatorType *ot); void VIEW3D_OT_rotate(struct wmOperatorType *ot); void VIEW3D_OT_ndof_orbit(struct wmOperatorType *ot); void VIEW3D_OT_ndof_pan(struct wmOperatorType *ot); +void VIEW3D_OT_ndof_all(struct wmOperatorType *ot); void VIEW3D_OT_view_all(struct wmOperatorType *ot); void VIEW3D_OT_viewnumpad(struct wmOperatorType *ot); void VIEW3D_OT_view_selected(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index 7b3e7358978..14c02c2357e 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -64,6 +64,7 @@ void view3d_operatortypes(void) WM_operatortype_append(VIEW3D_OT_dolly); WM_operatortype_append(VIEW3D_OT_ndof_orbit); WM_operatortype_append(VIEW3D_OT_ndof_pan); + WM_operatortype_append(VIEW3D_OT_ndof_all); WM_operatortype_append(VIEW3D_OT_view_all); WM_operatortype_append(VIEW3D_OT_viewnumpad); WM_operatortype_append(VIEW3D_OT_view_orbit); @@ -221,8 +222,9 @@ void view3d_keymap(wmKeyConfig *keyconf) RNA_boolean_set(kmi->ptr, "align_active", TRUE); /* 3D mouse */ - WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_orbit", NDOF_MOTION, 0, 0, 0); + WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_orbit", NDOF_MOTION, 0, KM_CTRL, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_pan", NDOF_MOTION, 0, KM_SHIFT, 0); + WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_all", NDOF_MOTION, 0, 0, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_view_selected", NDOF_BUTTON_FIT, KM_PRESS, 0, 0); RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_FRONT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_FRONT); RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_BACK, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_BACK); diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 8b62f58212b..3f9f4d3980e 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -414,6 +414,8 @@ typedef struct UserDef { short use_16bit_textures, use_gpu_mipmap; float ndof_sensitivity; /* overall sensitivity of 3D mouse */ + float ndof_orbit_sensitivity; + float pad4; int ndof_flag; /* flags for 3D mouse */ float glalphaclip; @@ -649,6 +651,7 @@ extern UserDef U; /* from blenkernel blender.c */ #define NDOF_PANX_INVERT_AXIS (1 << 12) #define NDOF_PANY_INVERT_AXIS (1 << 13) #define NDOF_PANZ_INVERT_AXIS (1 << 14) +#define NDOF_TURNTABLE (1 << 15) /* compute_device_type */ #define USER_COMPUTE_DEVICE_NONE 0 diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index e3cd236a8e3..7cebbe5a895 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -3358,7 +3358,11 @@ static void rna_def_userdef_input(BlenderRNA *brna) /* global options */ prop = RNA_def_property(srna, "ndof_sensitivity", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.25f, 4.0f); - RNA_def_property_ui_text(prop, "Sensitivity", "Overall sensitivity of the 3D Mouse"); + RNA_def_property_ui_text(prop, "Sensitivity", "Overall sensitivity of the 3D Mouse for panning"); + + prop = RNA_def_property(srna, "ndof_orbit_sensitivity", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.25f, 4.0f); + RNA_def_property_ui_text(prop, "Orbit Sensitivity", "Overall sensitivity of the 3D Mouse for orbiting"); prop = RNA_def_property(srna, "ndof_zoom_updown", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_ZOOM_UPDOWN); @@ -3375,6 +3379,11 @@ static void rna_def_userdef_input(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Show Navigation Guide", "Display the center and axis during rotation"); /* TODO: update description when fly-mode visuals are in place ("projected position in fly mode")*/ + /* 3D view */ + prop = RNA_def_property(srna, "ndof_turntable", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_TURNTABLE); + RNA_def_property_ui_text(prop, "Turntable", "Turntable for ndof rotation"); + /* 3D view: roll */ prop = RNA_def_property(srna, "ndof_roll_invert_axis", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_ROLL_INVERT_AXIS); diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 10a383df5c9..577a472b40d 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -2617,12 +2617,13 @@ static void attach_ndof_data(wmEvent *event, const GHOST_TEventNDOFMotionData *g wmNDOFMotionData *data = MEM_mallocN(sizeof(wmNDOFMotionData), "customdata NDOF"); const float s = U.ndof_sensitivity; + const float rs = U.ndof_orbit_sensitivity; data->tx = s * ghost->tx; - data->rx = s * ghost->rx; - data->ry = s * ghost->ry; - data->rz = s * ghost->rz; + data->rx = rs * ghost->rx; + data->ry = rs * ghost->ry; + data->rz = rs * ghost->rz; if (U.ndof_flag & NDOF_ZOOM_UPDOWN) { /* rotate so Y is where Z was */ |