[Bf-blender-cvs] [714224ee1ff] xr-controller-support: XR: Support haptic feedback for actions

Peter Kim noreply at git.blender.org
Fri Jul 2 11:18:50 CEST 2021


Commit: 714224ee1ff6224d6334e2fc0e3da77a076d2b6e
Author: Peter Kim
Date:   Fri Jul 2 18:10:34 2021 +0900
Branches: xr-controller-support
https://developer.blender.org/rB714224ee1ff6224d6334e2fc0e3da77a076d2b6e

XR: Support haptic feedback for actions

Adds haptic settings to float (button) actions that can be used to
apply haptics when an action is active. Users can configure the
duration, frequency, and amplitude of the feedback as well as when
it will be applied (press, release, press/release, or repeat).

The haptic output path/target is specified via the name of an
existing action of type "haptic". This allows float actions to target
the same output paths without the need for multiple haptic actions.

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

M	intern/ghost/GHOST_C-api.h
M	intern/ghost/intern/GHOST_C-api.cpp
M	intern/ghost/intern/GHOST_XrAction.cpp
M	intern/ghost/intern/GHOST_XrAction.h
M	intern/ghost/intern/GHOST_XrSession.cpp
M	intern/ghost/intern/GHOST_XrSession.h
M	source/blender/makesdna/DNA_xr_types.h
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/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index c62ba7972a1..d01076ae7be 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -1138,6 +1138,7 @@ int GHOST_XrSyncActions(GHOST_XrContextHandle xr_context, const char *action_set
 int GHOST_XrApplyHapticAction(GHOST_XrContextHandle xr_context,
                               const char *action_set_name,
                               const char *action_name,
+                              const char **subaction_path,
                               const GHOST_TInt64 *duration,
                               const float *frequency,
                               const float *amplitude);
@@ -1147,7 +1148,8 @@ int GHOST_XrApplyHapticAction(GHOST_XrContextHandle xr_context,
  */
 void GHOST_XrStopHapticAction(GHOST_XrContextHandle xr_context,
                               const char *action_set_name,
-                              const char *action_name);
+                              const char *action_name,
+                              const char **subaction_path);
 
 /**
  * Get action set custom data (owned by Blender, not GHOST).
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index 7844fccc7fe..c50bd96f19e 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -1054,25 +1054,29 @@ int GHOST_XrSyncActions(GHOST_XrContextHandle xr_contexthandle, const char *acti
 int GHOST_XrApplyHapticAction(GHOST_XrContextHandle xr_contexthandle,
                               const char *action_set_name,
                               const char *action_name,
+                              const char **subaction_path,
                               const GHOST_TInt64 *duration,
                               const float *frequency,
                               const float *amplitude)
 {
   GHOST_IXrContext *xr_context = (GHOST_IXrContext *)xr_contexthandle;
   GHOST_XrSession *xr_session = xr_context->getSession();
-  GHOST_XR_CAPI_CALL_RET(xr_session->applyHapticAction(
-                             action_set_name, action_name, *duration, *frequency, *amplitude),
-                         xr_context);
+  GHOST_XR_CAPI_CALL_RET(
+      xr_session->applyHapticAction(
+          action_set_name, action_name, subaction_path, *duration, *frequency, *amplitude),
+      xr_context);
   return 0;
 }
 
 void GHOST_XrStopHapticAction(GHOST_XrContextHandle xr_contexthandle,
                               const char *action_set_name,
-                              const char *action_name)
+                              const char *action_name,
+                              const char **subaction_path)
 {
   GHOST_IXrContext *xr_context = (GHOST_IXrContext *)xr_contexthandle;
   GHOST_XrSession *xr_session = xr_context->getSession();
-  GHOST_XR_CAPI_CALL(xr_session->stopHapticAction(action_set_name, action_name), xr_context);
+  GHOST_XR_CAPI_CALL(xr_session->stopHapticAction(action_set_name, action_name, subaction_path),
+                     xr_context);
 }
 
 void *GHOST_XrGetActionSetCustomdata(GHOST_XrContextHandle xr_contexthandle,
diff --git a/intern/ghost/intern/GHOST_XrAction.cpp b/intern/ghost/intern/GHOST_XrAction.cpp
index 50f578717ed..e364ef98c06 100644
--- a/intern/ghost/intern/GHOST_XrAction.cpp
+++ b/intern/ghost/intern/GHOST_XrAction.cpp
@@ -158,8 +158,10 @@ GHOST_XrAction::GHOST_XrAction(XrInstance instance,
   m_subaction_paths.resize(info.count_subaction_paths);
 
   for (uint32_t i = 0; i < info.count_subaction_paths; ++i) {
-    CHECK_XR(xrStringToPath(instance, info.subaction_paths[i], &m_subaction_paths[i]),
-             (std::string("Failed to get user path \"") + info.subaction_paths[i] + "\".").data());
+    const char *subaction_path_str = info.subaction_paths[i];
+    CHECK_XR(xrStringToPath(instance, subaction_path_str, &m_subaction_paths[i]),
+             (std::string("Failed to get user path \"") + subaction_path_str + "\".").data());
+    m_subaction_indices.insert({subaction_path_str, i});
   }
 
   XrActionCreateInfo action_info{XR_TYPE_ACTION_CREATE_INFO};
@@ -329,6 +331,7 @@ void GHOST_XrAction::updateState(XrSession session,
 
 void GHOST_XrAction::applyHapticFeedback(XrSession session,
                                          const char *action_name,
+                                         const char **subaction_path_str,
                                          const GHOST_TInt64 &duration,
                                          const float &frequency,
                                          const float &amplitude)
@@ -342,22 +345,46 @@ void GHOST_XrAction::applyHapticFeedback(XrSession session,
   XrHapticActionInfo haptic_info{XR_TYPE_HAPTIC_ACTION_INFO};
   haptic_info.action = m_action;
 
-  for (const XrPath &subaction_path : m_subaction_paths) {
-    haptic_info.subactionPath = subaction_path;
-    CHECK_XR(xrApplyHapticFeedback(session, &haptic_info, (const XrHapticBaseHeader *)&vibration),
-             (std::string("Failed to apply haptic action \"") + action_name + "\".").data());
+  if (subaction_path_str != nullptr) {
+    std::map<std::string, uint32_t>::iterator it = m_subaction_indices.find(*subaction_path_str);
+    if (it != m_subaction_indices.end()) {
+      haptic_info.subactionPath = m_subaction_paths[it->second];
+      CHECK_XR(
+          xrApplyHapticFeedback(session, &haptic_info, (const XrHapticBaseHeader *)&vibration),
+          (std::string("Failed to apply haptic action \"") + action_name + "\".").data());
+    }
+  }
+  else {
+    for (const XrPath &subaction_path : m_subaction_paths) {
+      haptic_info.subactionPath = subaction_path;
+      CHECK_XR(
+          xrApplyHapticFeedback(session, &haptic_info, (const XrHapticBaseHeader *)&vibration),
+          (std::string("Failed to apply haptic action \"") + action_name + "\".").data());
+    }
   }
 }
 
-void GHOST_XrAction::stopHapticFeedback(XrSession session, const char *action_name)
+void GHOST_XrAction::stopHapticFeedback(XrSession session,
+                                        const char *action_name,
+                                        const char **subaction_path_str)
 {
   XrHapticActionInfo haptic_info{XR_TYPE_HAPTIC_ACTION_INFO};
   haptic_info.action = m_action;
 
-  for (const XrPath &subaction_path : m_subaction_paths) {
-    haptic_info.subactionPath = subaction_path;
-    CHECK_XR(xrStopHapticFeedback(session, &haptic_info),
-             (std::string("Failed to stop haptic action \"") + action_name + "\".").data());
+  if (subaction_path_str != nullptr) {
+    std::map<std::string, uint32_t>::iterator it = m_subaction_indices.find(*subaction_path_str);
+    if (it != m_subaction_indices.end()) {
+      haptic_info.subactionPath = m_subaction_paths[it->second];
+      CHECK_XR(xrStopHapticFeedback(session, &haptic_info),
+               (std::string("Failed to stop haptic action \"") + action_name + "\".").data());
+    }
+  }
+  else {
+    for (const XrPath &subaction_path : m_subaction_paths) {
+      haptic_info.subactionPath = subaction_path;
+      CHECK_XR(xrStopHapticFeedback(session, &haptic_info),
+               (std::string("Failed to stop haptic action \"") + action_name + "\".").data());
+    }
   }
 }
 
diff --git a/intern/ghost/intern/GHOST_XrAction.h b/intern/ghost/intern/GHOST_XrAction.h
index 222b398e392..0e96b32d67b 100644
--- a/intern/ghost/intern/GHOST_XrAction.h
+++ b/intern/ghost/intern/GHOST_XrAction.h
@@ -19,7 +19,7 @@
  */
 
 /* Note: Requires OpenXR headers to be included before this one for OpenXR types (XrSpace, XrPath,
- * etc.). */
+ * etc). */
 
 #pragma once
 
