diff --git a/doc/changes/state_trackers/mr.510.md b/doc/changes/state_trackers/mr.510.md new file mode 100644 index 000000000..aff860b81 --- /dev/null +++ b/doc/changes/state_trackers/mr.510.md @@ -0,0 +1,3 @@ +OpenXR: For pose actions the any path (`XR_NULL_PATH`) needs to be special +cased, essentially turning into a separate action sub path, that is assigned +at binding time. diff --git a/src/xrt/state_trackers/oxr/oxr_input.c b/src/xrt/state_trackers/oxr/oxr_input.c index 2c0bf9d30..fffef6bea 100644 --- a/src/xrt/state_trackers/oxr/oxr_input.c +++ b/src/xrt/state_trackers/oxr/oxr_input.c @@ -445,7 +445,7 @@ XrResult oxr_action_get_pose_input(struct oxr_logger *log, struct oxr_session *sess, uint32_t act_key, - const struct oxr_sub_paths *sub_paths, + const struct oxr_sub_paths *sub_paths_ptr, struct oxr_action_input **out_input) { struct oxr_action_attachment *act_attached = NULL; @@ -456,10 +456,14 @@ oxr_action_get_pose_input(struct oxr_logger *log, return XR_SUCCESS; } + struct oxr_sub_paths sub_paths = *sub_paths_ptr; + if (sub_paths.any) { + sub_paths = act_attached->any_pose_sub_path; + } + // Priority of inputs. #define GET_POSE_INPUT(X) \ - if (act_attached->X.current.active && \ - (sub_paths->X || sub_paths->any)) { \ + if (act_attached->X.current.active && sub_paths.X) { \ *out_input = act_attached->X.inputs; \ return XR_SUCCESS; \ } @@ -696,6 +700,29 @@ oxr_action_attachment_bind(struct oxr_logger *log, OXR_FOR_EACH_VALID_SUBACTION_PATH_DETAILED(BIND_SUBACTION) #undef BIND_SUBACTION + + /*! + * The any sub path is special cased for poses, it binds to one sub path + * and sticks with it. + */ + if (act_ref->action_type == XR_ACTION_TYPE_POSE_INPUT) { + +#define POSE_ANY(X) \ + if (act_ref->sub_paths.X && act_attached->X.num_inputs > 0) { \ + act_attached->any_pose_sub_path.X = true; \ + oxr_slog(&slog, \ + "\tFor: <any>\n\t\tBinding any pose to " #X ".\n"); \ + } else + OXR_FOR_EACH_VALID_SUBACTION_PATH(POSE_ANY) +#undef POSE_ANY + + { + oxr_slog(&slog, + "\tFor: <any>\n\t\tNo active sub paths for " + "the any pose!\n"); + } + } + oxr_slog(&slog, "\tDone"); // Also frees all data. @@ -1731,15 +1758,24 @@ oxr_action_get_pose(struct oxr_logger *log, "Action has not been attached to this session"); } + // For poses on the any path we select a single path. + if (sub_paths.any) { + sub_paths = act_attached->any_pose_sub_path; + } + data->isActive = XR_FALSE; + /* + * The sub path any is used as a catch all here to see if any + */ #define COMPUTE_ACTIVE(X) \ - if (sub_paths.X || sub_paths.any) { \ + if (sub_paths.X) { \ data->isActive |= act_attached->X.current.active; \ } OXR_FOR_EACH_VALID_SUBACTION_PATH(COMPUTE_ACTIVE) #undef COMPUTE_ACTIVE + return oxr_session_success_result(sess); } @@ -1771,8 +1807,6 @@ set_action_output_vibration(struct oxr_session *sess, } } - - XrResult oxr_action_apply_haptic_feedback(struct oxr_logger *log, struct oxr_session *sess, diff --git a/src/xrt/state_trackers/oxr/oxr_objects.h b/src/xrt/state_trackers/oxr/oxr_objects.h index f1ccfbf2d..151cd889d 100644 --- a/src/xrt/state_trackers/oxr/oxr_objects.h +++ b/src/xrt/state_trackers/oxr/oxr_objects.h @@ -1568,6 +1568,13 @@ struct oxr_action_attachment //! Unique key for the session hashmap. uint32_t act_key; + + /*! + * For pose actions any sub paths are special treated, at bind time we + * pick one sub path and stick to it as long as the action lives. + */ + struct oxr_sub_paths any_pose_sub_path; + struct oxr_action_state any_state; #define OXR_CACHE_MEMBER(X) struct oxr_action_cache X;