[Bf-blender-cvs] [3434a991ec5] master: XR Controller Support Step 5: Navigation

Peter Kim noreply at git.blender.org
Tue Oct 26 06:36:09 CEST 2021


Commit: 3434a991ec5befef19c5484bfc70a3a333e42c34
Author: Peter Kim
Date:   Tue Oct 26 13:33:02 2021 +0900
Branches: master
https://developer.blender.org/rB3434a991ec5befef19c5484bfc70a3a333e42c34

XR Controller Support Step 5: Navigation

Adds navigation transforms (pose, scale) to the XR session state that
will be applied to the viewer/controller poses. By manipulating these
values, a viewer can move through the VR viewport without the need to
physically walk through it.

Add-ons can access these transforms via Python
(XrSessionState.navigation_location/rotation/scale) to use with custom
operators.

Also adds 3 new VR navigation operators that will be exposed to users
as default actions in the VR Scene Inspection add-on. While all three
of these operators have custom properties that can greatly influence
their behaviors, for now these properties will not be accessible by
users from the UI. However, other add-ons can still set these custom
properties if they desire.

1). Raycast-based teleport
Moves the user to a location pointed at on a mesh object. The result
can optionally be constrained to specific axes, for example to achieve
"elevation snapping" behavior by constraining to the Z-axis. In
addition, one can specify an interpolation factor and offset.

Credit to KISKA for the elevation snapping concept.

2). "Grab" navigation
Moves the user through the viewport by pressing inputs on one or two
held controllers and applying deltas to the navigation matrix based on
the displacement of these controllers. When inputs on both controllers
are pressed at the same time (bimanual interaction), the user can scale
themselves relative to the scene based on the distance between the
controllers.

Also supports locks for location, rotation, and scale.

3). Fly navigation
Navigates the viewport by pressing a button and moving/turning relative to
navigation space or the VR viewer or controller. Via the operator's
properties, one can select from a variety of these modes as well as
specify the min/max speed and whether to lock elevation.

Reviewed By: Severin

Differential Revision: https://developer.blender.org/D11501

===================================================================

M	source/blender/editors/include/ED_transform_snap_object_context.h
M	source/blender/editors/transform/transform_snap_object.c
M	source/blender/makesdna/DNA_xr_types.h
M	source/blender/makesrna/intern/rna_xr.c
M	source/blender/windowmanager/CMakeLists.txt
M	source/blender/windowmanager/WM_api.h
M	source/blender/windowmanager/intern/wm_operators.c
M	source/blender/windowmanager/xr/intern/wm_xr_draw.c
M	source/blender/windowmanager/xr/intern/wm_xr_intern.h
A	source/blender/windowmanager/xr/intern/wm_xr_operators.c
M	source/blender/windowmanager/xr/intern/wm_xr_session.c
M	source/blender/windowmanager/xr/wm_xr.h

===================================================================

diff --git a/source/blender/editors/include/ED_transform_snap_object_context.h b/source/blender/editors/include/ED_transform_snap_object_context.h
index 7002db163b6..62d1dfbf0b1 100644
--- a/source/blender/editors/include/ED_transform_snap_object_context.h
+++ b/source/blender/editors/include/ED_transform_snap_object_context.h
@@ -44,6 +44,7 @@ typedef enum {
   SNAP_NOT_SELECTED = 1,
   SNAP_NOT_ACTIVE = 2,
   SNAP_ONLY_ACTIVE = 3,
+  SNAP_SELECTABLE = 4,
 } eSnapSelect;
 
 typedef enum {
diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c
index f5f3fafe897..c779fbe4a33 100644
--- a/source/blender/editors/transform/transform_snap_object.c
+++ b/source/blender/editors/transform/transform_snap_object.c
@@ -493,6 +493,11 @@ static void iter_snap_objects(SnapObjectContext *sctx,
         continue;
       }
     }
