diff --git a/src/xrt/drivers/vive/vive_controller_driver.c b/src/xrt/drivers/vive/vive_controller_driver.c index 93dd788bf..2cc8182e4 100644 --- a/src/xrt/drivers/vive/vive_controller_driver.c +++ b/src/xrt/drivers/vive/vive_controller_driver.c @@ -86,8 +86,7 @@ enum vive_controller_input_index VIVE_CONTROLLER_INDEX_SYSTEM_CLICK, VIVE_CONTROLLER_INDEX_TRIGGER_CLICK, VIVE_CONTROLLER_INDEX_TRIGGER_VALUE, - VIVE_CONTROLLER_INDEX_TRACKPAD_X, - VIVE_CONTROLLER_INDEX_TRACKPAD_Y, + VIVE_CONTROLLER_INDEX_TRACKPAD, VIVE_CONTROLLER_INDEX_TRACKPAD_TOUCH, // Vive Wand specific inputs @@ -96,8 +95,7 @@ enum vive_controller_input_index VIVE_CONTROLLER_INDEX_TRACKPAD_CLICK, // Valve Index specific inputs - VIVE_CONTROLLER_INDEX_THUMBSTICK_X, - VIVE_CONTROLLER_INDEX_THUMBSTICK_Y, + VIVE_CONTROLLER_INDEX_THUMBSTICK, VIVE_CONTROLLER_INDEX_A_CLICK, VIVE_CONTROLLER_INDEX_B_CLICK, VIVE_CONTROLLER_INDEX_THUMBSTICK_CLICK, @@ -268,23 +266,15 @@ vive_controller_device_update_wand_inputs(struct xrt_device *xdev) } } - if (d->state.trackpad.x != 0) { + if (d->state.trackpad.x != 0 || d->state.trackpad.y != 0) { struct xrt_input *input = - &d->base.inputs[VIVE_CONTROLLER_INDEX_TRACKPAD_X]; + &d->base.inputs[VIVE_CONTROLLER_INDEX_TRACKPAD]; input->timestamp = now; - input->value.vec1.x = d->state.trackpad.x; - } - - if (d->state.trackpad.y != 0) { - struct xrt_input *input = - &d->base.inputs[VIVE_CONTROLLER_INDEX_TRACKPAD_Y]; - input->timestamp = now; - input->value.vec1.x = d->state.trackpad.y; - } - - if (d->state.trackpad.x != 0 || d->state.trackpad.y != 0) + input->value.vec2.x = d->state.trackpad.x; + input->value.vec2.y = d->state.trackpad.y; VIVE_CONTROLLER_DEBUG(d, "Trackpad: %f, %f", d->state.trackpad.x, d->state.trackpad.y); + } if (d->state.trigger != 0) { struct xrt_input *input = @@ -348,33 +338,18 @@ vive_controller_device_update_index_inputs(struct xrt_device *xdev) * report trackpad position when trackpad has been touched last, and * thumbstick position when trackpad touch has been released */ - if (d->state.trackpad.x != 0) { - struct xrt_input *input; - if (d->base.inputs[VIVE_CONTROLLER_INDEX_TRACKPAD_TOUCH] - .value.boolean) - input = - &d->base.inputs[VIVE_CONTROLLER_INDEX_TRACKPAD_X]; - else - input = - &d->base.inputs[VIVE_CONTROLLER_INDEX_THUMBSTICK_X]; - input->timestamp = now; - input->value.vec1.x = d->state.trackpad.x; - } - - if (d->state.trackpad.y != 0) { - struct xrt_input *input; - if (d->base.inputs[VIVE_CONTROLLER_INDEX_TRACKPAD_TOUCH] - .value.boolean) - input = - &d->base.inputs[VIVE_CONTROLLER_INDEX_TRACKPAD_X]; - else - input = - &d->base.inputs[VIVE_CONTROLLER_INDEX_THUMBSTICK_X]; - input->timestamp = now; - input->value.vec1.x = d->state.trackpad.y; - } - if (d->state.trackpad.x != 0 || d->state.trackpad.y != 0) { + struct xrt_input *input; + if (d->base.inputs[VIVE_CONTROLLER_INDEX_TRACKPAD_TOUCH] + .value.boolean) + input = &d->base.inputs[VIVE_CONTROLLER_INDEX_TRACKPAD]; + else + input = + &d->base.inputs[VIVE_CONTROLLER_INDEX_THUMBSTICK]; + input->timestamp = now; + input->value.vec2.x = d->state.trackpad.x; + input->value.vec2.y = d->state.trackpad.y; + const char *component = d->base.inputs[VIVE_CONTROLLER_INDEX_TRACKPAD_TOUCH] .value.boolean @@ -1159,8 +1134,7 @@ vive_controller_found(struct xrt_prober *xp, SET_WAND_INPUT(MENU_CLICK, MENU_CLICK); SET_WAND_INPUT(TRIGGER_CLICK, TRIGGER_CLICK); SET_WAND_INPUT(TRIGGER_VALUE, TRIGGER_VALUE); - SET_WAND_INPUT(TRACKPAD_X, TRACKPAD_X); - SET_WAND_INPUT(TRACKPAD_Y, TRACKPAD_Y); + SET_WAND_INPUT(TRACKPAD, TRACKPAD); SET_WAND_INPUT(TRACKPAD_CLICK, TRACKPAD_CLICK); SET_WAND_INPUT(TRACKPAD_TOUCH, TRACKPAD_TOUCH); @@ -1180,11 +1154,9 @@ vive_controller_found(struct xrt_prober *xp, SET_INDEX_INPUT(B_CLICK, B_CLICK); SET_INDEX_INPUT(TRIGGER_CLICK, TRIGGER_CLICK); SET_INDEX_INPUT(TRIGGER_VALUE, TRIGGER_VALUE); - SET_INDEX_INPUT(TRACKPAD_X, TRACKPAD_X); - SET_INDEX_INPUT(TRACKPAD_Y, TRACKPAD_Y); + SET_INDEX_INPUT(TRACKPAD, TRACKPAD); SET_INDEX_INPUT(TRACKPAD_TOUCH, TRACKPAD_TOUCH); - SET_INDEX_INPUT(THUMBSTICK_X, THUMBSTICK_X); - SET_INDEX_INPUT(THUMBSTICK_Y, THUMBSTICK_Y); + SET_INDEX_INPUT(THUMBSTICK, THUMBSTICK); SET_INDEX_INPUT(THUMBSTICK_CLICK, THUMBSTICK_CLICK); SET_INDEX_INPUT(AIM_POSE, AIM_POSE); diff --git a/src/xrt/include/xrt/xrt_defines.h b/src/xrt/include/xrt/xrt_defines.h index af6bc22cc..48395fe79 100644 --- a/src/xrt/include/xrt/xrt_defines.h +++ b/src/xrt/include/xrt/xrt_defines.h @@ -469,12 +469,10 @@ enum xrt_input_name XRT_INPUT_INDEX_TRIGGER_CLICK = XRT_INPUT_NAME(0x0058, BOOLEAN), XRT_INPUT_INDEX_TRIGGER_VALUE = XRT_INPUT_NAME(0x0059, VEC1_ZERO_TO_ONE), XRT_INPUT_INDEX_TRIGGER_TOUCH = XRT_INPUT_NAME(0x005A, BOOLEAN), - XRT_INPUT_INDEX_THUMBSTICK_X = XRT_INPUT_NAME(0x005B, VEC1_ZERO_TO_ONE), - XRT_INPUT_INDEX_THUMBSTICK_Y = XRT_INPUT_NAME(0x005C, VEC1_ZERO_TO_ONE), + XRT_INPUT_INDEX_THUMBSTICK = XRT_INPUT_NAME(0x005B, VEC2_MINUS_ONE_TO_ONE), XRT_INPUT_INDEX_THUMBSTICK_CLICK = XRT_INPUT_NAME(0x005D, BOOLEAN), XRT_INPUT_INDEX_THUMBSTICK_TOUCH = XRT_INPUT_NAME(0x005E, BOOLEAN), - XRT_INPUT_INDEX_TRACKPAD_X = XRT_INPUT_NAME(0x005F, VEC1_ZERO_TO_ONE), - XRT_INPUT_INDEX_TRACKPAD_Y = XRT_INPUT_NAME(0x0060, VEC1_ZERO_TO_ONE), + XRT_INPUT_INDEX_TRACKPAD = XRT_INPUT_NAME(0x005F, VEC2_MINUS_ONE_TO_ONE), XRT_INPUT_INDEX_TRACKPAD_FORCE = XRT_INPUT_NAME(0x0061, VEC1_ZERO_TO_ONE), XRT_INPUT_INDEX_TRACKPAD_TOUCH = XRT_INPUT_NAME(0x0062, BOOLEAN), XRT_INPUT_INDEX_GRIP_POSE = XRT_INPUT_NAME(0x0063, POSE), @@ -485,8 +483,7 @@ enum xrt_input_name XRT_INPUT_VIVE_MENU_CLICK = XRT_INPUT_NAME(0x0072, BOOLEAN), XRT_INPUT_VIVE_TRIGGER_CLICK = XRT_INPUT_NAME(0x0073, BOOLEAN), XRT_INPUT_VIVE_TRIGGER_VALUE = XRT_INPUT_NAME(0x0074, VEC1_ZERO_TO_ONE), - XRT_INPUT_VIVE_TRACKPAD_X = XRT_INPUT_NAME(0x0075, VEC1_ZERO_TO_ONE), - XRT_INPUT_VIVE_TRACKPAD_Y = XRT_INPUT_NAME(0x0076, VEC1_ZERO_TO_ONE), + XRT_INPUT_VIVE_TRACKPAD = XRT_INPUT_NAME(0x0076, VEC2_MINUS_ONE_TO_ONE), XRT_INPUT_VIVE_TRACKPAD_CLICK = XRT_INPUT_NAME(0x0077, BOOLEAN), XRT_INPUT_VIVE_TRACKPAD_TOUCH = XRT_INPUT_NAME(0x0077, BOOLEAN), XRT_INPUT_VIVE_GRIP_POSE = XRT_INPUT_NAME(0x0078, POSE), diff --git a/src/xrt/include/xrt/xrt_device.h b/src/xrt/include/xrt/xrt_device.h index 9a3351868..79be46948 100644 --- a/src/xrt/include/xrt/xrt_device.h +++ b/src/xrt/include/xrt/xrt_device.h @@ -189,6 +189,13 @@ struct xrt_input union xrt_input_value value; }; +enum xrt_source_value_redirect +{ + INPUT_REDIRECT_DEFAULT = 0, + INPUT_REDIRECT_VEC2_X_TO_VEC1, + INPUT_REDIRECT_VEC2_Y_TO_VEC1 +}; + struct xrt_output { enum xrt_output_name name; diff --git a/src/xrt/state_trackers/oxr/oxr_binding.c b/src/xrt/state_trackers/oxr/oxr_binding.c index 6d8b50d56..75d618ffd 100644 --- a/src/xrt/state_trackers/oxr/oxr_binding.c +++ b/src/xrt/state_trackers/oxr/oxr_binding.c @@ -195,7 +195,8 @@ static void add_key_to_matching_bindings(struct oxr_binding *bindings, size_t num_bindings, XrPath path, - uint32_t key) + uint32_t key, + uint32_t *preferred_binding_path) { for (size_t x = 0; x < num_bindings; x++) { struct oxr_binding *b = &bindings[x]; @@ -204,6 +205,7 @@ add_key_to_matching_bindings(struct oxr_binding *bindings, for (size_t y = 0; y < b->num_paths; y++) { if (b->paths[y] == path) { found = true; + *preferred_binding_path = y; break; } } @@ -391,8 +393,9 @@ oxr_action_suggest_interaction_profile_bindings( fprintf(stderr, "\t\t%s %i -> %s\n", act->name, act->key, str); #endif - add_key_to_matching_bindings(bindings, num_bindings, s->binding, - act->key); + add_key_to_matching_bindings( + bindings, num_bindings, s->binding, act->key, + &act->preferred_binding_path_index); } return XR_SUCCESS; diff --git a/src/xrt/state_trackers/oxr/oxr_binding_data.h b/src/xrt/state_trackers/oxr/oxr_binding_data.h index 2f5df2e94..8c8a93e47 100644 --- a/src/xrt/state_trackers/oxr/oxr_binding_data.h +++ b/src/xrt/state_trackers/oxr/oxr_binding_data.h @@ -826,6 +826,69 @@ static struct binding_template mnd_ball_on_stick_controller_bindings[26] = { }, \ }, +// creates an input that can not be "downgraded" to the top level path. +// e.g. don't bind ../trackpad/click, ../trackpad/touch with just ../trackpad +#define MAKE_INPUT_SUFFIX_ONLY(COMPONENT, SUFFIX, INPUT) \ + { \ + .sub_path = OXR_SUB_ACTION_PATH_LEFT, \ + .paths = \ + { \ + "/user/hand/left/input/" #COMPONENT "/" #SUFFIX, \ + NULL, \ + }, \ + .inputs = \ + { \ + INPUT, \ + (enum xrt_input_name)0, \ + }, \ + }, \ + { \ + .sub_path = OXR_SUB_ACTION_PATH_RIGHT, \ + .paths = \ + { \ + "/user/hand/right/input/" #COMPONENT "/" #SUFFIX, \ + NULL, \ + }, \ + .inputs = \ + { \ + INPUT, \ + (enum xrt_input_name)0, \ + }, \ + }, + +// creates an input with a top level path and /x and /y sub paths +#define MAKE_INPUT_VEC2F(COMPONENT, INPUT) \ + { \ + .sub_path = OXR_SUB_ACTION_PATH_LEFT, \ + .paths = \ + { \ + "/user/hand/left/input/" #COMPONENT, \ + "/user/hand/left/input/" #COMPONENT "/x", \ + "/user/hand/left/input/" #COMPONENT "/y", \ + NULL, \ + }, \ + .inputs = \ + { \ + INPUT, \ + (enum xrt_input_name)0, \ + }, \ + }, \ + { \ + .sub_path = OXR_SUB_ACTION_PATH_RIGHT, \ + .paths = \ + { \ + "/user/hand/right/input/" #COMPONENT, \ + "/user/hand/right/input/" #COMPONENT "/x", \ + "/user/hand/right/input/" #COMPONENT "/y", \ + NULL, \ + }, \ + .inputs = \ + { \ + INPUT, \ + (enum xrt_input_name)0, \ + }, \ + }, + #define MAKE_OUTPUT(COMPONENT, SUFFIX, OUTPUT) \ { \ .sub_path = OXR_SUB_ACTION_PATH_LEFT, \ @@ -869,14 +932,12 @@ static struct binding_template valve_index_controller_bindings[44] = { MAKE_INPUT(trigger, click, XRT_INPUT_INDEX_TRIGGER_CLICK) MAKE_INPUT(trigger, value, XRT_INPUT_INDEX_TRIGGER_VALUE) MAKE_INPUT(trigger, touch, XRT_INPUT_INDEX_TRIGGER_TOUCH) - MAKE_INPUT(thumbstick, x, XRT_INPUT_INDEX_THUMBSTICK_X) - MAKE_INPUT(thumbstick, y, XRT_INPUT_INDEX_THUMBSTICK_Y) - MAKE_INPUT(thumbstick, click, XRT_INPUT_INDEX_THUMBSTICK_CLICK) - MAKE_INPUT(thumbstick, touch, XRT_INPUT_INDEX_THUMBSTICK_TOUCH) - MAKE_INPUT(trackpad, x, XRT_INPUT_INDEX_TRACKPAD_X) - MAKE_INPUT(trackpad, y, XRT_INPUT_INDEX_TRACKPAD_Y) - MAKE_INPUT(trackpad, force, XRT_INPUT_INDEX_TRACKPAD_FORCE) - MAKE_INPUT(trackpad, touch, XRT_INPUT_INDEX_TRACKPAD_TOUCH) + MAKE_INPUT_VEC2F(thumbstick, XRT_INPUT_INDEX_THUMBSTICK) + MAKE_INPUT_SUFFIX_ONLY(thumbstick, click, XRT_INPUT_INDEX_THUMBSTICK_CLICK) + MAKE_INPUT_SUFFIX_ONLY(thumbstick, touch, XRT_INPUT_INDEX_THUMBSTICK_TOUCH) + MAKE_INPUT_VEC2F(trackpad, XRT_INPUT_INDEX_TRACKPAD) + MAKE_INPUT_SUFFIX_ONLY(trackpad, force, XRT_INPUT_INDEX_TRACKPAD_FORCE) + MAKE_INPUT_SUFFIX_ONLY(trackpad, touch, XRT_INPUT_INDEX_TRACKPAD_TOUCH) MAKE_INPUT(grip, pose, XRT_INPUT_INDEX_GRIP_POSE) MAKE_INPUT(aim, pose, XRT_INPUT_INDEX_AIM_POSE) @@ -891,10 +952,9 @@ static struct binding_template htc_vive_controller_bindings[24] = { MAKE_INPUT(menu, click, XRT_INPUT_VIVE_MENU_CLICK) MAKE_INPUT(trigger, click, XRT_INPUT_VIVE_TRIGGER_CLICK) MAKE_INPUT(trigger, value, XRT_INPUT_VIVE_TRIGGER_VALUE) - MAKE_INPUT(trackpad, x, XRT_INPUT_VIVE_TRACKPAD_X) - MAKE_INPUT(trackpad, y, XRT_INPUT_VIVE_TRACKPAD_Y) - MAKE_INPUT(trackpad, click, XRT_INPUT_VIVE_TRACKPAD_CLICK) - MAKE_INPUT(trackpad, touch, XRT_INPUT_VIVE_TRACKPAD_TOUCH) + MAKE_INPUT_VEC2F(trackpad, XRT_INPUT_VIVE_TRACKPAD) + MAKE_INPUT_SUFFIX_ONLY(trackpad, click, XRT_INPUT_VIVE_TRACKPAD_CLICK) + MAKE_INPUT_SUFFIX_ONLY(trackpad, touch, XRT_INPUT_VIVE_TRACKPAD_TOUCH) MAKE_INPUT(grip, pose, XRT_INPUT_VIVE_GRIP_POSE) MAKE_INPUT(aim, pose, XRT_INPUT_VIVE_AIM_POSE) diff --git a/src/xrt/state_trackers/oxr/oxr_input.c b/src/xrt/state_trackers/oxr/oxr_input.c index 72ff63b3c..ce7cb8d8b 100644 --- a/src/xrt/state_trackers/oxr/oxr_input.c +++ b/src/xrt/state_trackers/oxr/oxr_input.c @@ -327,6 +327,54 @@ do_io_bindings(struct oxr_binding *b, return found; } +static bool +ends_with(const char *str, const char *suffix) +{ + int len = strlen(str); + int suffix_len = strlen(suffix); + + return (len >= suffix_len) && + (0 == strcmp(str + (len - suffix_len), suffix)); +} + +static void +oxr_source_cache_determine_redirect(struct oxr_logger *log, + struct oxr_session *sess, + struct oxr_action *act, + struct oxr_source_cache *cache, + XrPath bound_path) +{ + + cache->redirect = INPUT_REDIRECT_DEFAULT; + + struct oxr_source_input *input = &cache->inputs[0]; + if (input == NULL) + return; + + const char *str; + size_t length; + oxr_path_get_string(log, sess->sys->inst, bound_path, &str, &length); + + enum xrt_input_type t = XRT_GET_INPUT_TYPE(input->input->name); + + // trackpad/thumbstick data is kept in vec2f values. + // When a float action binds to ../trackpad/x or ../thumbstick/y, store + // the information which vec2f component to read. + if (act->action_type == XR_ACTION_TYPE_FLOAT_INPUT && + t == XRT_INPUT_TYPE_VEC2_MINUS_ONE_TO_ONE) { + if (ends_with(str, "/x")) { + cache->redirect = INPUT_REDIRECT_VEC2_X_TO_VEC1; + } else if (ends_with(str, "/y")) { + cache->redirect = INPUT_REDIRECT_VEC2_Y_TO_VEC1; + } else { + oxr_log(log, + "No rule to get float from vec2f for action " + "%s, binding %s\n", + act->name, str); + } + } +} + static void get_binding(struct oxr_logger *log, struct oxr_sink_logger *slog, @@ -337,7 +385,8 @@ get_binding(struct oxr_logger *log, struct oxr_source_input inputs[16], uint32_t *num_inputs, struct oxr_source_output outputs[16], - uint32_t *num_outputs) + uint32_t *num_outputs, + XrPath *bound_path) { struct xrt_device *xdev = NULL; struct oxr_binding *bindings[32]; @@ -400,8 +449,15 @@ get_binding(struct oxr_logger *log, const char *str = NULL; struct oxr_binding *b = bindings[i]; - // Just pick the first path. - oxr_path_get_string(log, sess->sys->inst, b->paths[0], &str, + // pick the path that the action prefers. + // e.g. an action bound to /user/hand/*/trackpad will prefer + // index 0 of those bindings, an action bound to + // /user/hand/*/trackpad will prefer index 1 + // [/user/hand/*/trackpad, /user/hand/*/trackpad/x] + + XrPath preferred_path = + b->paths[act->preferred_binding_path_index]; + oxr_path_get_string(log, sess->sys->inst, preferred_path, &str, &length); oxr_slog(slog, "\t\t\tBinding: %s\n", str); @@ -414,6 +470,7 @@ get_binding(struct oxr_logger *log, outputs, num_outputs); if (found) { + *bound_path = preferred_path; oxr_slog(slog, "\t\t\t\tBound!\n"); } else { oxr_slog(slog, "\t\t\t\tRejected! (NO XDEV MAPPING)\n"); @@ -812,8 +869,9 @@ oxr_source_bind_inputs(struct oxr_logger *log, struct oxr_source_output outputs[16] = {0}; uint32_t num_outputs = 0; + XrPath bound_path; get_binding(log, slog, sess, act, profile, sub_path, inputs, - &num_inputs, outputs, &num_outputs); + &num_inputs, outputs, &num_outputs, &bound_path); cache->current.active = false; @@ -836,6 +894,8 @@ oxr_source_bind_inputs(struct oxr_logger *log, } cache->num_outputs = num_outputs; } + + oxr_source_cache_determine_redirect(log, sess, act, cache, bound_path); } @@ -1018,7 +1078,8 @@ oxr_action_sync_data(struct oxr_logger *log, static void get_state_from_state_bool(struct oxr_source_state *state, - XrActionStateBoolean *data) + XrActionStateBoolean *data, + enum xrt_source_value_redirect redirect) { data->currentState = state->boolean; data->lastChangeTime = state->timestamp; @@ -1028,9 +1089,20 @@ get_state_from_state_bool(struct oxr_source_state *state, static void get_state_from_state_vec1(struct oxr_source_state *state, - XrActionStateFloat *data) + XrActionStateFloat *data, + enum xrt_source_value_redirect redirect) { - data->currentState = state->vec1.x; + switch (redirect) { + case INPUT_REDIRECT_VEC2_X_TO_VEC1: + data->currentState = state->vec2.x; + break; + case INPUT_REDIRECT_VEC2_Y_TO_VEC1: + data->currentState = state->vec2.y; + break; + case INPUT_REDIRECT_DEFAULT: + default: data->currentState = state->vec1.x; break; + } + data->lastChangeTime = state->timestamp; data->changedSinceLastSync = state->changed; data->isActive = XR_TRUE; @@ -1038,7 +1110,8 @@ get_state_from_state_vec1(struct oxr_source_state *state, static void get_state_from_state_vec2(struct oxr_source_state *state, - XrActionStateVector2f *data) + XrActionStateVector2f *data, + enum xrt_source_value_redirect redirect) { data->currentState.x = state->vec2.x; data->currentState.y = state->vec2.y; @@ -1049,22 +1122,28 @@ get_state_from_state_vec2(struct oxr_source_state *state, #define OXR_ACTION_GET_FILLER(TYPE) \ if (sub_paths.any && src->any_state.active) { \ - get_state_from_state_##TYPE(&src->any_state, data); \ + get_state_from_state_##TYPE(&src->any_state, data, \ + INPUT_REDIRECT_DEFAULT); \ } \ if (sub_paths.user && src->user.current.active) { \ - get_state_from_state_##TYPE(&src->user.current, data); \ + get_state_from_state_##TYPE(&src->user.current, data, \ + src->user.redirect); \ } \ if (sub_paths.head && src->head.current.active) { \ - get_state_from_state_##TYPE(&src->head.current, data); \ + get_state_from_state_##TYPE(&src->head.current, data, \ + src->head.redirect); \ } \ if (sub_paths.left && src->left.current.active) { \ - get_state_from_state_##TYPE(&src->left.current, data); \ + get_state_from_state_##TYPE(&src->left.current, data, \ + src->left.redirect); \ } \ if (sub_paths.right && src->right.current.active) { \ - get_state_from_state_##TYPE(&src->right.current, data); \ + get_state_from_state_##TYPE(&src->right.current, data, \ + src->right.redirect); \ } \ if (sub_paths.gamepad && src->gamepad.current.active) { \ - get_state_from_state_##TYPE(&src->gamepad.current, data); \ + get_state_from_state_##TYPE(&src->gamepad.current, data, \ + src->gamepad.redirect); \ } diff --git a/src/xrt/state_trackers/oxr/oxr_objects.h b/src/xrt/state_trackers/oxr/oxr_objects.h index 090923d56..4d609a183 100644 --- a/src/xrt/state_trackers/oxr/oxr_objects.h +++ b/src/xrt/state_trackers/oxr/oxr_objects.h @@ -1194,6 +1194,8 @@ struct oxr_source_cache int64_t stop_output_time; size_t num_outputs; struct oxr_source_output *outputs; + + enum xrt_source_value_redirect redirect; }; /*! @@ -1335,6 +1337,9 @@ struct oxr_action //! Which sub action paths that this action was created with. struct oxr_sub_paths sub_paths; + + //! Which of the paths in oxr_binding.paths matches this action. + uint32_t preferred_binding_path_index; }; /*!