summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2023-08-28 20:09:35 -0700
committeryum <yum.food.vr@gmail.com>2023-08-28 20:09:35 -0700
commit2daa2c8057cf036357a64e09925487e6f5c0025e (patch)
tree226e7be8da04ed8ceea186ebcfae0551e9d14b77
parent302f7ba09f2ee115d0ee4b8f0841f6ffcd50ec57 (diff)
Switch back to openvr
openxr doesn't have any notion of background process, making it unusable trash :)
-rw-r--r--Scripts/requirements.txt2
-rw-r--r--Scripts/steamvr.py180
-rw-r--r--Scripts/transcribe.py4
3 files changed, 98 insertions, 88 deletions
diff --git a/Scripts/requirements.txt b/Scripts/requirements.txt
index 3a2cf42..8989ed1 100644
--- a/Scripts/requirements.txt
+++ b/Scripts/requirements.txt
@@ -5,7 +5,7 @@ future==0.18.2
keyboard
langcodes
language-data
-pyopenxr
+openvr
pillow
pyaudio
python-osc
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))
diff --git a/Scripts/transcribe.py b/Scripts/transcribe.py
index 4b00bd0..5301b0b 100644
--- a/Scripts/transcribe.py
+++ b/Scripts/transcribe.py
@@ -616,7 +616,7 @@ def readControllerInput(audio_state, enable_local_beep: bool,
time.sleep(0.01)
event = next(button_generator)
- if event == steamvr.EVENT_RISING_EDGE:
+ if event.opcode == steamvr.EVENT_RISING_EDGE:
last_rising = time.time()
if state == PAUSE_STATE:
@@ -625,7 +625,7 @@ def readControllerInput(audio_state, enable_local_beep: bool,
audio_state.drop_transcription = True
audio_state.audio_paused = False
- elif event == steamvr.EVENT_FALLING_EDGE:
+ elif event.opcode == steamvr.EVENT_FALLING_EDGE:
now = time.time()
if now - last_rising > 1.5:
# Long press: treat as the end of transcription.