+    else if (snap_select == SNAP_SELECTABLE) {
+      if (!(base->flag & BASE_SELECTABLE)) {
+        continue;
+      }
+    }
 
     Object *obj_eval = DEG_get_evaluated_object(sctx->runtime.depsgraph, base->object);
     if (obj_eval->transflag & OB_DUPLI || BKE_object_has_geometry_set_instances(obj_eval)) {
diff --git a/source/blender/makesdna/DNA_xr_types.h b/source/blender/makesdna/DNA_xr_types.h
index 6f4f7e3e8ae..f7da912f299 100644
--- a/source/blender/makesdna/DNA_xr_types.h
+++ b/source/blender/makesdna/DNA_xr_types.h
@@ -32,8 +32,8 @@ typedef struct XrSessionSettings {
   /** Shading settings, struct shared with 3D-View so settings are the same. */
   struct View3DShading shading;
 
-  char _pad[7];
-
+  float base_scale;
+  char _pad[3];
   char base_pose_type; /* #eXRSessionBasePoseType */
   /** Object to take the location and rotation as base position from. */
   Object *base_pose_object;
diff --git a/source/blender/makesrna/intern/rna_xr.c b/source/blender/makesrna/intern/rna_xr.c
index 3705284ca66..0f6544e6d47 100644
--- a/source/blender/makesrna/intern/rna_xr.c
+++ b/source/blender/makesrna/intern/rna_xr.c
@@ -892,6 +892,71 @@ static void rna_XrSessionState_viewer_pose_rotation_get(PointerRNA *ptr, float *
 #  endif
 }
 
+static void rna_XrSessionState_nav_location_get(PointerRNA *ptr, float *r_values)
+{
+#  ifdef WITH_XR_OPENXR
+  const wmXrData *xr = rna_XrSession_wm_xr_data_get(ptr);
+  WM_xr_session_state_nav_location_get(xr, r_values);
+#  else
+  UNUSED_VARS(ptr);
+  zero_v3(r_values);
+#  endif
+}
+
+static void rna_XrSessionState_nav_location_set(PointerRNA *ptr, const float *values)
+{
+#  ifdef WITH_XR_OPENXR
+  wmXrData *xr = rna_XrSession_wm_xr_data_get(ptr);
+  WM_xr_session_state_nav_location_set(xr, values);
+#  else
+  UNUSED_VARS(ptr, values);
+#  endif
+}
+
+static void rna_XrSessionState_nav_rotation_get(PointerRNA *ptr, float *r_values)
+{
+#  ifdef WITH_XR_OPENXR
+  const wmXrData *xr = rna_XrSession_wm_xr_data_get(ptr);
+  WM_xr_session_state_nav_rotation_get(xr, r_values);
+#  else
+  UNUSED_VARS(ptr);
+  unit_qt(r_values);
+#  endif
+}
+
+static void rna_XrSessionState_nav_rotation_set(PointerRNA *ptr, const float *values)
+{
+#  ifdef WITH_XR_OPENXR
+  wmXrData *xr = rna_XrSession_wm_xr_data_get(ptr);
+  WM_xr_session_state_nav_rotation_set(xr, values);
+#  else
+  UNUSED_VARS(ptr, values);
+#  endif
+}
+
+static float rna_XrSessionState_nav_scale_get(PointerRNA *ptr)
+{
+  float value;
+#  ifdef WITH_XR_OPENXR
+  const wmXrData *xr = rna_XrSession_wm_xr_data_get(ptr);
+  WM_xr_session_state_nav_scale_get(xr, &value);
+#  else
+  UNUSED_VARS(ptr);
+  value = 1.0f;
+#  endif
+  return value;
+}
+
+static void rna_XrSessionState_nav_scale_set(PointerRNA *ptr, float value)
+{
+#  ifdef WITH_XR_OPENXR
+  wmXrData *xr = rna_XrSession_wm_xr_data_get(ptr);
+  WM_xr_session_state_nav_scale_set(xr, value);
+#  else
+  UNUSED_VARS(ptr, value);
+#  endif
+}
+
 static void rna_XrSessionState_actionmaps_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
 {
 #  ifdef WITH_XR_OPENXR
@@ -1615,6 +1680,13 @@ static void rna_def_xr_session_settings(BlenderRNA *brna)
       "Rotation angle around the Z-Axis to apply the rotation deltas from the VR headset to");
   RNA_def_property_update(prop, NC_WM | ND_XR_DATA_CHANGED, NULL);
 
+  prop = RNA_def_property(srna, "base_scale", PROP_FLOAT, PROP_NONE);
+  RNA_def_property_ui_text(prop, "Base Scale", "Uniform scale to apply to VR view");
+  RNA_def_property_range(prop, 1e-6f, FLT_MAX);
+  RNA_def_property_ui_range(prop, 0.001f, FLT_MAX, 10, 3);
+  RNA_def_property_float_default(prop, 1.0f);
+  RNA_def_property_update(prop, NC_WM | ND_XR_DATA_CHANGED, NULL);
+
   prop = RNA_def_property(srna, "show_floor", PROP_BOOLEAN, PROP_NONE);
   RNA_def_property_boolean_sdna(prop, NULL, "draw_flags", V3D_OFSDRAW_SHOW_GRIDFLOOR);
   RNA_def_property_ui_text(prop, "Display Grid Floor", "Show the ground plane grid");
@@ -1981,6 +2053,32 @@ static void rna_def_xr_session_state(BlenderRNA *brna)
       "Viewer Pose Rotation",
       "Last known rotation of the viewer pose (center between the eyes) in world space");
 
+  prop = RNA_def_property(srna, "navigation_location", PROP_FLOAT, PROP_TRANSLATION);
+  RNA_def_property_array(prop, 3);
+  RNA_def_property_float_funcs(
+      prop, "rna_XrSessionState_nav_location_get", "rna_XrSessionState_nav_location_set", NULL);
+  RNA_def_property_ui_text(
+      prop,
+      "Navigation Location",
+      "Location offset to apply to base pose when determining viewer location");
+
+  prop = RNA_def_property(srna, "navigation_rotation", PROP_FLOAT, PROP_QUATERNION);
+  RNA_def_property_array(prop, 4);
+  RNA_def_property_float_funcs(
+      prop, "rna_XrSessionState_nav_rotation_get", "rna_XrSessionState_nav_rotation_set", NULL);
+  RNA_def_property_ui_text(
+      prop,
+      "Navigation Rotation",
+      "Rotation offset to apply to base pose when determining viewer rotation");
+
+  prop = RNA_def_property(srna, "navigation_scale", PROP_FLOAT, PROP_NONE);
+  RNA_def_property_float_funcs(
+      prop, "rna_XrSessionState_nav_scale_get", "rna_XrSessionState_nav_scale_set", NULL);
+  RNA_def_property_ui_text(
+      prop,
+      "Navigation Scale",
+      "Additional scale multiplier to apply to base scale when determining viewer scale");
+
   prop = RNA_def_property(srna, "actionmaps", PROP_COLLECTION, PROP_NONE);
   RNA_def_property_collection_funcs(prop,
                                     "rna_XrSessionState_actionmaps_begin",
diff --git a/source/blender/windowmanager/CMakeLists.txt b/source/blender/windowmanager/CMakeLists.txt
index 4d65726fe2b..03b2fb49085 100644
--- a/source/blender/windowmanager/CMakeLists.txt
+++ b/source/blender/windowmanager/CMakeLists.txt
@@ -202,6 +202,7 @@ if(WITH_XR_OPENXR)
     xr/intern/wm_xr_action.c
     xr/intern/wm_xr_actionmap.c
     xr/intern/wm_xr_draw.c
+    xr/intern/wm_xr_operators.c
     xr/intern/wm_xr_session.c
 
     xr/wm_xr.h
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 2988aacc4d3..2d5100eec7c 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -1027,6 +1027,13 @@ bool WM_xr_session_state_controller_aim_location_get(const wmXrData *xr,
 bool WM_xr_session_state_controller_aim_rotation_get(const wmXrData *xr,
                                                      unsigned int subaction_idx,
                                                      float r_rotation[4]);
+bool WM_xr_session_state_nav_location_get(const wmXrData *xr, float r_location[3]);
+void WM_xr_session_state_nav_location_set(wmXrData *xr, const float location[3]);
+bool WM_xr_session_state_nav_rotation_get(const wmXrData *xr, float r_rotation[4]);
+void WM_xr_session_state_nav_rotation_set(wmXrData *xr, const float rotation[4]);
+bool WM_xr_session_state_nav_scale_get(const wmXrData *xr, float *r_scale);
+void WM_xr_session_state_nav_scale_set(wmXrData *xr, float scale);
+void WM_xr_session_state_navigation_reset(struct wmXrSessionState *state);
 
 struct ARegionType *WM_xr_surface_controller_region_type_get(void);
 
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 89f0206d72e..1130ad9a558 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -3759,87 +3759,6 @@ static void WM_OT_stereo3d_set(wmOperatorType *ot)
 
 /** \} */
 
-#ifdef WITH_XR_OPENXR
-
-static void wm_xr_session_update_screen(Main *bmain, const wmXrData *xr_data)
-{
-  const bool session_exists = WM_xr_session_exists(xr_data);
-
-  for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
-    LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
-      LISTBASE_FOREACH (SpaceLink *, slink, &area->spacedata) {
-        if (slink->spacetype == SPACE_VIEW3D) {
-          View3D *v3d = (View3D *)slink;
-
-          if (v3d->flag & V3D_XR_SESSION_MIRROR) {
-            ED_view3d_xr_mirror_update(area, v3d, session_exists);
-          }
-
-          if (session_exists) {
-            wmWindowManager *wm = bmain->wm.first;
-            const Scene *scene = WM_windows_scene_get_from_screen(wm, screen);
-
-            ED_view3d_xr_shading_update(wm, v3d, scene);
-          }
-          /* Ensure no 3D View is tagged as session root. */
-          else {
-            v3d->runtime.flag &= ~V3D_RUNTIME_XR_SESSION_ROOT;
-          }
-        }
-      }
-    }
-  }
-
-  WM_main_add_notifier(NC_WM | ND_XR_DATA_CHANGED, NULL);
-}
-
-static void wm_xr_session_update_screen_on_exit_cb(const wmXrData *xr_data)
-{
-  /* Just use G_MAIN here, storing main isn't reliable enough on file read or exit. */
-  wm_xr_session_update_screen(G_MAIN, xr_data);
-}
-
-static int wm_xr_session_toggle_exec(bContext *C, wmOperator *UNUSED(op))
-{
-  Main *bmain = CTX_data_main(C);
-  wmWindowManager *wm = CTX_wm_manager(C);
-  wmWindow *win = CTX_wm_window(C);
-  View3D *v3d = CTX_wm_view3d(C);
-
-  /* Lazy-create xr context - tries to dynlink to the runtime, reading active_runtime.json. */
-  if (wm_xr_init(wm) == false) {
-    return OPERATOR_CANCELLED;
-  }
-
-  v3d->runtime.flag |= V3D_RUNTIME_XR_SESSION_ROOT;
-  wm_xr_session_toggle(wm, win, wm_xr_sessio

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list