[Bf-blender-cvs] [e022f99e5c1] xr-controller-support: XR: Allow multiple modal actions at a time

Peter Kim noreply at git.blender.org
Sat Jun 26 12:34:17 CEST 2021


Commit: e022f99e5c19d1292125b95cd7a5fc196b02891e
Author: Peter Kim
Date:   Sat Jun 26 19:25:52 2021 +0900
Branches: xr-controller-support
https://developer.blender.org/rBe022f99e5c19d1292125b95cd7a5fc196b02891e

XR: Allow multiple modal actions at a time

This was disabled before since modal handlers for action operators
could receive events from other actions and exit prematurely. Now,
the XR operators check for events with the matching operator and
properties to avoid this. In addition, a list of active modal actions
is stored in the session state so that duplicate operators can be
filtered out when dispatching events.

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

M	source/blender/windowmanager/xr/intern/wm_xr_action.c
M	source/blender/windowmanager/xr/intern/wm_xr_intern.h
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/windowmanager/xr/intern/wm_xr_action.c b/source/blender/windowmanager/xr/intern/wm_xr_action.c
index 1b7e083ab95..a1344ad8986 100644
--- a/source/blender/windowmanager/xr/intern/wm_xr_action.c
+++ b/source/blender/windowmanager/xr/intern/wm_xr_action.c
@@ -23,6 +23,7 @@
  * All functions are designed to be usable by RNA / the Python API.
  */
 
+#include "BLI_listbase.h"
 #include "BLI_math.h"
 
 #include "GHOST_C-api.h"
@@ -56,6 +57,8 @@ static void action_set_destroy(void *val)
 
   MEM_SAFE_FREE(action_set->name);
 
+  BLI_freelistN(&action_set->active_modal_actions);
+
   MEM_freeN(action_set);
 }
 
@@ -184,9 +187,9 @@ void WM_xr_action_set_destroy(wmXrData *xr, const char *action_set_name)
       wm_xr_session_controller_data_clear(session_state);
       action_set->controller_pose_action = NULL;
     }
-    if (action_set->active_modal_action) {
-      action_set->active_modal_action = NULL;
-    }
+
+    BLI_freelistN(&action_set->active_modal_actions);
+
     session_state->active_action_set = NULL;
   }
 
@@ -265,14 +268,12 @@ void WM_xr_action_destroy(wmXrData *xr, const char *action_set_name, const char
     }
     action_set->controller_pose_action = NULL;
   }
-  if (action_set->active_modal_action &&
-      STREQ(action_set->active_modal_action->name, action_name)) {
-    action_set->active_modal_action = NULL;
-  }
 
-  wmXrAction *action = action_find(xr, action_set_name, action_name);
-  if (!action) {
-    return;
+  LISTBASE_FOREACH (LinkData *, ld, &action_set->active_modal_actions) {
+    wmXrAction *action = ld->data;
+    if (STREQ(action->name, action_name)) {
+      BLI_freelinkN(&action_set->active_modal_actions, ld);
+    }
   }
 }
 
@@ -372,16 +373,10 @@ bool WM_xr_active_action_set_set(wmXrData *xr, const char *action_set_name)
   }
 
   {
-    /* Unset active modal action (if any). */
+    /* Clear any active modal actions. */
     wmXrActionSet *active_action_set = xr->runtime->session_state.active_action_set;
     if (active_action_set) {
-      wmXrAction *active_modal_action = active_action_set->active_modal_action;
-      if (active_modal_action) {
-        if (active_modal_action->active_modal_path) {
-          active_modal_action->active_modal_path = NULL;
-        }
-        active_action_set->active_modal_action = NULL;
-      }
+      BLI_freelistN(&active_action_set->active_modal_actions);
     }
   }
 
diff --git a/source/blender/windowmanager/xr/intern/wm_xr_intern.h b/source/blender/windowmanager/xr/intern/wm_xr_intern.h
index cf7bda23aa0..2177768d48d 100644
--- a/source/blender/windowmanager/xr/intern/wm_xr_intern.h
+++ b/source/blender/windowmanager/xr/intern/wm_xr_intern.h
@@ -178,8 +178,8 @@ typedef struct wmXrActionSet {
    * although it could differ depending on the specification and hardware. */
   wmXrAction *controller_pose_action;
 
-  /** The currently active modal action (if any). */
-  wmXrAction *active_modal_action;
+  /** Currently active modal actions. */
+  ListBase active_modal_actions;
 } wmXrActionSet;
 
 wmXrRuntimeData *wm_xr_runtime_data_create(void);
diff --git a/source/blender/windowmanager/xr/intern/wm_xr_operators.c b/source/blender/windowmanager/xr/intern/wm_xr_operators.c
index 9963feb4a2c..414d2dd21b5 100644
--- a/source/blender/windowmanager/xr/intern/wm_xr_operators.c
+++ b/source/blender/windowmanager/xr/intern/wm_xr_operators.c
@@ -29,6 +29,7 @@
 #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_object.h"
@@ -61,17 +62,25 @@
 #include "wm_xr_intern.h"
 
 /* -------------------------------------------------------------------- */
-/** \name Operator Callbacks
+/** \name Operator Conditions
  * \{ */
 
 /* 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;
+  return WM_xr_session_is_ready(&wm->xr);
+}
+
+static bool wm_xr_operator_test_event(const wmOperator *op, const wmEvent *event)
+{
+  BLI_assert(event->type == EVT_XR_ACTION);
+  BLI_assert(event->custom == EVT_DATA_XR);
+  BLI_assert(event->customdata);
+
+  wmXrActionData *actiondata = event->customdata;
+  return (actiondata->ot == op->type &&
+          IDP_EqualsProperties(actiondata->op_properties, op->properties));
 }
 
 /** \} */
