[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