Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2014-02-20 03:00:16 +0400
committerCampbell Barton <ideasman42@gmail.com>2014-02-20 05:02:59 +0400
commitea58918171e7135e146e6bb90d988908d7c1540f (patch)
treee87ce0f4ddcedee7e4354c2335eb9a08bf1fab39
parent5fb72b7ee55358f92fe965e5dae5de971c62bff8 (diff)
NDOF: define 2 default navigation modes: free & orbit
After some discussion it seems both are valid defaults but useful for very different purposes. - 'free' lets you explore the scene with full 6dof (like fly mode) - 'orbit' is closer to typical mouse view orbit, constraining to orbiting about a central location. This doesn't effect orbit/pan which are available with modifier keys.
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py12
-rw-r--r--source/blender/editors/include/ED_view3d.h1
-rw-r--r--source/blender/editors/space_view3d/view3d_camera_control.c16
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c81
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h9
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c15
6 files changed, 94 insertions, 40 deletions
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index 57485604cdc..b44b45e118d 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -950,18 +950,22 @@ class USERPREF_MT_ndof_settings(Menu):
input_prefs = context.user_preferences.inputs
- layout.prop(input_prefs, "ndof_sensitivity")
- layout.prop(input_prefs, "ndof_orbit_sensitivity")
-
is_view3d = context.space_data.type == 'VIEW_3D'
+ layout.prop(input_prefs, "ndof_sensitivity")
+ if is_view3d:
+ layout.prop(input_prefs, "ndof_orbit_sensitivity")
+
if is_view3d:
layout.separator()
layout.prop(input_prefs, "ndof_show_guide")
layout.separator()
- layout.label(text="Orbit options")
+ layout.label(text="Orbit style")
+ layout.row().prop(input_prefs, "ndof_view_navigate_method", text="")
layout.row().prop(input_prefs, "ndof_view_rotate_method", text="")
+ layout.separator()
+ layout.label(text="Orbit options")
layout.prop(input_prefs, "ndof_rotx_invert_axis")
layout.prop(input_prefs, "ndof_roty_invert_axis")
layout.prop(input_prefs, "ndof_rotz_invert_axis")
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index 8fce5e7e7c0..a42b352ad51 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -335,6 +335,7 @@ void ED_view3D_background_image_clear(struct View3D *v3d);
#define VIEW3D_MARGIN 1.4f
#define VIEW3D_DIST_FALLBACK 1.0f
float ED_view3d_offset_distance(float mat[4][4], const float ofs[3], const float dist_fallback);
+void ED_view3d_distance_set(struct RegionView3D *rv3d, const float dist);
float ED_scene_grid_scale(struct Scene *scene, const char **grid_unit);
float ED_view3d_grid_scale(struct Scene *scene, struct View3D *v3d, const char **grid_unit);
diff --git a/source/blender/editors/space_view3d/view3d_camera_control.c b/source/blender/editors/space_view3d/view3d_camera_control.c
index 2797125485c..230df49f386 100644
--- a/source/blender/editors/space_view3d/view3d_camera_control.c
+++ b/source/blender/editors/space_view3d/view3d_camera_control.c
@@ -185,7 +185,6 @@ struct View3DCameraControl *ED_view3d_cameracontrol_aquire(
rv3d->dist = 0.0;
}
else {
- float tvec[3];
/* perspective or ortho */
if (rv3d->persp == RV3D_ORTHO)
rv3d->persp = RV3D_PERSP; /* if ortho projection, make perspective */
@@ -200,11 +199,7 @@ struct View3DCameraControl *ED_view3d_cameracontrol_aquire(
* but to correct the dist removal we must
* alter offset so the view doesn't jump. */
- rv3d->dist = 0.0f;
-
- copy_v3_fl3(tvec, 0.0f, 0.0f, vctrl->dist_backup);
- mul_mat3_m4_v3(rv3d->viewinv, tvec);
- sub_v3_v3(rv3d->ofs, tvec);
+ ED_view3d_distance_set(rv3d, 0.0f);
/* Done with correcting for the dist */
}
@@ -316,7 +311,6 @@ void ED_view3d_cameracontrol_release(
View3D *v3d = vctrl->ctx_v3d;
RegionView3D *rv3d = vctrl->ctx_rv3d;
- rv3d->dist = vctrl->dist_backup;
if (restore) {
/* Revert to original view? */
if (vctrl->persp_backup == RV3D_CAMOB) { /* a camera view */
@@ -334,21 +328,19 @@ void ED_view3d_cameracontrol_release(
}
/* always, is set to zero otherwise */
copy_v3_v3(rv3d->ofs, vctrl->ofs_backup);
+ rv3d->dist = vctrl->dist_backup;
}
else if (vctrl->persp_backup == RV3D_CAMOB) { /* camera */
DAG_id_tag_update((ID *)view3d_cameracontrol_object(vctrl), OB_RECALC_OB);
/* always, is set to zero otherwise */
copy_v3_v3(rv3d->ofs, vctrl->ofs_backup);
+ rv3d->dist = vctrl->dist_backup;
}
else { /* not camera */
- float tvec[3];
-
/* Apply the fly mode view */
/* restore the dist */
- copy_v3_fl3(tvec, 0.0f, 0.0f, vctrl->dist_backup);
- mul_mat3_m4_v3(rv3d->viewinv, tvec);
- add_v3_v3(rv3d->ofs, tvec);
+ ED_view3d_distance_set(rv3d, vctrl->dist_backup);
/* Done with correcting for the dist */
}
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 03c0063babe..faee6514616 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -1219,15 +1219,18 @@ static void view3d_ndof_pan_zoom(const struct wmNDOFMotionData *ndof, ScrArea *s
}
-static void view3d_ndof_orbit(const struct wmNDOFMotionData *ndof, RegionView3D *rv3d, const float dt,
+static void view3d_ndof_orbit(const struct wmNDOFMotionData *ndof, ScrArea *sa, ARegion *ar,
/* optional, can be NULL*/
ViewOpsData *vod)
{
+ View3D *v3d = sa->spacedata.first;
+ RegionView3D *rv3d = ar->regiondata;
+
float view_inv[4];
BLI_assert((rv3d->viewlock & RV3D_LOCKED) == 0);
- view3d_ensure_persp(vod->v3d, vod->ar);
+ view3d_ensure_persp(v3d, ar);
rv3d->view = RV3D_VIEW_USER;
@@ -1247,13 +1250,13 @@ static void view3d_ndof_orbit(const struct wmNDOFMotionData *ndof, RegionView3D
mul_qt_v3(view_inv, xvec);
/* Perform the up/down rotation */
- angle = dt * rot[0];
+ angle = ndof->dt * rot[0];
quat[0] = cosf(angle);
mul_v3_v3fl(quat + 1, xvec, sin(angle));
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, quat);
/* Perform the orbital rotation */
- angle = dt * rot[1];
+ angle = ndof->dt * rot[1];
/* update the onscreen doo-dad */
rv3d->rot_angle = angle;
@@ -1432,7 +1435,7 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *op, const wmEvent *event)
View3D *v3d;
RegionView3D *rv3d;
- wmNDOFMotionData *ndof = (wmNDOFMotionData *) event->customdata;
+ const wmNDOFMotionData *ndof = event->customdata;
viewops_data_alloc(C, op);
viewops_data_create(C, op, event);
@@ -1457,7 +1460,7 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *op, const wmEvent *event)
}
if (has_rotation) {
- view3d_ndof_orbit(ndof, rv3d, ndof->dt, vod);
+ view3d_ndof_orbit(ndof, vod->sa, vod->ar, vod);
}
}
@@ -1497,7 +1500,7 @@ static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *ev
View3D *v3d;
RegionView3D *rv3d;
- wmNDOFMotionData *ndof = (wmNDOFMotionData *) event->customdata;
+ const wmNDOFMotionData *ndof = event->customdata;
viewops_data_alloc(C, op);
viewops_data_create(C, op, event);
@@ -1511,21 +1514,49 @@ static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *ev
ED_view3d_camera_lock_init(v3d, rv3d);
- if (ndof->progress != P_FINISHING) {
- const bool has_rotation = NDOF_HAS_ROTATE && (RV3D_VIEW_IS_AXIS(rv3d->view) == false);
+ if (ndof->progress == P_FINISHING) {
+ /* pass */
+ }
+ else if (RV3D_VIEW_IS_AXIS(rv3d->view)) {
/* if we can't rotate, fallback to translate (locked axis views) */
const bool has_translate = NDOF_HAS_TRANSLATE;
- /* always zoom since this is the main purpose of the function */
- const bool has_zoom = true;
- if (has_translate || has_zoom) {
+ if (has_translate) {
view3d_ndof_pan_zoom(ndof, vod->sa, vod->ar, has_translate, true);
}
+ }
+ else if (U.ndof_flag & NDOF_MODE_ORBIT) {
+ const bool has_rotation = NDOF_HAS_ROTATE;
+ const bool has_zoom = (ndof->tvec[2] != 0.0f);
+
+ if (has_zoom) {
+ view3d_ndof_pan_zoom(ndof, vod->sa, vod->ar, false, has_zoom);
+ }
if (has_rotation) {
- view3d_ndof_orbit(ndof, rv3d, ndof->dt, vod);
+ view3d_ndof_orbit(ndof, vod->sa, vod->ar, vod);
}
}
+ else { /* free/explore (like fly mode) */
+ Scene *scene = CTX_data_scene(C);
+ const bool has_rotation = NDOF_HAS_ROTATE;
+ const bool has_translate = NDOF_HAS_TRANSLATE;
+
+ const float dist_backup = rv3d->dist;
+
+ if (has_translate) {
+ view3d_ndof_pan_zoom(ndof, vod->sa, vod->ar, true, false);
+ }
+
+ ED_view3d_distance_set(rv3d, 0.0f);
+
+ if (has_rotation) {
+ view3d_ndof_orbit(ndof, vod->sa, vod->ar, NULL);
+ }
+
+ ED_view3d_update_viewmat(scene, v3d, vod->ar, NULL, NULL);
+ ED_view3d_distance_set(rv3d, dist_backup);
+ }
ED_view3d_camera_lock_sync(v3d, rv3d);
@@ -1563,7 +1594,7 @@ static int ndof_pan_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *e
else {
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
- wmNDOFMotionData *ndof = (wmNDOFMotionData *) event->customdata;
+ const wmNDOFMotionData *ndof = event->customdata;
const bool has_translate = NDOF_HAS_TRANSLATE;
const bool has_zoom = !rv3d->is_persp;
@@ -1622,7 +1653,7 @@ static int ndof_all_invoke(bContext *C, wmOperator *op, const wmEvent *event)
View3D *v3d;
RegionView3D *rv3d;
- wmNDOFMotionData *ndof = (wmNDOFMotionData *) event->customdata;
+ const wmNDOFMotionData *ndof = event->customdata;
viewops_data_alloc(C, op);
viewops_data_create(C, op, event);
@@ -1646,7 +1677,7 @@ static int ndof_all_invoke(bContext *C, wmOperator *op, const wmEvent *event)
}
if (has_rotation) {
- view3d_ndof_orbit(ndof, rv3d, ndof->dt, vod);
+ view3d_ndof_orbit(ndof, vod->sa, vod->ar, vod);
}
}
@@ -4562,6 +4593,24 @@ float ED_view3d_offset_distance(float mat[4][4], const float ofs[3], const float
}
/**
+ * Set the dist without moving the view (compensate with #RegionView3D.ofs)
+ *
+ * \note take care that viewinv is up to date, #ED_view3d_update_viewmat first.
+ */
+void ED_view3d_distance_set(RegionView3D *rv3d, const float dist)
+{
+ float tvec[3];
+
+ BLI_assert(dist >= 0.0f);
+
+ copy_v3_fl3(tvec, 0.0f, 0.0f, rv3d->dist - dist);
+ mul_mat3_m4_v3(rv3d->viewinv, tvec);
+ sub_v3_v3(rv3d->ofs, tvec);
+
+ rv3d->dist = dist;
+}
+
+/**
* Set the view transformation from a 4x4 matrix.
*
* \param mat The view 4x4 transformation matrix to assign.
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index 1705a0d16c5..4248efd0919 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -782,13 +782,10 @@ typedef enum eNdof_Flag {
NDOF_SHOULD_ZOOM = (1 << 4),
NDOF_SHOULD_ROTATE = (1 << 5),
- /* orbit navigation modes
- * only two options, so it's sort of a hybrid bool/enum
- * if ((U.ndof_flag & NDOF_ORBIT_MODE) == NDOF_OM_OBJECT)... */
+ /* orbit navigation modes */
- // NDOF_ORBIT_MODE = (1 << 6),
- // #define NDOF_OM_TARGETCAMERA 0
- // #define NDOF_OM_OBJECT NDOF_ORBIT_MODE
+ /* exposed as Orbit|Explore in the UI */
+ NDOF_MODE_ORBIT = (1 << 6),
/* actually... users probably don't care about what the mode
* is called, just that it feels right */
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 0910ee65d6b..cca619c1a55 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -3947,19 +3947,25 @@ static void rna_def_userdef_input(BlenderRNA *brna)
{0, "RIGHT", 0, "Right", "Use Right Mouse Button for selection"},
{0, NULL, 0, NULL, NULL}
};
-
+
static EnumPropertyItem view_rotation_items[] = {
{0, "TURNTABLE", 0, "Turntable", "Use turntable style rotation in the viewport"},
{USER_TRACKBALL, "TRACKBALL", 0, "Trackball", "Use trackball style rotation in the viewport"},
{0, NULL, 0, NULL, NULL}
};
+ static EnumPropertyItem ndof_view_navigation_items[] = {
+ {0, "FREE", 0, "Free", "Use full 6 degrees of freedom by default"},
+ {NDOF_MODE_ORBIT, "ORBIT", 0, "Orbit", "Orbit about the view center by default"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
static EnumPropertyItem ndof_view_rotation_items[] = {
{NDOF_TURNTABLE, "TURNTABLE", 0, "Turntable", "Use turntable style rotation in the viewport"},
{0, "TRACKBALL", 0, "Trackball", "Use trackball style rotation in the viewport"},
{0, NULL, 0, NULL, NULL}
};
-
+
static EnumPropertyItem view_zoom_styles[] = {
{USER_ZOOM_CONT, "CONTINUE", 0, "Continue", "Old style zoom, continues while moving mouse up or down"},
{USER_ZOOM_DOLLY, "DOLLY", 0, "Dolly", "Zoom in and out based on vertical mouse movement"},
@@ -4062,6 +4068,11 @@ static void rna_def_userdef_input(BlenderRNA *brna)
/* TODO: update description when fly-mode visuals are in place ("projected position in fly mode")*/
/* 3D view */
+ prop = RNA_def_property(srna, "ndof_view_navigate_method", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_bitflag_sdna(prop, NULL, "ndof_flag");
+ RNA_def_property_enum_items(prop, ndof_view_navigation_items);
+ RNA_def_property_ui_text(prop, "NDOF View Navigate", "Navigation style in the viewport");
+
prop = RNA_def_property(srna, "ndof_view_rotate_method", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "ndof_flag");
RNA_def_property_enum_items(prop, ndof_view_rotation_items);