@@ -91,10 +91,11 @@ class GHOST_XrAction {
                    const XrTime &predicted_display_time);
   void applyHapticFeedback(XrSession session,
                            const char *action_name,
+                           const char **subaction_path,
                            const GHOST_TInt64 &duration,
                            const float &frequency,
                            const float &amplitude);
-  void stopHapticFeedback(XrSession session, const char *action_name);
+  void stopHapticFeedback(XrSession session, const char *action_name, const char **subaction_path);
 
   void *getCustomdata();
   void getBindings(std::map<XrPath, std::vector<XrActionSuggestedBinding>> &r_bindings) const;
@@ -102,6 +103,7 @@ class GHOST_XrAction {
  private:
   XrAction m_action = XR_NULL_HANDLE;
   GHOST_XrActionType m_type;
+  std::map<std::string, uint32_t> m_subaction_indices;
   std::vector<XrPath> m_subaction_paths;
   /** States for each subaction path. */
   void *m_states;
diff --git a/intern/ghost/intern/GHOST_XrSession.cpp b/intern/ghost/intern/GHOST_XrSession.cpp
index 2e3c4017cbb..b94a7a4048d 100644
--- a/intern/ghost/intern/GHOST_XrSession.cpp
+++ b/intern/ghost/intern/GHOST_XrSession.cpp
@@ -815,6 +815,7 @@ bool GHOST_XrSession::syncActions(const char *action_set_name)
 
 bool GHOST_XrSession::applyHapticAction(const char *action_set_name,
                                         const char *action_name,
+                                        const char **subaction_path,
                                         const GHOST_TInt64 &duration,
                                         const float &frequency,
                                         const float &amplitude)
@@ -829,12 +830,15 @@ bool GHOST_XrSession::applyHapticAction(const char *action_set_name,
     return false;
   }
 
-  action->applyHapticFeedback(m_oxr->session, action_name, duration, frequency, amplitude);
+  action->applyHapticFeedback(
+      m_oxr->session, action_name, subaction_path, duration, frequency, amplitude);
 
   return true;
 }
 
-void GHOST_XrSession::stopHapticAction(const char *action_set_name, const char *action_name)
+void GHOST_XrSession::stopHapticAction(const char *action_set_name,
+                                       const char *action_name,
+                                       const char **subaction_path)
 {
   GHOST_XrActionSet *action_set = find_action_set(m_oxr.get(), action_set_name);
   if (action_set == nullptr) {
@@ -846,7 +850,7 @@ void GHOST_XrSession::stopHapticAction(const char *action_set_name, const char *
     r

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list