From d3893c229f00a2f44b7d32f51abe29cc9a34bfec Mon Sep 17 00:00:00 2001 From: Mario Kleiner Date: Mon, 16 Jan 2023 22:21:25 +0100 Subject: [PATCH] aux/binding: Implement optional "steamvr_path" for SteamVR input bindings When using the Monado SteamVR driver plugin together with an Oculus Rift CV-1 and Oculus touch controllers, the grip / squeeze sensors (e.g., /user/hand/left/input/squeeze/value) and the thumbsticks did not work. This because SteamVR expects those controls to be exposed under a different path than what one would use for OpenXR, e.g., OpenXR /input/squeeze --> SteamVR /input/grip and OpenXR /input/thumbstick --> SteamVR /input/joystick The same is true for some other controller types. To fix this, add some new code for input subpath substitution, to perform this remapping, depending on binding type: For type "trigger": Substitute squeeze with grip For type "joystick": Substitute thumbstick with joystick For rare controller types where this would be the wrong thing to do, e.g., Valve Index (for type "joystick", needs the path to remain "thumbstick" as before), and for special cases not covered, we add a new optional parameter 'steamvr_path' which can be used in bindings.json to handle such mismatches in path flexibly to allow a dedicated path name for SteamVR, overriding the regular "OpenXR style" input path or auto-substituted path is if the parameter is omitted. This makes the Oculus Rift CV-1 touch controllers fully work under SteamVR. I haven't tested this with other controllers, as I only have Oculus controllers for testing atm. But after reading about the HTC Vive controllers, i did add a "steamvr_path" override for /input/menu -> /input/application_menu. Cfe. https://github.com/ValveSoftware/openvr/wiki/IVRDriverInput-Overview Also, a minor typo fix in steamvr_profiles.py as a bonus. Signed-off-by: Mario Kleiner --- src/xrt/auxiliary/bindings/bindings.json | 2 ++ src/xrt/auxiliary/bindings/bindings.py | 21 +++++++++++++++++-- .../auxiliary/bindings/steamvr_profiles.py | 12 ++--------- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/xrt/auxiliary/bindings/bindings.json b/src/xrt/auxiliary/bindings/bindings.json index a197d97b2..0000fc189 100644 --- a/src/xrt/auxiliary/bindings/bindings.json +++ b/src/xrt/auxiliary/bindings/bindings.json @@ -130,6 +130,7 @@ }, "/input/menu": { "type": "button", + "steamvr_path": "/input/application_menu", "localized_name": "Menu", "components": ["click"], "monado_bindings": { @@ -756,6 +757,7 @@ }, "/input/thumbstick": { "type": "joystick", + "steamvr_path": "/input/thumbstick", "localized_name": "Thumbstick", "components": ["click", "touch", "position"], "dpad_emulation": { diff --git a/src/xrt/auxiliary/bindings/bindings.py b/src/xrt/auxiliary/bindings/bindings.py index 49c7e0dfd..e15b3e239 100755 --- a/src/xrt/auxiliary/bindings/bindings.py +++ b/src/xrt/auxiliary/bindings/bindings.py @@ -19,6 +19,17 @@ def find_component_in_list_by_name(name, component_list, subaction_path=None, id return component return None +def steamvr_subpath_name(steamvr_path, subpath_type): + if subpath_type == "pose": + return steamvr_path.replace("/input/", "/pose/") + + if subpath_type == "trigger" or subpath_type == "button": + return steamvr_path.replace("squeeze", "grip") + + if subpath_type == "joystick": + return steamvr_path.replace("thumbstick", "joystick") + + return steamvr_path class PathsByLengthCollector: """Helper class to sort paths by length, useful for creating fast path @@ -119,8 +130,13 @@ class Component: if component_name in monado_bindings: monado_binding = monado_bindings[component_name] + steamvr_path = steamvr_subpath_name(identifier_json_path, json_subpath["type"]) + if "steamvr_path" in json_subpath: + steamvr_path = json_subpath["steamvr_path"] + c = Component(subaction_path, identifier_json_path, + steamvr_path, json_subpath["localized_name"], json_subpath["type"], component_name, @@ -134,6 +150,7 @@ class Component: def __init__(self, subaction_path, identifier_json_path, + steamvr_path, subpath_localized_name, subpath_type, component_name, @@ -142,6 +159,7 @@ class Component: components_for_subpath): self.subaction_path = subaction_path self.identifier_json_path = identifier_json_path # note: starts with a slash + self.steamvr_path = steamvr_path self.subpath_localized_name = subpath_localized_name self.subpath_type = subpath_type self.component_name = component_name @@ -382,8 +400,7 @@ def generate_bindings_c(file, p): component: Component for idx, component in enumerate(profile.components): - json_path = component.identifier_json_path - steamvr_path = json_path # @todo Doesn't handle pose yet. + steamvr_path = component.steamvr_path # @todo Doesn't handle pose yet. if component.component_name in ["click", "touch", "force", "value"]: steamvr_path += "/" + component.component_name diff --git a/src/xrt/auxiliary/bindings/steamvr_profiles.py b/src/xrt/auxiliary/bindings/steamvr_profiles.py index 6ccc6df51..373f09e6b 100644 --- a/src/xrt/auxiliary/bindings/steamvr_profiles.py +++ b/src/xrt/auxiliary/bindings/steamvr_profiles.py @@ -33,14 +33,6 @@ def open_file(args, fname): f = open(fname, "w") return f - -def steamvr_subpath_name(component): - if component.subpath_type == "pose": - return component.identifier_json_path.replace("/input/", "/pose/") - - return component.identifier_json_path - - def get_required_components(path_type): if path_type == "button": return ["click", "touch"] @@ -81,7 +73,7 @@ def main(): component: Component for idx, component in enumerate(p.components): - subpath_name = steamvr_subpath_name(component) + subpath_name = component.steamvr_path input_source[subpath_name] = { "type": component.subpath_type, @@ -100,7 +92,7 @@ def main(): "driver_name": "monado", # "legacy_binding": None, # TODO "input_bindingui_mode": "controller_handed", - "should_show_binidng_errors": True, + "should_show_binding_errors": True, "input_bindingui_left": { "image": "{indexcontroller}/icons/indexcontroller_left.svg" # TODO }, -- 2.51.2