Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorPeter Kim <pk15950@gmail.com>2021-08-05 17:40:17 +0300
committerPeter Kim <pk15950@gmail.com>2021-08-05 17:40:17 +0300
commite844e9e8f3bb6814e24749316003814156e2e2ce (patch)
tree3c3ef939b10a84b2de5c2f5fb2e713a0b49e3dca /intern
parent0cff7c2a228589505bd2d66e966e5e84613b2786 (diff)
XR Controller Support Step 2: Action Maps
Addresses the remaining portions of T77137 (Python API for Controller Interaction), which was partially completed by D10942. Adds an XR "action maps" system for loading XR action data from a Python script. Action maps are accessible via the Python API, and are used to pass default actions to the VR session during the xr_session_start_pre() callback. Since action maps are stored only as runtime data, they will be cleaned up with the rest of the VR runtime data on file read or exit. Reviewed By: Julian Eisel, Hans Goudey Differential Revision: https://developer.blender.org/D10943
Diffstat (limited to 'intern')
-rw-r--r--intern/ghost/GHOST_C-api.h16
-rw-r--r--intern/ghost/intern/GHOST_C-api.cpp33
-rw-r--r--intern/ghost/intern/GHOST_XrAction.cpp64
-rw-r--r--intern/ghost/intern/GHOST_XrAction.h8
-rw-r--r--intern/ghost/intern/GHOST_XrSession.cpp31
-rw-r--r--intern/ghost/intern/GHOST_XrSession.h7
6 files changed, 135 insertions, 24 deletions
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index fea5a545807..83c67f83908 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -1102,6 +1102,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 int64_t *duration,
const float *frequency,
const float *amplitude);
@@ -1111,7 +1112,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).
@@ -1126,6 +1128,18 @@ void *GHOST_XrGetActionCustomdata(GHOST_XrContextHandle xr_context,
const char *action_set_name,
const char *action_name);
+/**
+ * Get the number of actions in an action set.
+ */
+unsigned int GHOST_XrGetActionCount(GHOST_XrContextHandle xr_context, const char *action_set_name);
+
+/**
+ * Get custom data for all actions in an action set.
+ */
+void GHOST_XrGetActionCustomdataArray(GHOST_XrContextHandle xr_context,
+ const char *action_set_name,
+ void **r_customdata_array);
+
#endif /* WITH_XR_OPENXR */
#ifdef __cplusplus
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index 0bc9be26eb1..b1af5c131ab 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -1005,25 +1005,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 int64_t *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,
@@ -1046,4 +1050,23 @@ void *GHOST_XrGetActionCustomdata(GHOST_XrContextHandle xr_contexthandle,
return 0;
}
+unsigned int GHOST_XrGetActionCount(GHOST_XrContextHandle xr_contexthandle,
+ const char *action_set_name)
+{
+ GHOST_IXrContext *xr_context = (GHOST_IXrContext *)xr_contexthandle;
+ GHOST_XrSession *xr_session = xr_context->getSession();
+ GHOST_XR_CAPI_CALL_RET(xr_session->getActionCount(action_set_name), xr_context);
+ return 0;
+}
+
+void GHOST_XrGetActionCustomdataArray(GHOST_XrContextHandle xr_contexthandle,
+ const char *action_set_name,
+ void **r_customdata_array)
+{
+ GHOST_IXrContext *xr_context = (GHOST_IXrContext *)xr_contexthandle;
+ GHOST_XrSession *xr_session = xr_context->getSession();
+ GHOST_XR_CAPI_CALL(xr_session->getActionCustomdataArray(action_set_name, r_customdata_array),
+ xr_context);
+}
+
#endif /* WITH_XR_OPENXR */
diff --git a/intern/ghost/intern/GHOST_XrAction.cpp b/intern/ghost/intern/GHOST_XrAction.cpp
index 676a3367ee1..07eb42c14e6 100644
--- a/intern/ghost/intern/GHOST_XrAction.cpp
+++ b/intern/ghost/intern/GHOST_XrAction.cpp
@@ -208,8 +208,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};
@@ -373,6 +375,7 @@ void GHOST_XrAction::updateState(XrSession session,
void GHOST_XrAction::applyHapticFeedback(XrSession session,
const char *action_name,
+ const char **subaction_path_str,
const int64_t &duration,
const float &frequency,
const float &amplitude)
@@ -386,24 +389,46 @@ void GHOST_XrAction::applyHapticFeedback(XrSession session,
XrHapticActionInfo haptic_info{XR_TYPE_HAPTIC_ACTION_INFO};
haptic_info.action = m_action;
- for (std::vector<XrPath>::iterator it = m_subaction_paths.begin(); it != m_subaction_paths.end();
- ++it) {
- haptic_info.subactionPath = *it;
- CHECK_XR(xrApplyHapticFeedback(session, &haptic_info, (const XrHapticBaseHeader *)&vibration),
- (std::string("Failed to apply haptic action \"") + action_name + "\".").data());
+ if (subaction_path_str != nullptr) {
+ SubactionIndexMap::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 (std::vector<XrPath>::iterator it = m_subaction_paths.begin(); it != m_subaction_paths.end();
- ++it) {
- haptic_info.subactionPath = *it;
- CHECK_XR(xrStopHapticFeedback(session, &haptic_info),
- (std::string("Failed to stop haptic action \"") + action_name + "\".").data());
+ if (subaction_path_str != nullptr) {
+ SubactionIndexMap::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());
+ }
}
}
@@ -511,6 +536,19 @@ void *GHOST_XrActionSet::getCustomdata()
return m_custom_data_->custom_data_;
}
+uint32_t GHOST_XrActionSet::getActionCount() const
+{
+ return (uint32_t)m_actions.size();
+}
+
+void GHOST_XrActionSet::getActionCustomdataArray(void **r_customdata_array)
+{
+ uint32_t i = 0;
+ for (auto &[name, action] : m_actions) {
+ r_customdata_array[i++] = action.getCustomdata();
+ }
+}
+
void GHOST_XrActionSet::getBindings(
std::map<XrPath, std::vector<XrActionSuggestedBinding>> &r_bindings) const
{
diff --git a/intern/ghost/intern/GHOST_XrAction.h b/intern/ghost/intern/GHOST_XrAction.h
index e2a89e87278..73a1cd9cd6a 100644
--- a/intern/ghost/intern/GHOST_XrAction.h
+++ b/intern/ghost/intern/GHOST_XrAction.h
@@ -103,17 +103,21 @@ class GHOST_XrAction {
const XrTime &predicted_display_time);
void applyHapticFeedback(XrSession session,
const char *action_name,
+ const char **subaction_path,
const int64_t &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;
private:
+ using SubactionIndexMap = std::map<std::string, uint32_t>;
+
XrAction m_action = XR_NULL_HANDLE;
GHOST_XrActionType m_type;
+ SubactionIndexMap m_subaction_indices;
std::vector<XrPath> m_subaction_paths;
/** States for each subaction path. */
void *m_states;
@@ -145,6 +149,8 @@ class GHOST_XrActionSet {
XrActionSet getActionSet() const;
void *getCustomdata();
+ uint32_t getActionCount() const;
+ void getActionCustomdataArray(void **r_customdata_array);
void getBindings(std::map<XrPath, std::vector<XrActionSuggestedBinding>> &r_bindings) const;
private:
diff --git a/intern/ghost/intern/GHOST_XrSession.cpp b/intern/ghost/intern/GHOST_XrSession.cpp
index a29ec1cc560..a63ce5c9344 100644
--- a/intern/ghost/intern/GHOST_XrSession.cpp
+++ b/intern/ghost/intern/GHOST_XrSession.cpp
@@ -754,6 +754,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 int64_t &duration,
const float &frequency,
const float &amplitude)
@@ -768,12 +769,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) {
@@ -785,7 +789,7 @@ void GHOST_XrSession::stopHapticAction(const char *action_set_name, const char *
return;
}
- action->stopHapticFeedback(m_oxr->session, action_name);
+ action->stopHapticFeedback(m_oxr->session, action_name, subaction_path);
}
void *GHOST_XrSession::getActionSetCustomdata(const char *action_set_name)
@@ -813,4 +817,25 @@ void *GHOST_XrSession::getActionCustomdata(const char *action_set_name, const ch
return action->getCustomdata();
}
+uint32_t GHOST_XrSession::getActionCount(const char *action_set_name)
+{
+ GHOST_XrActionSet *action_set = find_action_set(m_oxr.get(), action_set_name);
+ if (action_set == nullptr) {
+ return 0;
+ }
+
+ return action_set->getActionCount();
+}
+
+void GHOST_XrSession::getActionCustomdataArray(const char *action_set_name,
+ void **r_customdata_array)
+{
+ GHOST_XrActionSet *action_set = find_action_set(m_oxr.get(), action_set_name);
+ if (action_set == nullptr) {
+ return;
+ }
+
+ action_set->getActionCustomdataArray(r_customdata_array);
+}
+
/** \} */ /* Actions */
diff --git a/intern/ghost/intern/GHOST_XrSession.h b/intern/ghost/intern/GHOST_XrSession.h
index cdeef153fb1..ec15897058f 100644
--- a/intern/ghost/intern/GHOST_XrSession.h
+++ b/intern/ghost/intern/GHOST_XrSession.h
@@ -76,14 +76,19 @@ class GHOST_XrSession {
bool syncActions(const char *action_set_name = nullptr);
bool applyHapticAction(const char *action_set_name,
const char *action_name,
+ const char **subaction_path,
const int64_t &duration,
const float &frequency,
const float &amplitude);
- void stopHapticAction(const char *action_set_name, const char *action_name);
+ void stopHapticAction(const char *action_set_name,
+ const char *action_name,
+ const char **subaction_path);
/* Custom data (owned by Blender, not GHOST) accessors. */
void *getActionSetCustomdata(const char *action_set_name);
void *getActionCustomdata(const char *action_set_name, const char *action_name);
+ uint32_t getActionCount(const char *action_set_name);
+ void getActionCustomdataArray(const char *action_set_name, void **r_customdata_array);
private:
/** Pointer back to context managing this session. Would be nice to avoid, but needed to access