[Bf-blender-cvs] [498804edc88] xr-actions-D9124: XR: Implement raycast select operator

Peter Kim noreply at git.blender.org
Sun Nov 1 16:09:52 CET 2020


Commit: 498804edc88af5435f8f85740bf82573275fddc7
Author: Peter Kim
Date:   Sun Nov 1 23:50:46 2020 +0900
Branches: xr-actions-D9124
https://developer.blender.org/rB498804edc88af5435f8f85740bf82573275fddc7

XR: Implement raycast select operator

Uses the same raycast method as Scene.ray_cast() and works in object
and edit mode. Although it gives users an alternative to the existing
projection-based VR selection method, it is limited to objects with
real geometry (i.e. meshes).

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

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/intern/wm_event_system.c
M	source/blender/windowmanager/xr/intern/wm_xr_operators.c
M	source/blender/windowmanager/xr/intern/wm_xr_session.c

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

diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index d3eb6c00f57..5ca7bfd7379 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -556,6 +556,7 @@ void ED_view3d_viewcontext_init(struct bContext *C,
 void ED_view3d_viewcontext_init_object(struct ViewContext *vc, struct Object *obact);
 void view3d_operator_needs_opengl(const struct bContext *C);
 void view3d_region_operator_needs_opengl(struct wmWindow *win, struct ARegion *region);
+bool object_deselect_all_except(struct ViewLayer *view_layer, struct Base *b);
 
 /* XXX should move to BLI_math */
 bool edge_inside_circle(const float cent[2],
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 35ac43a3062..82c9a8523b3 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -168,7 +168,7 @@ static bool object_deselect_all_visible(ViewLayer *view_layer, View3D *v3d)
 }
 
 /* deselect all except b */
-static bool object_deselect_all_except(ViewLayer *view_layer, Base *b)
+bool object_deselect_all_except(ViewLayer *view_layer, Base *b)
 {
   bool changed = false;
   LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
diff --git a/source/blender/windowmanager/CMakeLists.txt b/source/blender/windowmanager/CMakeLists.txt
index dea181aa0fb..927f119fdec 100644
--- a/source/blender/windowmanager/CMakeLists.txt
+++ b/source/blender/windowmanager/CMakeLists.txt
@@ -27,6 +27,7 @@ set(INC
   ../blenlib
   ../blenloader
   ../blentranslation
+  ../bmesh
   ../compositor
   ../depsgraph
   ../editors/include
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index a96fcb9bc13..f111f0234eb 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -3249,7 +3249,7 @@ static void wm_event_do_surface_handlers(bContext *C, wmSurface *surface)
           PointerRNA properties = {.type = action_data->ot->srna,
                                    .data = action_data->op_properties};
 
-          if (action_data->ot->invoke) {
+          if (action_data->ot->invoke || action_data->ot->invoke_3d) {
             /* Invoke operator, either executing operator or transferring responsibility to window
              * modal handlers. */
             wm_operator_invoke(C,
@@ -4885,7 +4885,7 @@ void wm_event_add_xrevent(const char *action_set_name,
   BLI_assert(val == KM_PRESS || val == KM_RELEASE);
 
   wmXrSurfaceData *surface_data = surface->customdata;
-  const bool add_win_event = (action->ot->modal &&
+  const bool add_win_event = ((action->ot->modal || action->ot->modal_3d) &&
                               ((val == KM_PRESS && !press_start) || val == KM_RELEASE));
 
   wmEvent _event;
diff --git a/source/blender/windowmanager/xr/intern/wm_xr_operators.c b/source/blender/windowmanager/xr/intern/wm_xr_operators.c
index eb8cfe02031..12bdbd6719a 100644
--- a/source/blender/windowmanager/xr/intern/wm_xr_operators.c
+++ b/source/blender/windowmanager/xr/intern/wm_xr_operators.c
@@ -22,22 +22,57 @@
  * Collection of XR-related operators.
  */
 
+#include "BLI_kdopbvh.h"
 #include "BLI_listbase.h"
+#include "BLI_math.h"
 
 #include "BKE_context.h"
+#include "BKE_editmesh.h"
 #include "BKE_global.h"
+#include "BKE_layer.h"
 #include "BKE_main.h"
+#include "BKE_object.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"
 
 #include "GHOST_Types.h"
 
+#include "GPU_immediate.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
 #include "WM_api.h"
 #include "WM_types.h"
 
 #include "wm_xr_intern.h"
 
+/* -------------------------------------------------------------------- */
+/** \name Operator Callbacks
+ * \{ */
+
+/* op->poll */
+static bool wm_xr_operator_sessionactive(bContext *C)
+{
+  wmWindowManager *wm = CTX_wm_manager(C);
+  if (WM_xr_session_is_ready(&wm->xr)) {
+    return true;
+  }
+  return false;
+}
+
 /* -------------------------------------------------------------------- */
 /** \name XR Session Toggle
  *
@@ -123,6 +158,454 @@ static void WM_OT_xr_session_toggle(wmOperatorType *ot)
 
 /** \} */
 
+/* -------------------------------------------------------------------- */
+/** \name XR Raycast Select Operator
+ *
+ * Casts a ray from an XR controller's pose and selects any hit geometry.
+ * \{ */
+
+typedef struct XrRaycastSelectData {
+  float origin[3];
+  float direction[3];
+  float end[3];
+  void *draw_handle;
+} XrRaycastSelectData;
+
+void wm_xr_select_raycast_draw(const bContext *UNUSED(C),
+                               ARegion *UNUSED(region),
+                               void *customdata)
+{
+  const XrRaycastSelectData *data = customdata;
+
+  const eGPUDepthTest depth_test_prev = GPU_depth_test_get();
+  GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
+
+  GPUVertFormat *format = immVertexFormat();
+  uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+  GPU_line_width(2.0f);
+
+  immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+
+  immBegin(GPU_PRIM_LINES, 2);
+  immUniformColor4f(0.35f, 0.35f, 1.0f, 1.0f);
+  immVertex3fv(pos, data->origin);
+  immVertex3fv(pos, data->end);
+  immEnd();
+
+  immUnbindProgram();
+
+  GPU_depth_test(depth_test_prev);
+}
+
+static void wm_xr_select_raycast_init(bContext *C, wmOperator *op)
+{
+  BLI_assert(op->customdata == NULL);
+
+  op->customdata = MEM_callocN(sizeof(XrRaycastSelectData), __func__);
+
+  ARegionType *art = WM_xr_surface_region_type_get();
+  if (art) {
+    ((XrRaycastSelectData *)op->customdata)->draw_handle = ED_region_draw_cb_activate(
+        art, wm_xr_select_raycast_draw, op->customdata, REGION_DRAW_POST_VIEW);
+  }
+}
+
+static void wm_xr_select_raycast_uninit(bContext *C, wmOperator *op)
+{
+  if (op->customdata) {
+    ARegionType *art = WM_xr_surface_region_type_get();
+    if (art) {
+      ED_region_draw_cb_exit(art, ((XrRaycastSelectData *)op->customdata)->draw_handle);
+    }
+
+    MEM_freeN(op->customdata);
+  }
+}
+
+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;
+          }
+          default: {
+            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;
+          }
+        }
+      }
+      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,
+                                 eSelectOp select_op,
+                                 bool deselect_all)
+{
+  /* Uses same raycast method as Scene.ray_cast(). */
+  Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+  ViewContext vc;
+  ED_view3d_viewcontext_init(C, &vc, depsgraph);
+
+  float location[3];
+  float normal[3];
+  int index;
+  Object *ob = NULL;
+  float obmat[4][4];
+
+  SnapObjectContext *sctx = ED_transform_snap_object_context_create(vc.scene, 0);
+
+  ED_transform_snap_object_project_ray_ex(sctx,
+                                          depsgraph,
+                                          &(const struct SnapObjectParams){
+                                              .snap_select = SNAP_ALL,
+                                          },
+                                          origin,
+                                          direction,
+                                          ray_dist,
+                                          location,
+                   

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list