diff options
author | Peter Kim <pk15950@gmail.com> | 2022-02-17 09:41:53 +0300 |
---|---|---|
committer | Peter Kim <pk15950@gmail.com> | 2022-02-17 09:51:16 +0300 |
commit | 6a8709ba136ef4e8522555f279294a886595e34c (patch) | |
tree | 1edbe054f8e9b14c537e841c56ee648816f4ee53 /source/blender/windowmanager | |
parent | 7d4d8a13ce9e93c7382edbd816042837bf3aa4e6 (diff) |
XR: Allow variable count of action map subactions
Previously, the number of action map subactions was limited to two per
action (identified by user_path0, user_path1), however for devices with
more than two user paths (e.g. Vive Tracker) it will be useful to
support a variable amount instead.
For example, a single pose action could then be used to query the
positions of all connected trackers, with each tracker having its own
subaction tracking space.
NOTE: This introduces breaking changes for the XR Python API as follows:
- XrActionMapItem: The new `user_paths` collection property
replaces the `user_path0`/`user_path1` properties.
- XrActionMapBinding: The new `component_paths` collection property
replaces the `component_path0`/`component_path1` properties.
Reviewed By: Severin
Differential Revision: https://developer.blender.org/D13949
Diffstat (limited to 'source/blender/windowmanager')
5 files changed, 76 insertions, 54 deletions
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index c1281632cc1..49fbf2c27e1 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -1583,8 +1583,7 @@ bool WM_xr_action_create(wmXrData *xr, const char *action_set_name, const char *action_name, eXrActionType type, - unsigned int count_subaction_paths, - const char **subaction_paths, + const ListBase *user_paths, struct wmOperatorType *ot, struct IDProperty *op_properties, const char *haptic_name, @@ -1599,9 +1598,8 @@ bool WM_xr_action_binding_create(wmXrData *xr, const char *action_set_name, const char *action_name, const char *profile_path, - unsigned int count_subaction_paths, - const char **subaction_paths, - const char **component_paths, + const ListBase *user_paths, + const ListBase *component_paths, const float *float_thresholds, const eXrAxisFlag *axis_flags, const struct wmXrPose *poses); diff --git a/source/blender/windowmanager/xr/intern/wm_xr_action.c b/source/blender/windowmanager/xr/intern/wm_xr_action.c index f6003428700..0ce0837d83a 100644 --- a/source/blender/windowmanager/xr/intern/wm_xr_action.c +++ b/source/blender/windowmanager/xr/intern/wm_xr_action.c @@ -56,8 +56,7 @@ static wmXrActionSet *action_set_find(wmXrData *xr, const char *action_set_name) static wmXrAction *action_create(const char *action_name, eXrActionType type, - unsigned int count_subaction_paths, - const char **subaction_paths, + const ListBase *user_paths, wmOperatorType *ot, IDProperty *op_properties, const char *haptic_name, @@ -73,15 +72,16 @@ static wmXrAction *action_create(const char *action_name, strcpy(action->name, action_name); action->type = type; - const unsigned int count = count_subaction_paths; + const unsigned int count = (unsigned int)BLI_listbase_count(user_paths); + unsigned int subaction_idx = 0; action->count_subaction_paths = count; action->subaction_paths = MEM_mallocN(sizeof(*action->subaction_paths) * count, "XrAction_SubactionPaths"); - for (unsigned int i = 0; i < count; ++i) { - action->subaction_paths[i] = MEM_mallocN(strlen(subaction_paths[i]) + 1, - "XrAction_SubactionPath"); - strcpy(action->subaction_paths[i], subaction_paths[i]); + LISTBASE_FOREACH_INDEX (XrUserPath *, user_path, user_paths, subaction_idx) { + action->subaction_paths[subaction_idx] = MEM_mallocN(strlen(user_path->path) + 1, + "XrAction_SubactionPath"); + strcpy(action->subaction_paths[subaction_idx], user_path->path); } size_t size; @@ -140,10 +140,9 @@ static void action_destroy(void *val) MEM_SAFE_FREE(action->name); - const unsigned int count = action->count_subaction_paths; char **subaction_paths = action->subaction_paths; if (subaction_paths) { - for (unsigned int i = 0; i < count; ++i) { + for (unsigned int i = 0; i < action->count_subaction_paths; ++i) { MEM_SAFE_FREE(subaction_paths[i]); } MEM_freeN(subaction_paths); @@ -214,8 +213,7 @@ bool WM_xr_action_create(wmXrData *xr, const char *action_set_name, const char *action_name, eXrActionType type, - unsigned int count_subaction_paths, - const char **subaction_paths, + const ListBase *user_paths, wmOperatorType *ot, IDProperty *op_properties, const char *haptic_name, @@ -232,8 +230,7 @@ bool WM_xr_action_create(wmXrData *xr, wmXrAction *action = action_create(action_name, type, - count_subaction_paths, - subaction_paths, + user_paths, ot, op_properties, haptic_name, @@ -244,9 +241,19 @@ bool WM_xr_action_create(wmXrData *xr, action_flag, haptic_flag); + const unsigned int count = (unsigned int)BLI_listbase_count(user_paths); + unsigned int subaction_idx = 0; + + char **subaction_paths = MEM_calloc_arrayN( + count, sizeof(*subaction_paths), "XrAction_SubactionPathPointers"); + + LISTBASE_FOREACH_INDEX (XrUserPath *, user_path, user_paths, subaction_idx) { + subaction_paths[subaction_idx] = (char *)user_path->path; + } + GHOST_XrActionInfo info = { .name = action_name, - .count_subaction_paths = count_subaction_paths, + .count_subaction_paths = count, .subaction_paths = subaction_paths, .states = action->states, .float_thresholds = action->float_thresholds, @@ -273,11 +280,11 @@ bool WM_xr_action_create(wmXrData *xr, break; } - if (!GHOST_XrCreateActions(xr->runtime->context, action_set_name, 1, &info)) { - return false; - } + const bool success = GHOST_XrCreateActions(xr->runtime->context, action_set_name, 1, &info); - return true; + MEM_freeN(subaction_paths); + + return success; } void WM_xr_action_destroy(wmXrData *xr, const char *action_set_name, const char *action_name) @@ -323,19 +330,29 @@ bool WM_xr_action_binding_create(wmXrData *xr, const char *action_set_name, const char *action_name, const char *profile_path, - unsigned int count_subaction_paths, - const char **subaction_paths, - const char **component_paths, + const ListBase *user_paths, + const ListBase *component_paths, const float *float_thresholds, const eXrAxisFlag *axis_flags, const struct wmXrPose *poses) { + const unsigned int count = (unsigned int)BLI_listbase_count(user_paths); + BLI_assert(count == (unsigned int)BLI_listbase_count(component_paths)); + GHOST_XrActionBindingInfo *binding_infos = MEM_calloc_arrayN( - count_subaction_paths, sizeof(*binding_infos), __func__); + count, sizeof(*binding_infos), "XrActionBinding_Infos"); - for (unsigned int i = 0; i < count_subaction_paths; ++i) { + char **subaction_paths = MEM_calloc_arrayN( + count, sizeof(*subaction_paths), "XrActionBinding_SubactionPathPointers"); + + for (unsigned int i = 0; i < count; ++i) { GHOST_XrActionBindingInfo *binding_info = &binding_infos[i]; - binding_info->component_path = component_paths[i]; + const XrUserPath *user_path = BLI_findlink(user_paths, i); + const XrComponentPath *component_path = BLI_findlink(component_paths, i); + + subaction_paths[i] = (char *)user_path->path; + + binding_info->component_path = component_path->path; if (float_thresholds) { binding_info->float_threshold = float_thresholds[i]; } @@ -351,15 +368,18 @@ bool WM_xr_action_binding_create(wmXrData *xr, GHOST_XrActionProfileInfo profile_info = { .action_name = action_name, .profile_path = profile_path, - .count_subaction_paths = count_subaction_paths, + .count_subaction_paths = count, .subaction_paths = subaction_paths, .bindings = binding_infos, }; - bool ret = GHOST_XrCreateActionBindings(xr->runtime->context, action_set_name, 1, &profile_info); + const bool success = GHOST_XrCreateActionBindings( + xr->runtime->context, action_set_name, 1, &profile_info); + MEM_freeN(subaction_paths); MEM_freeN(binding_infos); - return ret; + + return success; } void WM_xr_action_binding_destroy(wmXrData *xr, diff --git a/source/blender/windowmanager/xr/intern/wm_xr_actionmap.c b/source/blender/windowmanager/xr/intern/wm_xr_actionmap.c index 0c356ab2b2e..267fb0481a8 100644 --- a/source/blender/windowmanager/xr/intern/wm_xr_actionmap.c +++ b/source/blender/windowmanager/xr/intern/wm_xr_actionmap.c @@ -118,11 +118,17 @@ XrActionMapBinding *WM_xr_actionmap_binding_add_copy(XrActionMapItem *ami, return amb_dst; } +static void wm_xr_actionmap_binding_clear(XrActionMapBinding *amb) +{ + BLI_freelistN(&amb->component_paths); +} + bool WM_xr_actionmap_binding_remove(XrActionMapItem *ami, XrActionMapBinding *amb) { int idx = BLI_findindex(&ami->bindings, amb); if (idx != -1) { + wm_xr_actionmap_binding_clear(amb); BLI_freelinkN(&ami->bindings, amb); if (idx <= ami->selbinding) { @@ -155,12 +161,6 @@ XrActionMapBinding *WM_xr_actionmap_binding_find(XrActionMapItem *ami, const cha * Item in an XR action map, that maps an XR event to an operator, pose, or haptic output. * \{ */ -static void wm_xr_actionmap_item_bindings_clear(XrActionMapItem *ami) -{ - BLI_freelistN(&ami->bindings); - ami->selbinding = 0; -} - static void wm_xr_actionmap_item_properties_set(XrActionMapItem *ami) { WM_operator_properties_alloc(&(ami->op_properties_ptr), &(ami->op_properties), ami->op); @@ -180,6 +180,19 @@ static void wm_xr_actionmap_item_properties_free(XrActionMapItem *ami) } } +static void wm_xr_actionmap_item_clear(XrActionMapItem *ami) +{ + LISTBASE_FOREACH (XrActionMapBinding *, amb, &ami->bindings) { + wm_xr_actionmap_binding_clear(amb); + } + BLI_freelistN(&ami->bindings); + ami->selbinding = 0; + + wm_xr_actionmap_item_properties_free(ami); + + BLI_freelistN(&ami->user_paths); +} + void WM_xr_actionmap_item_properties_update_ot(XrActionMapItem *ami) { switch (ami->type) { @@ -324,8 +337,7 @@ bool WM_xr_actionmap_item_remove(XrActionMap *actionmap, XrActionMapItem *ami) int idx = BLI_findindex(&actionmap->items, ami); if (idx != -1) { - wm_xr_actionmap_item_bindings_clear(ami); - wm_xr_actionmap_item_properties_free(ami); + wm_xr_actionmap_item_clear(ami); BLI_freelinkN(&actionmap->items, ami); if (idx <= actionmap->selitem) { @@ -480,12 +492,9 @@ XrActionMap *WM_xr_actionmap_find(wmXrRuntimeData *runtime, const char *name) void WM_xr_actionmap_clear(XrActionMap *actionmap) { LISTBASE_FOREACH (XrActionMapItem *, ami, &actionmap->items) { - wm_xr_actionmap_item_bindings_clear(ami); - wm_xr_actionmap_item_properties_free(ami); + wm_xr_actionmap_item_clear(ami); } - BLI_freelistN(&actionmap->items); - actionmap->selitem = 0; } @@ -494,9 +503,7 @@ void WM_xr_actionmaps_clear(wmXrRuntimeData *runtime) LISTBASE_FOREACH (XrActionMap *, am, &runtime->actionmaps) { WM_xr_actionmap_clear(am); } - BLI_freelistN(&runtime->actionmaps); - runtime->actactionmap = runtime->selactionmap = 0; } diff --git a/source/blender/windowmanager/xr/intern/wm_xr_intern.h b/source/blender/windowmanager/xr/intern/wm_xr_intern.h index 0e7c4d18753..9480104150a 100644 --- a/source/blender/windowmanager/xr/intern/wm_xr_intern.h +++ b/source/blender/windowmanager/xr/intern/wm_xr_intern.h @@ -114,12 +114,8 @@ typedef struct wmXrDrawData { typedef struct wmXrController { struct wmXrController *next, *prev; - /** OpenXR path identifier. Length is dependent on OpenXR's XR_MAX_PATH_LENGTH (256). - This subaction path will later be combined with a component path, and that combined path should - also have a max of XR_MAX_PATH_LENGTH (e.g. subaction_path = /user/hand/left, component_path = - /input/trigger/value, interaction_path = /user/hand/left/input/trigger/value). - */ - char subaction_path[64]; + /** OpenXR user path identifier. */ + char subaction_path[64]; /* XR_MAX_USER_PATH_LENGTH */ /** Pose (in world space) that represents the user's hand when holding the controller. */ GHOST_XrPose grip_pose; diff --git a/source/blender/windowmanager/xr/intern/wm_xr_session.c b/source/blender/windowmanager/xr/intern/wm_xr_session.c index 59b4eb00363..dfeaeae196c 100644 --- a/source/blender/windowmanager/xr/intern/wm_xr_session.c +++ b/source/blender/windowmanager/xr/intern/wm_xr_session.c @@ -1188,8 +1188,9 @@ void wm_xr_session_actions_update(wmWindowManager *wm) &state->viewer_pose, settings->base_scale * state->nav_scale, state->viewer_viewmat); } - int ret = GHOST_XrSyncActions(xr_context, active_action_set ? active_action_set->name : NULL); - if (!ret) { + const bool synced = GHOST_XrSyncActions(xr_context, + active_action_set ? active_action_set->name : NULL); + if (!synced) { return; } |