diff options
Diffstat (limited to 'Scripts/steamvr.py')
| -rw-r--r-- | Scripts/steamvr.py | 156 |
1 files changed, 66 insertions, 90 deletions
diff --git a/Scripts/steamvr.py b/Scripts/steamvr.py index 0f241ca..e0b59e3 100644 --- a/Scripts/steamvr.py +++ b/Scripts/steamvr.py @@ -1,109 +1,85 @@ -import openvr +#!/usr/bin/env python3 + +# python3 -m pip install openvr +# License: BSD-3.0 (requires showing notice in binary distributions) +import openvr as vr import sys import time -import typing -EVENT_RISING_EDGE = 0 -EVENT_FALLING_EDGE = 1 -EVENT_POSE = 2 +EVENT_NONE = 0 +EVENT_RISING_EDGE = 1 +EVENT_FALLING_EDGE = 2 class InputEvent: def __init__(self, - opcode: int, - pos: typing.Tuple[float,float,float] = None): + opcode: int): self.opcode = opcode - self.pos = pos - 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}" +# Checks if the given button on the given controller is pressed. +def pollButtonPress( + hand: str = "right", + button: str = "b", + ) -> int: + hands = {} + hands["left"] = vr.TrackedControllerRole_LeftHand + hands["right"] = vr.TrackedControllerRole_RightHand -def pollButtonPress(hand: str = "right", button: str = "b") -> InputEvent: - openvr.init(openvr.VRApplication_Overlay) + buttons = {} + buttons["a"] = vr.k_EButton_IndexController_A + buttons["b"] = vr.k_EButton_IndexController_B + buttons["thumbstick"] = vr.k_EButton_Axis0 - system = openvr.VRSystem() + system = None + while not system: + try: + system = vr.init(vr.VRApplication_Background) + except Exception as e: + print(f"Failed to start steamVR input thread: {repr(e)}", file=sys.stderr) + time.sleep(5) + last_packet = 0 + event_high = False - button_mapping = { - 'a': k_EButton_Index_Controller_A, - 'b': k_EButton_Index_Controller_B, - 'thumbstick': k_EButton_SteamVR_Touchpad, - } + while True: + time.sleep(0.01) - print("SteamVR session created. Listening for controller input...") + lh_idx = system.getTrackedDeviceIndexForControllerRole(hand_id) + #print("left hand device idx: {}".format(lh_idx)) - 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) + got_state, state = system.getControllerState(lh_idx) + if not got_state: + continue - # Max out a 100 Hz. - time.sleep(0.01) + if state.unPacketNum == last_packet: + continue - openvr.shutdown() + # Clicking joysticks and moving joysticks fire the same events. To + # differentiate movement from clicking, we create a dead zone: if the event + # fires while the stick isn't moved far from center, we assume it's a + # click, not movement. + dead_zone_radius = 0.7 -if __name__ == "__main__": - if len(sys.argv) != 3: - print("Usage: script_name.py [left|right] [a|b|thumbstick]") - sys.exit(1) + button_mask = (1 << button_id) + ret = EVENT_NONE + if (state.ulButtonPressed & button_mask) != 0 and\ + (state.rAxis[0].x**2 + state.rAxis[0].y**2 < dead_zone_radius**2): + #print("button pressed: %016x" % state.ulButtonPressed) + #for i in range(0, 5): + # print("axis {} x: {} y: {}".format(i, state.rAxis[i].x, state.rAxis[i].y)) + if not event_high: + yield InputEvent(EVENT_RISING_EDGE) + event_high = True + elif event_high: + event_high = False + yield InputEvent(EVENT_FALLING_EDGE) - hand = sys.argv[1] - button = sys.argv[2] - gen = pollButtonPress(hand, button) +if __name__ == "__main__": + gen = pollButtonPress() while True: - print(next(gen)) + time.sleep(0.1) + + event = pollButtonPress(session_state, hand_id = hands["left"], button_id = buttons["joystick"]) + if event == EVENT_RISING_EDGE: + print("rising edge") + elif event == EVENT_FALLING_EDGE: + print("falling edge") |
