[Bf-blender-cvs] [314e5cb8899] master: XR: Fix controller flicker when switching action sets

Peter Kim noreply at git.blender.org
Sat May 28 10:24:30 CEST 2022


Commit: 314e5cb8899734347624ab23b458ccedab09a0dd
Author: Peter Kim
Date:   Sat May 28 17:23:27 2022 +0900
Branches: master
https://developer.blender.org/rB314e5cb8899734347624ab23b458ccedab09a0dd

XR: Fix controller flicker when switching action sets

This could happen when switching between custom action sets that both
had controller pose actions. Problem was that controller data is
cleared when changing action sets, and this clearing was done when
handling WM events, which always occurs after XR controller data is
updated from GHOST.

Now, instead of activating the action set immediately, delay activation
until just before the next XR actions sync.

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

M	source/blender/makesrna/intern/rna_xr.c
M	source/blender/windowmanager/WM_api.h
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_session.c

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

diff --git a/source/blender/makesrna/intern/rna_xr.c b/source/blender/makesrna/intern/rna_xr.c
index 696d2d0f31d..dcfa1bbca51 100644
--- a/source/blender/makesrna/intern/rna_xr.c
+++ b/source/blender/makesrna/intern/rna_xr.c
@@ -849,7 +849,7 @@ bool rna_XrSessionState_active_action_set_set(bContext *C, const char *action_se
 {
 #  ifdef WITH_XR_OPENXR
   wmWindowManager *wm = CTX_wm_manager(C);
-  return WM_xr_active_action_set_set(&wm->xr, action_set_name);
+  return WM_xr_active_action_set_set(&wm->xr, action_set_name, true);
 #  else
   UNUSED_VARS(C, action_set_name);
   return false;
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index dda60975a96..890872a06bc 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -1700,7 +1700,7 @@ void WM_xr_action_binding_destroy(wmXrData *xr,
 /**
  * If action_set_name is NULL, then all action sets will be treated as active.
  */
-bool WM_xr_active_action_set_set(wmXrData *xr, const char *action_set_name);
+bool WM_xr_active_action_set_set(wmXrData *xr, const char *action_set_name, bool delayed);
 
 bool WM_xr_controller_pose_actions_set(wmXrData *xr,
                                        const char *action_set_name,
diff --git a/source/blender/windowmanager/xr/intern/wm_xr_action.c b/source/blender/windowmanager/xr/intern/wm_xr_action.c
index 6750e7a7d77..a83415c98af 100644
--- a/source/blender/windowmanager/xr/intern/wm_xr_action.c
+++ b/source/blender/windowmanager/xr/intern/wm_xr_action.c
@@ -391,13 +391,20 @@ void WM_xr_action_binding_destroy(wmXrData *xr,
       xr->runtime->context, action_set_name, 1, &action_name, &profile_path);
 }
 
-bool WM_xr_active_action_set_set(wmXrData *xr, const char *action_set_name)
+bool WM_xr_active_action_set_set(wmXrData *xr, const char *action_set_name, bool delayed)
 {
   wmXrActionSet *action_set = action_set_find(xr, action_set_name);
   if (!action_set) {
     return false;
   }
 
+  if (delayed) {
+    /* Save name to activate action set later, before next actions sync
+     * (see #wm_xr_session_actions_update()). */
+    strcpy(xr->runtime->session_state.active_action_set_next, action_set_name);
+    return true;
+  }
+
   {
     /* Clear any active modal/haptic actions. */
     wmXrActionSet *active_action_set = xr->runtime->session_state.active_action_set;
diff --git a/source/blender/windowmanager/xr/intern/wm_xr_intern.h b/source/blender/windowmanager/xr/intern/wm_xr_intern.h
index 3fc1f362541..bb24514457d 100644
--- a/source/blender/windowmanager/xr/intern/wm_xr_intern.h
+++ b/source/blender/windowmanager/xr/intern/wm_xr_intern.h
@@ -54,9 +54,11 @@ typedef struct wmXrSessionState {
   ListBase controllers; /* #wmXrController */
 
   /** The currently active action set that will be updated on calls to
-   * wm_xr_session_actions_update(). If NULL, all action sets will be treated as active and
+   * #wm_xr_session_actions_update(). If NULL, all action sets will be treated as active and
    * updated. */
   struct wmXrActionSet *active_action_set;
+  /* Name of the action set (if any) to activate before the next actions sync. */
+  char active_action_set_next[64]; /* MAX_NAME */
 } wmXrSessionState;
 
 typedef struct wmXrRuntimeData {
diff --git a/source/blender/windowmanager/xr/intern/wm_xr_session.c b/source/blender/windowmanager/xr/intern/wm_xr_session.c
index 2a829e274d9..a4d2a65830f 100644
--- a/source/blender/windowmanager/xr/intern/wm_xr_session.c
+++ b/source/blender/windowmanager/xr/intern/wm_xr_session.c
@@ -1175,7 +1175,6 @@ void wm_xr_session_actions_update(wmWindowManager *wm)
   XrSessionSettings *settings = &xr->session_settings;
   GHOST_XrContextHandle xr_context = xr->runtime->context;
   wmXrSessionState *state = &xr->runtime->session_state;
-  wmXrActionSet *active_action_set = state->active_action_set;
 
   if (state->is_navigation_dirty) {
     memcpy(&state->nav_pose_prev, &state->nav_pose, sizeof(state->nav_pose_prev));
@@ -1192,6 +1191,13 @@ void wm_xr_session_actions_update(wmWindowManager *wm)
         &state->viewer_pose, settings->base_scale * state->nav_scale, state->viewer_viewmat);
   }
 
+  /* Set active action set if requested previously. */
+  if (state->active_action_set_next[0]) {
+    WM_xr_active_action_set_set(xr, state->active_action_set_next, false);
+    state->active_action_set_next[0] = '\0';
+  }
+  wmXrActionSet *active_action_set = state->active_action_set;
+
   const bool synced = GHOST_XrSyncActions(xr_context,
                                           active_action_set ? active_action_set->name : NULL);
   if (!synced) {



More information about the Bf-blender-cvs mailing list