@@ -399,9 +408,9 @@ static void wm_xr_grab_compute_bimanual(const wmXrActionData *actiondata,
 
 static int wm_xr_navigation_grab_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);
+  if (!wm_xr_operator_test_event(op, event)) {
+    return OPERATOR_PASS_THROUGH;
+  }
 
   const wmXrActionData *actiondata = event->customdata;
 
@@ -420,9 +429,9 @@ static int wm_xr_navigation_grab_exec(bContext *UNUSED(C), wmOperator *UNUSED(op
 
 static int wm_xr_navigation_grab_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);
+  if (!wm_xr_operator_test_event(op, event)) {
+    return OPERATOR_PASS_THROUGH;
+  }
 
   const wmXrActionData *actiondata = event->customdata;
   XrGrabData *data = op->customdata;
@@ -834,9 +843,9 @@ static void wm_xr_basenav_rotation_calc(const wmXrData *xr,
 
 static int wm_xr_navigation_fly_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);
+  if (!wm_xr_operator_test_event(op, event)) {
+    return OPERATOR_PASS_THROUGH;
+  }
 
   int retval = op->type->modal_3d(C, op, event);
 
@@ -854,9 +863,9 @@ static int wm_xr_navigation_fly_exec(bContext *UNUSED(C), wmOperator *UNUSED(op)
 
 static int wm_xr_navigation_fly_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);
+  if (!wm_xr_operator_test_event(op, event)) {
+    return OPERATOR_PASS_THROUGH;
+  }
 
   if (event->val == KM_RELEASE) {
     return OPERATOR_FINISHED;
@@ -1123,9 +1132,9 @@ static void wm_xr_navigation_teleport(bContext *C,
 
 static int wm_xr_navigation_teleport_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);
+  if (!wm_xr_operator_test_event(op, event)) {
+    return OPERATOR_PASS_THROUGH;
+  }
 
   wm_xr_raycast_init(op);
 
@@ -1145,9 +1154,9 @@ static int wm_xr_navigation_teleport_exec(bContext *UNUSED(C), wmOperator *UNUSE
 
 static int wm_xr_navigation_teleport_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);
+  if (!wm_xr_operator_test_event(op, event)) {
+    return OPERATOR_PASS_THROUGH;
+  }
 
   const wmXrActionData *actiondata = event->customdata;
   wmWindowManager *wm = CTX_wm_manager(C);
@@ -1527,9 +1536,9 @@ static bool wm_xr_select_raycast(bContext *C,
 
 static int wm_xr_select_raycast_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);
+  if (!wm_xr_operator_test_event(op, event)) {
+    return OPERATOR_PASS_THROUGH;
+  }
 
   wm_xr_raycast_init(op);
 
@@ -1549,9 +1558,9 @@ static int wm_xr_select_raycast_exec(bContext *UNUSED(C), wmOperator *UNUSED(op)
 
 static int wm_xr_select_raycast_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);
+  if (!wm_xr_operator_test_event(op, event)) {
+    return OPERATOR_PASS_THROUGH;
+  }
 
   const wmXrActionData *actiondata = event->customdata;
   wmWindowManager *wm = CTX_wm_manager(C);
@@ -1674,9 +1683,9 @@ static void WM_OT_xr_select_raycast(wmOperatorType *ot)
 
 static int wm_xr_transform_grab_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);
+  if (!wm_xr_operator_test_event(op, event)) {
+    return OPERATOR_PASS_THROUGH;
+  }
 
   bool loc_lock, rot_lock, scale_lock;
   float loc_t, rot_t;
@@ -1847,9 +1856,9 @@ static int wm_xr_transform_grab_exec(bContext *UNUSED(C), wmOperator *UNUSED(op)
 
 static int wm_xr_transform_grab_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);
+  if (!wm_xr_operator_test_event(op, event)) {
+    return OPERATOR_PASS_THROUGH;
+  }
 
   const wmXrActionData *actiondata = event->customdata;
   XrGrabData *data = op->customdata;
diff --git a/source/blender/windowmanager/xr/intern/wm_xr_session.c b/source/blender/windowmanager/xr/intern/wm_xr_session.c
index 0919b64a0c0..403966dd8cd 100644
--- a/source/blender/windowmanager/xr/intern/wm_xr_session.c
+++ b/source/blender/windowmanager/xr/intern/wm_xr_session.c
@@ -21,6 +21,7 @@
 #include "BKE_callbacks.h"
 #include "BKE_context.h"
 #include "BKE_global.h"
+#include "BKE_idprop.h"
 #include "BKE_layer.h"
 #include "BKE_main.h"
 #include "BKE_scene.h"
@@ -788,6 +789,55 @@ BLI_INLINE bool test_vec2f_state(const float state[2], float threshold, eXrActio
   return (len_v2(state) > threshold);
 }
 
+static bool wm_xr_session_modal_action_test(const ListBase *active_modal_actions,
+                                            const wmXrAction *action,
+                                            bool *r_found)
+{
+  if (r_found) {
+    *r_found = false;
+  }
+
+  LISTBASE_FOREACH (LinkData *, ld, active_modal_actions) {
+    wmXrAction *active_modal_action = ld->data;
+    if (action == active_modal_action) {
+      if (r_found) {
+        *r_f

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list