[Bf-blender-cvs] [c8db91fc936] xr-actions-D9124: XR: Only allow one active modal action/subaction
Peter Kim
noreply at git.blender.org
Mon Nov 23 08:17:56 CET 2020
Commit: c8db91fc936ed90cbc86622bbd6ab4e016cb7f08
Author: Peter Kim
Date: Mon Nov 23 16:16:41 2020 +0900
Branches: xr-actions-D9124
https://developer.blender.org/rBc8db91fc936ed90cbc86622bbd6ab4e016cb7f08
XR: Only allow one active modal action/subaction
Prevents unwanted behavior when a modal operator is bound to multiple
inputs (e.g. when an action has multiple subaction paths). Can be
refactored in the future to support "bimanual" interaction for some
operators.
===================================================================
M intern/ghost/GHOST_Types.h
M source/blender/windowmanager/xr/intern/wm_xr_actions.c
M source/blender/windowmanager/xr/intern/wm_xr_intern.h
M source/blender/windowmanager/xr/intern/wm_xr_session.c
===================================================================
diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h
index c1ee5dbd1d1..4e7a75bb393 100644
--- a/intern/ghost/GHOST_Types.h
+++ b/intern/ghost/GHOST_Types.h
@@ -713,6 +713,9 @@ typedef struct GHOST_XrActionInfo {
/** Input threshold for float actions (only used by wm). */
float threshold;
+ /** The currently active subaction path (if any) for modal actions (only used by wm). */
+ char **active_modal_path;
+
/** Operator to be called on XR events (only used by wm). */
void *ot;
void *op_properties;
diff --git a/source/blender/windowmanager/xr/intern/wm_xr_actions.c b/source/blender/windowmanager/xr/intern/wm_xr_actions.c
index 3ada9b6ca8e..70d46f3faf9 100644
--- a/source/blender/windowmanager/xr/intern/wm_xr_actions.c
+++ b/source/blender/windowmanager/xr/intern/wm_xr_actions.c
@@ -197,6 +197,9 @@ void WM_xr_action_set_destroy(wmXrData *xr, const char *action_set_name, bool re
wm_xr_session_controller_data_clear(&xr->runtime->session_state);
action_set->controller_pose_action = NULL;
}
+ if (action_set->active_modal_action) {
+ action_set->active_modal_action = NULL;
+ }
session_state->active_action_set = NULL;
}
@@ -261,21 +264,38 @@ void WM_xr_actions_destroy(wmXrData *xr,
GHOST_XrDestroyActions(xr->runtime->context, action_set_name, count, action_names);
- /* Save name of controller pose action in case the action is removed from the GHash. */
+ GHash *actions = action_set->actions;
char controller_pose_name[64];
- strcpy(controller_pose_name, action_set->controller_pose_action->name);
+ char active_modal_name[64];
+
+ /* Save names of controller pose and active modal actions in case they are removed from the
+ * GHash. */
+ if (action_set->controller_pose_action) {
+ strcpy(controller_pose_name, action_set->controller_pose_action->name);
+ }
+ else {
+ controller_pose_name[0] = '\0';
+ }
+ if (action_set->active_modal_action) {
+ strcpy(active_modal_name, action_set->active_modal_action->name);
+ }
+ else {
+ active_modal_name[0] = '\0';
+ }
- GHash *actions = action_set->actions;
for (unsigned int i = 0; i < count; ++i) {
BLI_ghash_remove(actions, action_names[i], NULL, action_destroy);
}
- if (!action_find(action_set, controller_pose_name)) {
+ if ((controller_pose_name[0] != '\0') && !action_find(action_set, controller_pose_name)) {
if (action_set == xr->runtime->session_state.active_action_set) {
wm_xr_session_controller_data_clear(&xr->runtime->session_state);
}
action_set->controller_pose_action = NULL;
}
+ if ((active_modal_name[0] != '\0') && !action_find(action_set, active_modal_name)) {
+ action_set->active_modal_action = NULL;
+ }
}
bool WM_xr_action_spaces_create(wmXrData *xr,
@@ -318,6 +338,20 @@ bool WM_xr_active_action_set_set(wmXrData *xr, const char *action_set_name)
return false;
}
+ {
+ /* Unset active modal action (if any). */
+ 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;
+ }
+ }
+ }
+
xr->runtime->session_state.active_action_set = action_set;
if (action_set->controller_pose_action) {
diff --git a/source/blender/windowmanager/xr/intern/wm_xr_intern.h b/source/blender/windowmanager/xr/intern/wm_xr_intern.h
index 1ef2ac595de..cff648f1341 100644
--- a/source/blender/windowmanager/xr/intern/wm_xr_intern.h
+++ b/source/blender/windowmanager/xr/intern/wm_xr_intern.h
@@ -136,6 +136,9 @@ typedef struct wmXrAction {
/** Input threshold for float actions. */
float threshold;
+ /** The currently active subaction path (if any) for modal actions. */
+ char **active_modal_path;
+
/** Operator to be called on XR events. */
struct wmOperatorType *ot;
IDProperty *op_properties;
@@ -145,10 +148,14 @@ typedef struct wmXrAction {
typedef struct wmXrActionSet {
char *name;
struct GHash *actions; /* wmXrAction */
+
/** Shared pointer with the GHash. The XR pose action that determines the controller
* transforms. This is usually identified by the OpenXR path "/grip/pose" or "/aim/pose",
* although it could differ depending on the specification and hardware. */
wmXrAction *controller_pose_action;
+
+ /** Shared pointer with the GHash. The currently active modal action (if any). */
+ wmXrAction *active_modal_action;
} wmXrActionSet;
wmXrRuntimeData *wm_xr_runtime_data_create(void);
diff --git a/source/blender/windowmanager/xr/intern/wm_xr_session.c b/source/blender/windowmanager/xr/intern/wm_xr_session.c
index 69b2cb6f8e6..024ef21b97d 100644
--- a/source/blender/windowmanager/xr/intern/wm_xr_session.c
+++ b/source/blender/windowmanager/xr/intern/wm_xr_session.c
@@ -621,12 +621,16 @@ static const GHOST_XrPose *wm_xr_session_controller_pose_find(const wmXrSessionS
/* Dispatch events to XR surface / window queues. */
static void wm_xr_session_events_dispatch(const XrSessionSettings *settings,
- const char *action_set_name,
- GHash *actions,
+ wmXrActionSet *action_set,
wmXrSessionState *session_state,
wmSurface *surface,
wmWindow *win)
{
+ const wmXrEyeData *eye_data = &session_state->eyes[settings->selection_eye];
+ const char *action_set_name = action_set->name;
+ GHash *actions = action_set->actions;
+ wmXrAction *active_modal_action = action_set->active_modal_action;
+
GHashIterator *ghi = BLI_ghashIterator_new(actions);
GHASH_ITER (*ghi, actions) {
wmXrAction *action = BLI_ghashIterator_getValue(ghi);
@@ -634,7 +638,7 @@ static void wm_xr_session_events_dispatch(const XrSessionSettings *settings,
bool modal = (action->ot->modal || action->ot->modal_3d) ? true : false;
for (unsigned int i = 0; i < action->count_subaction_paths; ++i) {
- short val = KM_ANY;
+ short val = KM_NOTHING;
bool press_start;
switch (action->type) {
@@ -646,6 +650,11 @@ static void wm_xr_session_events_dispatch(const XrSessionSettings *settings,
if (modal || action->op_flag == XR_OP_PRESS) {
val = KM_PRESS;
press_start = true;
+ if (modal && !active_modal_action) {
+ /* Set active modal action. */
+ active_modal_action = action_set->active_modal_action = action;
+ active_modal_action->active_modal_path = &action->subaction_paths[i];
+ }
}
}
else if (modal) {
@@ -657,6 +666,12 @@ static void wm_xr_session_events_dispatch(const XrSessionSettings *settings,
if (modal || action->op_flag == XR_OP_RELEASE) {
val = KM_RELEASE;
press_start = false;
+ if (modal && ((action == active_modal_action) &&
+ (&action->subaction_paths[i] == action->active_modal_path))) {
+ /* Unset active modal action. */
+ active_modal_action->active_modal_path = NULL;
+ active_modal_action = action_set->active_modal_action = NULL;
+ }
}
}
*state_prev = *state;
@@ -670,6 +685,11 @@ static void wm_xr_session_events_dispatch(const XrSessionSettings *settings,
if (modal || action->op_flag == XR_OP_PRESS) {
val = KM_PRESS;
press_start = true;
+ if (modal && !active_modal_action) {
+ /* Set active modal action. */
+ active_modal_action = action_set->active_modal_action = action;
+ active_modal_action->active_modal_path = &action->subaction_paths[i];
+ }
}
}
else if (modal) {
@@ -681,6 +701,12 @@ static void wm_xr_session_events_dispatch(const XrSessionSettings *settings,
if (modal || action->op_flag == XR_OP_RELEASE) {
val = KM_RELEASE;
press_start = false;
+ if (modal && ((action == active_modal_action) &&
+ (&action->subaction_paths[i] == action->active_modal_path))) {
+ /* Unset active modal action. */
+ active_modal_action->active_modal_path = NULL;
+ active_modal_action = action_set->active_modal_action = NULL;
+ }
}
}
*state_prev = *state;
@@ -694,6 +720,11 @@ static void wm_xr_session_events_dispatch(const XrSessionSettings *settings,
if (modal || action->op_flag == XR_OP_PRESS) {
val = KM_PRESS;
press_start = true;
+ if (modal && !active_modal_action) {
+ /* Set active modal action. */
+ active_modal_action = action_set->active_modal_action = action;
+ active_modal_action->active_modal_path = &action->subaction_paths[i];
+ }
}
}
else if (modal) {
@@ -705,6 +736,12 @@ static void wm_xr_session_events_dispatch(const XrSessionSettings *settings,
if (modal || action->op_flag == XR_OP_RELEASE) {
val = KM_RELEASE;
press_start = false;
+ if (modal && ((action == active_modal_action) &&
+ (&action->subaction_paths[i] == action->active_modal_path))) {
+ /* Unset active modal action. */
+ active_modal_action->active_modal_path = NULL;
+ active_modal_action = action_set->active_modal_action = NULL;
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list