[Bf-blender-cvs] [66e22a2ed78] xr-actions-D9124: Operators: Add modal_3d() and implement for box select
Peter Kim
noreply at git.blender.org
Wed Oct 14 17:44:21 CEST 2020
Commit: 66e22a2ed789c86a389f11fbd86bc388e58eccaf
Author: Peter Kim
Date: Thu Oct 15 00:41:34 2020 +0900
Branches: xr-actions-D9124
https://developer.blender.org/rB66e22a2ed789c86a389f11fbd86bc388e58eccaf
Operators: Add modal_3d() and implement for box select
This follows the same logic as invoke_3d(). That is, we wrap an
operator's modal() with modal_3d() and project 3D controller coords to
2D mouse coords.
===================================================================
M source/blender/editors/space_view3d/view3d_select.c
M source/blender/windowmanager/WM_api.h
M source/blender/windowmanager/intern/wm_event_system.c
M source/blender/windowmanager/intern/wm_gesture_ops.c
M source/blender/windowmanager/xr/intern/wm_xr_draw.c
===================================================================
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index e03609dab52..9c12a396ab9 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -2507,36 +2507,28 @@ static int view3d_select_invoke(bContext *C, wmOperator *op, const wmEvent *even
return view3d_select_exec(C, op);
}
-static void controller_loc_to_mval(const float loc[3],
- const float viewmat[4][4],
- const float winmat[4][4],
- short winx,
- short winy,
- int r_mval[2])
-{
- float persmat[4][4];
- float tmp[3];
-
- mul_m4_m4m4(persmat, winmat, viewmat);
- copy_v3_v3(tmp, loc);
- mul_project_m4_v3(persmat, tmp);
- r_mval[0] = (int)(((float)winx / 2.0f) * (1.0f + tmp[0]));
- r_mval[1] = (int)(((float)winy / 2.0f) * (1.0f + tmp[1]));
-}
-
static int view3d_select_invoke_3d(bContext *C, wmOperator *op, const wmEvent *event)
{
BLI_assert(event->type == EVT_XR_ACTION);
BLI_assert(event->custom == EVT_DATA_XR);
BLI_assert(event->customdata);
- ARegion *ar = CTX_wm_region(C);
- RegionView3D *rv3d = ar->regiondata;
+ ARegion *region = CTX_wm_region(C);
+ RegionView3D *rv3d = region->regiondata;
wmXrActionData *customdata = event->customdata;
float viewmat_prev[4][4];
float winmat_prev[4][4];
int mval[2];
+ WM_xr_controller_loc_to_mval(customdata->controller_loc,
+ customdata->viewmat,
+ customdata->winmat,
+ region->winx,
+ region->winy,
+ mval);
+
+ RNA_int_set_array(op->ptr, "location", mval);
+
/* Since this function is called in a window context, we need to replace the
* window viewmat and winmat with the XR surface counterparts to get a correct
* result for GPU select. */
@@ -2545,15 +2537,6 @@ static int view3d_select_invoke_3d(bContext *C, wmOperator *op, const wmEvent *e
copy_m4_m4(rv3d->viewmat, customdata->viewmat);
copy_m4_m4(rv3d->winmat, customdata->winmat);
- controller_loc_to_mval(customdata->controller_loc,
- customdata->viewmat,
- customdata->winmat,
- ar->winx,
- ar->winy,
- mval);
-
- RNA_int_set_array(op->ptr, "location", mval);
-
int retval = view3d_select_exec(C, op);
copy_m4_m4(rv3d->viewmat, viewmat_prev);
copy_m4_m4(rv3d->winmat, winmat_prev);
@@ -3431,8 +3414,10 @@ void VIEW3D_OT_select_box(wmOperatorType *ot)
/* api callbacks */
ot->invoke = WM_gesture_box_invoke;
+ ot->invoke_3d = WM_gesture_box_invoke_3d;
ot->exec = view3d_box_select_exec;
ot->modal = WM_gesture_box_modal;
+ ot->modal_3d = WM_gesture_box_modal_3d;
ot->poll = view3d_selectable_data;
ot->cancel = WM_gesture_box_cancel;
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 754ad209c14..510c15d7ea0 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -614,7 +614,13 @@ void WM_paneltype_remove(struct PanelType *pt);
/* wm_gesture_ops.c */
int WM_gesture_box_invoke(struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
+int WM_gesture_box_invoke_3d(struct bContext *C,
+ struct wmOperator *op,
+ const struct wmEvent *event);
int WM_gesture_box_modal(struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
+int WM_gesture_box_modal_3d(struct bContext *C,
+ struct wmOperator *op,
+ const struct wmEvent *event);
void WM_gesture_box_cancel(struct bContext *C, struct wmOperator *op);
int WM_gesture_circle_invoke(struct bContext *C,
struct wmOperator *op,
@@ -986,6 +992,12 @@ void WM_xr_haptic_action_stop(wmXrData *xr,
const char *const *subaction_paths);
/* wm_xr_draw.c */
+void WM_xr_controller_loc_to_mval(const float loc[3],
+ const float viewmat[4][4],
+ const float winmat[4][4],
+ short winx,
+ short winy,
+ int r_mval[2]);
void WM_xr_draw_controllers(void /*const struct wmXrSessionState *state*/);
#endif
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index d7516cb913f..05aa8ab900d 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -2032,7 +2032,7 @@ static int wm_handler_operator_call(bContext *C,
* nothing to do in this case.
*/
}
- else if (ot->modal) {
+ else if (ot->modal || ot->modal_3d) {
/* we set context to where modal handler came from */
wmWindowManager *wm = CTX_wm_manager(C);
ScrArea *area = CTX_wm_area(C);
@@ -2048,7 +2048,15 @@ static int wm_handler_operator_call(bContext *C,
}
/* warning, after this call all context data and 'event' may be freed. see check below */
- retval = ot->modal(C, op, event);
+ if (ot->modal_3d && event->type == EVT_XR_ACTION) {
+ retval = ot->modal_3d(C, op, event);
+ }
+ else if (ot->modal) {
+ retval = ot->modal(C, op, event);
+ }
+ else {
+ /* Pass through. An "XR operator" (only modal_3d) received a non-XR event.*/
+ }
OPERATOR_RETVAL_CHECK(retval);
/* when this is _not_ the case the modal modifier may have loaded
diff --git a/source/blender/windowmanager/intern/wm_gesture_ops.c b/source/blender/windowmanager/intern/wm_gesture_ops.c
index 2c79b1f2215..12da6a81074 100644
--- a/source/blender/windowmanager/intern/wm_gesture_ops.c
+++ b/source/blender/windowmanager/intern/wm_gesture_ops.c
@@ -198,6 +198,33 @@ int WM_gesture_box_invoke(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
+int WM_gesture_box_invoke_3d(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ BLI_assert(event->type == EVT_XR_ACTION);
+ BLI_assert(event->custom == EVT_DATA_XR);
+ BLI_assert(event->customdata);
+
+ wmEvent event_mut;
+ memcpy(&event_mut, event, sizeof(wmEvent));
+
+ ARegion *region = CTX_wm_region(C);
+ wmXrActionData *customdata = event->customdata;
+ int mval[2];
+
+ WM_xr_controller_loc_to_mval(customdata->controller_loc,
+ customdata->viewmat,
+ customdata->winmat,
+ region->winx,
+ region->winy,
+ mval);
+ event_mut.x = mval[0];
+ event_mut.y = mval[1];
+
+ RNA_boolean_set(op->ptr, "wait_for_input", false);
+
+ return WM_gesture_box_invoke(C, op, &event_mut);
+}
+
int WM_gesture_box_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
wmWindow *win = CTX_wm_window(C);
@@ -261,6 +288,65 @@ int WM_gesture_box_modal(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
+int WM_gesture_box_modal_3d(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ BLI_assert(event->type == EVT_XR_ACTION);
+ BLI_assert(event->custom == EVT_DATA_XR);
+ BLI_assert(event->customdata);
+
+ wmEvent event_mut;
+ memcpy(&event_mut, event, sizeof(wmEvent));
+
+ ARegion *region = CTX_wm_region(C);
+ RegionView3D *rv3d = region->regiondata;
+ wmXrActionData *customdata = event->customdata;
+ int mval[2];
+
+ WM_xr_controller_loc_to_mval(customdata->controller_loc,
+ customdata->viewmat,
+ customdata->winmat,
+ region->winx,
+ region->winy,
+ mval);
+
+ if (event->val == KM_PRESS) {
+ event_mut.type = MOUSEMOVE;
+ {
+ wmGesture *gesture = op->customdata;
+ gesture->is_active = true;
+ }
+ event_mut.x = mval[0];
+ event_mut.y = mval[1];
+ }
+ else if (event->val == KM_RELEASE) {
+ event_mut.type = EVT_MODAL_MAP;
+ event_mut.val = GESTURE_MODAL_SELECT;
+
+ /* Since this function is called in a window context, we need to replace the
+ * window viewmat and winmat with the XR surface counterparts to get a correct
+ * result for some operators (e.g. GPU select).
+ * TODO_XR: There may be some cases where we don't want to replace the window mats? */
+ float viewmat_prev[4][4];
+ float winmat_prev[4][4];
+ copy_m4_m4(viewmat_prev, rv3d->viewmat);
+ copy_m4_m4(winmat_prev, rv3d->winmat);
+ copy_m4_m4(rv3d->viewmat, customdata->viewmat);
+ copy_m4_m4(rv3d->winmat, customdata->winmat);
+
+ int retval = WM_gesture_box_modal(C, op, &event_mut);
+ copy_m4_m4(rv3d->viewmat, viewmat_prev);
+ copy_m4_m4(rv3d->winmat, winmat_prev);
+
+ return retval;
+ }
+ else {
+ /* XR events currently only support press and release. */
+ BLI_assert(false);
+ }
+
+ return WM_gesture_box_modal(C, op, &event_mut);
+}
+
void WM_gesture_box_cancel(bContext *C, wmOperator *op)
{
gesture_modal_end(C, op);
diff --git a/source/blender/windowmanager/xr/intern/wm_xr_draw.c b/source/blender/windowmanager/xr/intern/wm_xr_draw.c
index ee1ca926de9..40d14893d96 100644
--- a/source/blender/windowmanager/xr/intern/wm_xr_draw.c
+++ b/source/blender/windowmanager/xr/intern/wm_xr_draw.c
@@ -55,6 +55,24 @@ void wm_xr_controller_pose_to_mat(const GHOST_XrPose *pose, float r_mat[4][4])
copy_v3_v3(r_mat[3], pose->position);
}
+/* Project 3D controller coordinates (in world space) to 2D mouse coordinates. */
+void WM_xr_controller_loc_to_mval(const float loc[3],
+ const float viewmat[4][4],
+ const float winmat[4][4],
+ short winx,
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list