diff options
| author | yum <yum.food.vr@gmail.com> | 2023-08-28 20:09:35 -0700 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2023-08-28 20:09:35 -0700 |
| commit | 2daa2c8057cf036357a64e09925487e6f5c0025e (patch) | |
| tree | 226e7be8da04ed8ceea186ebcfae0551e9d14b77 /Scripts/steamvr.py | |
| parent | 302f7ba09f2ee115d0ee4b8f0841f6ffcd50ec57 (diff) | |
Switch back to openvr
openxr doesn't have any notion of background process, making it unusable
trash :)
Diffstat (limited to 'Scripts/steamvr.py')
| -rw-r--r-- | Scripts/steamvr.py | 180 |
1 files changed, 95 insertions, 85 deletions
diff --git a/Scripts/steamvr.py b/Scripts/steamvr.py index df8f422..0f241ca 100644 --- a/Scripts/steamvr.py +++ b/Scripts/steamvr.py @@ -1,99 +1,109 @@ -import ctypes +import openvr +import sys import time -import xr +import typing -EVENT_NONE = 0 -EVENT_RISING_EDGE = 1 -EVENT_FALLING_EDGE = 2 +EVENT_RISING_EDGE = 0 +EVENT_FALLING_EDGE = 1 +EVENT_POSE = 2 -# hand: either "right" or "left" -# button: either "a" or "b" -def pollButtonPress(hand: str = "right", button: str = "b") -> int: - # ContextObject is a high level pythonic class meant to keep simple cases simple. - with xr.ContextObject( - instance_create_info=xr.InstanceCreateInfo( - enabled_extension_names=[ - xr.KHR_OPENGL_ENABLE_EXTENSION_NAME, # A graphics extension is mandatory - ], - ), - ) as context: - controller_path_str = f"/user/hand/{hand}" - binding_path_str = f"/user/hand/{hand}/input/{button}/click" - print(f"Controller path: {controller_path_str}") - print(f"Binding path: {binding_path_str}") +class InputEvent: + def __init__(self, + opcode: int, + pos: typing.Tuple[float,float,float] = None): + self.opcode = opcode + self.pos = pos - # Set up the B button action - controller_paths = (xr.Path * 1)( - xr.string_to_path(context.instance, controller_path_str,) - ) - b_button_action = xr.create_action( - action_set=context.default_action_set, - create_info=xr.ActionCreateInfo( - action_type=xr.ActionType.BOOLEAN_INPUT, - action_name="tastt_button_press", - localized_action_name="TaSTT Button Press", - count_subaction_paths=len(controller_paths), - subaction_paths=controller_paths, - ), - ) - suggested_bindings = (xr.ActionSuggestedBinding * 1)( - xr.ActionSuggestedBinding( - action=b_button_action, - binding=xr.string_to_path( - instance=context.instance, - path_string=binding_path_str, - ), - ), - ) - xr.suggest_interaction_profile_bindings( - instance=context.instance, - suggested_bindings=xr.InteractionProfileSuggestedBinding( - interaction_profile=xr.string_to_path( - context.instance, - "/interaction_profiles/valve/index_controller", - ), - count_suggested_bindings=len(suggested_bindings), - suggested_bindings=suggested_bindings, - ), - ) + def __str__(self): + if self.opcode == EVENT_RISING_EDGE: + return "EVENT_RISING_EDGE" + elif self.opcode == EVENT_FALLING_EDGE: + return "EVENT_FALLING_EDGE" + elif self.opcode == EVENT_POSE: + return f"EVENT_POSE: {self.pos}" - last_change_time = 0 - for frame_index, frame_state in enumerate(context.frame_loop()): - if context.session_state != xr.SessionState.FOCUSED: - yield EVENT_NONE - continue +def pollButtonPress(hand: str = "right", button: str = "b") -> InputEvent: + openvr.init(openvr.VRApplication_Overlay) - active_action_set = xr.ActiveActionSet( - action_set=context.default_action_set, - subaction_path=xr.NULL_PATH, - ) - xr.sync_actions( - session=context.session, - sync_info=xr.ActionsSyncInfo( - count_active_action_sets=1, - active_action_sets=ctypes.pointer(active_action_set), - ), - ) + system = openvr.VRSystem() - action_info = xr.ActionStateGetInfo(action=b_button_action) - action_bool = xr.get_action_state_boolean( - session=context.session, get_info=action_info - ) + button_mapping = { + 'a': k_EButton_Index_Controller_A, + 'b': k_EButton_Index_Controller_B, + 'thumbstick': k_EButton_SteamVR_Touchpad, + } - if action_bool.changed_since_last_sync == 0: - yield EVENT_NONE - continue + print("SteamVR session created. Listening for controller input...") - if action_bool.current_state == 1: - yield EVENT_RISING_EDGE - continue - else: - yield EVENT_FALLING_EDGE + while True: + # Drain input events. + event = openvr.VREvent_t() + while system.pollNextEvent(event): + # Event processing, e.g. button presses, goes here + if event.eventType == openvr.VREvent_ButtonPress or \ + event.eventType == openvr.VREvent_ButtonUnpress: + print(f"event.data.controller.button: {event.data.controller.button}") continue + print(f"event: {dir(event)}") + print(f"event.data: {dir(event.data)}") + print(f"event.data.controller: {dir(event.data.controller)}") + print(f"event.data.controller.button: {event.data.controller.button}") + print(f"event.data.keyboard: {dir(event.data.keyboard)}") + print(f"event.data.keyboard.cNewInput: {int.from_bytes(event.data.keyboard.cNewInput, byteorder='little')}") + print(f"event.data.keyboard.uUserValue: {event.data.keyboard.uUserValue}") + print(f"event.data.mouse: {dir(event.data.mouse)}") + print(f"event.data.mouse.button: {event.data.mouse.button}") + print(f"event.data.touchPadMove: {dir(event.data.touchPadMove)}") + print(f"event.data.touchPadMove.bFingerDown: {event.data.touchPadMove.bFingerDown}") + is_rising = event.eventType == openvr.VREvent_ButtonPress + # Check if the intended button is pressed + if button == 'thumbstick': + _, controller_state = system.getControllerState(event.trackedDeviceIndex) + mouse_x = controller_state.rAxis[0].x + mouse_y = controller_state.rAxis[0].y + print(f"mouse x/y: {mouse_x}/{mouse_y}") + print(f"mouse rad: {mouse_x**2 + mouse_y**2}") + dead_zone_radius = 0.05 + thumbstick_moved = mouse_x**2 + mouse_y**2 > dead_zone_radius**2 + if event.data.controller.button == button_mapping['thumbstick'] and not thumbstick_moved: + if is_rising: + yield InputEvent(EVENT_RISING_EDGE) + else: + yield InputEvent(EVENT_FALLING_EDGE) + elif event.data.controller.button == button_mapping[button]: + if is_rising: + yield InputEvent(EVENT_RISING_EDGE) + else: + yield InputEvent(EVENT_FALLING_EDGE) + # Check poses. + # TODO(yum) use this. Thinking about adding gestures: swipe to scale + # up/down, etc. + if False: + poses = (openvr.TrackedDevicePose_t * openvr.k_unMaxTrackedDeviceCount)() + system.getDeviceToAbsoluteTrackingPose(openvr.TrackingUniverseStanding, 0, poses) + pose = None + for i in range(openvr.k_unMaxTrackedDeviceCount): + if system.getControllerRoleForTrackedDeviceIndex(i) == openvr.TrackedControllerRole_RightHand: + pose = poses[i] + if pose and pose.bPoseIsValid: + position = pose.mDeviceToAbsoluteTracking.m[0][3], \ + pose.mDeviceToAbsoluteTracking.m[1][3], \ + pose.mDeviceToAbsoluteTracking.m[2][3] + yield InputEvent(EVENT_POSE, pos=position) + + # Max out a 100 Hz. + time.sleep(0.01) + + openvr.shutdown() if __name__ == "__main__": - gen = run() + if len(sys.argv) != 3: + print("Usage: script_name.py [left|right] [a|b|thumbstick]") + sys.exit(1) + + hand = sys.argv[1] + button = sys.argv[2] + gen = pollButtonPress(hand, button) while True: - event = next(gen) - print(f"event: {event}") + print(next(gen)) |
