[Bf-blender-cvs] [b4f3d7fdb1e] xr-dev: XR: Add raycast select operator

Peter Kim noreply at git.blender.org
Tue Feb 22 09:48:25 CET 2022


Commit: b4f3d7fdb1e7a29506f5d6348c629d5e9e7e2ed1
Author: Peter Kim
Date:   Tue Feb 22 16:08:09 2022 +0900
Branches: xr-dev
https://developer.blender.org/rBb4f3d7fdb1e7a29506f5d6348c629d5e9e7e2ed1

XR: Add raycast select operator

>From xr-controller-support branch.

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

M	source/blender/editors/include/ED_view3d.h
M	source/blender/editors/space_view3d/view3d_select.c
M	source/blender/windowmanager/CMakeLists.txt
M	source/blender/windowmanager/xr/intern/wm_xr_operators.c

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

diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index 18b63403fcb..01526d06a80 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -928,6 +928,10 @@ void ED_view3d_viewcontext_init(struct bContext *C,
                                 struct ViewContext *vc,
                                 struct Depsgraph *depsgraph);
 void ED_view3d_viewcontext_init_object(struct ViewContext *vc, struct Object *obact);
+/**
+ * Deselect all except b.
+ */
+bool ED_view3d_object_deselect_all_except(struct ViewLayer *view_layer, struct Base *b);
 /**
  * Use this call when executing an operator,
  * event system doesn't set for each event the OpenGL drawing context.
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index e380a08dcc7..1dec6373ed3 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -134,18 +134,12 @@ void ED_view3d_viewcontext_init_object(ViewContext *vc, Object *obact)
   }
 }
 
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Internal Object Utilities
- * \{ */
-
-static bool object_deselect_all_visible(ViewLayer *view_layer, View3D *v3d)
+bool ED_view3d_object_deselect_all_except(ViewLayer *view_layer, Base *b)
 {
   bool changed = false;
   LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
     if (base->flag & BASE_SELECTED) {
-      if (BASE_SELECTABLE(v3d, base)) {
+      if (b != base) {
         ED_object_base_select(base, BA_DESELECT);
         changed = true;
       }
@@ -154,13 +148,18 @@ static bool object_deselect_all_visible(ViewLayer *view_layer, View3D *v3d)
   return changed;
 }
 
-/* deselect all except b */
-static bool object_deselect_all_except(ViewLayer *view_layer, Base *b)
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Internal Object Utilities
+ * \{ */
+
+static bool object_deselect_all_visible(ViewLayer *view_layer, View3D *v3d)
 {
   bool changed = false;
   LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
     if (base->flag & BASE_SELECTED) {
-      if (b != base) {
+      if (BASE_SELECTABLE(v3d, base)) {
         ED_object_base_select(base, BA_DESELECT);
         changed = true;
       }
@@ -1494,7 +1493,7 @@ static int object_select_menu_exec(bContext *C, wmOperator *op)
     }
   }
   else {
-    object_deselect_all_except(view_layer, basact);
+    ED_view3d_object_deselect_all_except(view_layer, basact);
     ED_object_base_select(basact, BA_SELECT);
     changed = true;
   }
@@ -2508,7 +2507,7 @@ static bool ed_object_select_pick(bContext *C,
 
     if (vc.obedit) {
       /* only do select */
-      object_deselect_all_except(view_layer, basact);
+      ED_view3d_object_deselect_all_except(view_layer, basact);
       ED_object_base_select(basact, BA_SELECT);
     }
     /* also prevent making it active on mouse selection */
@@ -2534,7 +2533,7 @@ static bool ed_object_select_pick(bContext *C,
       else {
         /* When enabled, this puts other objects out of multi pose-mode. */
         if (is_pose_mode == false || (basact->object->mode & OB_MODE_POSE) == 0) {
-          object_deselect_all_except(view_layer, basact);
+          ED_view3d_object_deselect_all_except(view_layer, basact);
           ED_object_base_select(basact, BA_SELECT);
         }
       }
diff --git a/source/blender/windowmanager/CMakeLists.txt b/source/blender/windowmanager/CMakeLists.txt
index 7cc36d66928..79d59d7e3c4 100644
--- a/source/blender/windowmanager/CMakeLists.txt
+++ b/source/blender/windowmanager/CMakeLists.txt
@@ -174,6 +174,8 @@ if(WITH_XR_OPENXR)
 
   list(APPEND INC
     xr
+    # For wm_xr_operators.c: BKE_editmesh.h
+    ../bmesh
   )
 
   list(APPEND SRC
diff --git a/source/blender/windowmanager/xr/intern/wm_xr_operators.c b/source/blender/windowmanager/xr/intern/wm_xr_operators.c
index 54800a5cd35..d32b011ff5f 100644
--- a/source/blender/windowmanager/xr/intern/wm_xr_operators.c
+++ b/source/blender/windowmanager/xr/intern/wm_xr_operators.c
@@ -13,14 +13,20 @@
 #include "BLI_math.h"
 
 #include "BKE_context.h"
+#include "BKE_editmesh.h"
 #include "BKE_global.h"
 #include "BKE_idprop.h"
+#include "BKE_layer.h"
 #include "BKE_main.h"
 #include "BKE_screen.h"
 
 #include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
 
+#include "ED_mesh.h"
+#include "ED_object.h"
 #include "ED_screen.h"
+#include "ED_select_utils.h"
 #include "ED_space_api.h"
 #include "ED_transform_snap_object_context.h"
 #include "ED_view3d.h"
@@ -714,10 +720,10 @@ static void wm_xr_raycast_update(wmOperator *op,
 
 static void wm_xr_raycast(Scene *scene,
                           Depsgraph *depsgraph,
+                          eSnapSelect snap_select,
                           const float origin[3],
                           const float direction[3],
                           float *ray_dist,
-                          bool selectable_only,
                           float r_location[3],
                           float r_normal[3],
                           int *r_index,
@@ -731,8 +737,7 @@ static void wm_xr_raycast(Scene *scene,
       sctx,
       depsgraph,
       NULL,
-      &(const struct SnapObjectParams){
-          .snap_select = (selectable_only ? SNAP_SELECTABLE : SNAP_ALL)},
+      &(const struct SnapObjectParams){.snap_select = snap_select},
       origin,
       direction,
       ray_dist,
@@ -1224,10 +1229,10 @@ static void wm_xr_navigation_teleport(bContext *C,
 
   wm_xr_raycast(scene,
                 depsgraph,
+                selectable_only ? SNAP_SELECTABLE : SNAP_ALL,
                 origin,
                 direction,
                 ray_dist,
-                selectable_only,
                 location,
                 normal,
                 &index,
@@ -1276,7 +1281,7 @@ static int wm_xr_navigation_teleport_invoke(bContext *C, wmOperator *op, const w
 
   wm_xr_raycast_init(op);
 
-  int retval = op->type->modal(C, op, event);
+  const int retval = op->type->modal(C, op, event);
 
   if ((retval & OPERATOR_RUNNING_MODAL) != 0) {
     WM_event_add_modal_handler(C, op);
@@ -1507,6 +1512,397 @@ static void WM_OT_xr_navigation_reset(wmOperatorType *ot)
 
 /** \} */
 
+/* -------------------------------------------------------------------- */
+/** \name XR Raycast Select
+ *
+ * Casts a ray from an XR controller's pose and selects any hit geometry.
+ * \{ */
+
+typedef enum eXrSelectElem {
+  XR_SEL_BASE = 0,
+  XR_SEL_VERTEX = 1,
+  XR_SEL_EDGE = 2,
+  XR_SEL_FACE = 3,
+} eXrSelectElem;
+
+static void wm_xr_select_op_apply(void *elem,
+                                  BMesh *bm,
+                                  eXrSelectElem select_elem,
+                                  eSelectOp select_op,
+                                  bool *r_changed,
+                                  bool *r_set)
+{
+  const bool selected_prev = (select_elem == XR_SEL_BASE) ?
+                                 (((Base *)elem)->flag & BASE_SELECTED) != 0 :
+                                 (((BMElem *)elem)->head.hflag & BM_ELEM_SELECT) != 0;
+
+  if (selected_prev) {
+    switch (select_op) {
+      case SEL_OP_SUB:
+      case SEL_OP_XOR: {
+        switch (select_elem) {
+          case XR_SEL_BASE:
+            ED_object_base_select((Base *)elem, BA_DESELECT);
+            *r_changed = true;
+            break;
+          case XR_SEL_VERTEX:
+            BM_vert_select_set(bm, (BMVert *)elem, false);
+            *r_changed = true;
+            break;
+          case XR_SEL_EDGE:
+            BM_edge_select_set(bm, (BMEdge *)elem, false);
+            *r_changed = true;
+            break;
+          case XR_SEL_FACE:
+            BM_face_select_set(bm, (BMFace *)elem, false);
+            *r_changed = true;
+            break;
+        }
+        break;
+      }
+      default: {
+        break;
+      }
+    }
+  }
+  else {
+    switch (select_op) {
+      case SEL_OP_SET:
+      case SEL_OP_ADD:
+      case SEL_OP_XOR: {
+        switch (select_elem) {
+          case XR_SEL_BASE:
+            ED_object_base_select((Base *)elem, BA_SELECT);
+            *r_changed = true;
+            break;
+          case XR_SEL_VERTEX:
+            BM_vert_select_set(bm, (BMVert *)elem, true);
+            *r_changed = true;
+            break;
+          case XR_SEL_EDGE:
+            BM_edge_select_set(bm, (BMEdge *)elem, true);
+            *r_changed = true;
+            break;
+          case XR_SEL_FACE:
+            BM_face_select_set(bm, (BMFace *)elem, true);
+            *r_changed = true;
+            break;
+        }
+      }
+      default: {
+        break;
+      }
+    }
+
+    if (select_op == SEL_OP_SET) {
+      *r_set = true;
+    }
+  }
+}
+
+static bool wm_xr_select_raycast(bContext *C,
+                                 const float origin[3],
+                                 const float direction[3],
+                                 float *ray_dist,
+                                 bool selectable_only,
+                                 eSelectOp select_op,
+                                 bool deselect_all)
+{
+  Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+  ViewContext vc;
+  ED_view3d_viewcontext_init(C, &vc, depsgraph);
+  vc.em = (vc.obedit && (vc.obedit->type == OB_MESH)) ? BKE_editmesh_from_object(vc.obedit) : NULL;
+
+  float location[3];
+  float normal[3];
+  int index;
+  Object *ob = NULL;
+  float obmat[4][4];
+
+  wm_xr_raycast(vc.scene,
+                depsgraph,
+                vc.em ? SNAP_ONLY_ACTIVE : (selectable_only ? SNAP_SELECTABLE : SNAP_ALL),
+                origin,
+                direction,
+                ray_dist,
+                location,
+                normal,
+                &index,
+                &ob,
+                obmat);
+
+  /* Select. */
+  bool hit = false;
+  bool changed = false;
+
+  if (ob && vc.em &&
+      ((ob == vc.obedit) || (ob->id.orig_id == &vc.obedit->id))) { /* TODO_XR: Non-mesh objects. */
+    BMesh *bm = vc.em->bm;
+    BMFace *f = NULL;
+    BMEdge *e 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list