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 <mario.kleiner.de@gmail.com>
This commit is contained in:
Mario Kleiner 2023-01-16 22:21:25 +01:00 committed by Christoph Haag
parent 50f7b5ba5f
commit d3893c229f
3 changed files with 23 additions and 12 deletions

View file

@ -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": {

View file

@ -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

View file

@ -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
},