Professional Documents
Culture Documents
Ric's Half-Life Alyx FreePIE ALVR Script - Py
Ric's Half-Life Alyx FreePIE ALVR Script - Py
py
# ===========================================
#
# You can use an Oculus Go VR headseat to play Half-Life: Alyx on your PC.
# You will need to install some free software, including ALVR and FreePIE.
# This FreePIE script allows / help you play the game by binding specific
# game actions to the Oculus Go controller and your PC keyboard.
# Optionally, you can use a Gear VR controller instead of the keyboard.
# More details at https://github.com/AltoRetrato/Half-Life_Alyx_on_Oculus_Go
#
# 2020.05.23 - Fixed bug that didn't allow head position to change in fly mode.
# 2020.04.18 - Added support for the Gear VR (and maybe Daydream?) controller with
FreePIEVRController;
# Download DLL plugin at
https://github.com/polygraphene/FreePIEVRController/releases
# 2020.04.02 - 2nd release, flick of the wrist solved with new driver;
# reduced flight speed for better aiming, use single controller by
default.
# 2020.03.27 - [WIP] 1st release, still can't trigger a flick of the wrist
# Don't change the code below if you don't know what you are doing.
# conjugate quaternion
def conj(q):
return [-q[0], -q[1], -q[2], q[3]]
# multiplication of quaternion
def multiply(a, b):
x0, y0, z0, w0 = a
x1, y1, z1, w1 = b
return [x1 * w0 - y1 * z0 + z1 * y0 + w1 * x0,
x1 * z0 + y1 * w0 - z1 * x0 + w1 * y0,
-x1 * y0 + y1 * x0 + z1 * w0 + w1 * z0,
-x1 * x0 - y1 * y0 - z1 * z0 + w1 * w0]
return yaw_pitch_roll
if starting:
prev_back = False
mode = 0
modeName = ["0: default", "1: fly", "2: trackpad gesture"]
offset = [0.0, 0.0, 0.0]
offset2 = [0.0, 0.0, 0.0]
message_time = 0.0
controller = 0
controller_pos = [0.0, 0.0, 0.0]
for i in range(3):
alvr.controller_position[controller][i] = alvr.input_controller_position[i]
gearvr = "vrcontroller" in globals()
if not gearvr:
diagnostics.debug("Gear VR controller plugin not found!")
diagnostics.debug("Be sure to move the FreePIEVRController.dll file into the
FreePIE plugins folder")
diagnostics.debug('then right-click the file, select Properties and check
"Unblock".')
else:
diagnostics.debug("Gear VR controller plugin found.")
if not hasattr(vrcontroller[0], 'BUTTONS'):
diagnostics.debug("Gear VR controller not found. Is Bluetooth on your
computer turned on?")
gearvr = False
if gearvr:
gearvr_last_trigger = False
if gearvr:
gearvr_trigger = vrcontroller[0].trigger
for k in key_map:
alvr.buttons[controller][alvr.Id(k[0])] = keyboard.getKeyDown(k[1])
trigger_on = alvr.buttons[controller][alvr.Id("trigger")] or
alvr.input_buttons[alvr.InputId("trigger")]
if mode == 2:
# trackpad guesture mode
alvr.buttons[controller][alvr.Id("trigger")] = trigger_on
#alvr.buttons[controller][alvr.Id("application_menu")] = alvr.buttons[controller]
[alvr.Id("application_menu")] or alvr.input_buttons[alvr.InputId("back")]
if alvr.input_buttons[alvr.InputId("trackpad_click")]:
if alvr.input_trackpad[0] + alvr.input_trackpad[1] > 0.0:
if alvr.input_trackpad[0] - alvr.input_trackpad[1] > 0.0:
# right
alvr.buttons[controller][alvr.Id("system")] = True
else:
# top
alvr.buttons[controller][alvr.Id("trackpad_click")] = True
alvr.buttons[controller][alvr.Id("trackpad_touch")] = True
else:
if alvr.input_trackpad[0] - alvr.input_trackpad[1] > 0.0:
# bottom
alvr.buttons[controller][alvr.Id("grip")] = True
else:
# left
alvr.buttons[controller][alvr.Id("application_menu")] = True
elif mode == 1:
# fly mode
# press upper half of trackpad to move forward. bottom half to move back
if alvr.input_buttons[alvr.InputId("trackpad_click")]:
#if alvr.input_buttons[alvr.InputId("trigger")] and alvr.input_trackpad[0] -
alvr.input_trackpad[1] > 0.0:
# offset = [0.0, 0.0, 0.0]
#else:
outvec = rotatevec(alvr.input_controller_orientation, [0, 0, -1, 0])
speed = flight_speed * sign(alvr.input_trackpad[1])
if keyboard.getKeyDown(speed_toggle_key) or (gearvr and
vrcontroller[0].click):
speed = speed * speed_multiplier
for i in range(3):
offset[i] += speed * outvec[i]
alvr.buttons[controller][alvr.Id("trigger")] = trigger_on
elif mode == 0:
# passthrough mode
alvr.buttons[controller][alvr.Id("trackpad_click")] = alvr.buttons[controller]
[alvr.Id("trackpad_click")] or alvr.input_buttons[alvr.InputId("trackpad_click")]
alvr.buttons[controller][alvr.Id("trackpad_touch")] = alvr.buttons[controller]
[alvr.Id("trackpad_touch")] or alvr.input_buttons[alvr.InputId("trackpad_touch")]
alvr.buttons[controller][alvr.Id("trigger")] = trigger_on
alvr.trackpad[controller][0] = alvr.input_trackpad[0]
alvr.trackpad[controller][1] = alvr.input_trackpad[1]
# You need to set trigger value correctly to get trigger click work
alvr.trigger[controller] = 1.0 if alvr.buttons[controller][alvr.Id("trigger")] else
0.0
# Use Gear VR controller vol. up / down buttons to displace hand position as well,
even outside of fly mode.
if gearvr and (vrcontroller[0].volup or vrcontroller[0].voldown):
outvec = rotatevec(alvr.input_controller_orientation, [0, 0, -1, 0])
speed = -flight_speed if vrcontroller[0].voldown else flight_speed
for i in range(3):
offset2[i] += speed * outvec[i]
alvr.override_head_position = True
alvr.override_controller_position = True
alvr.override_controller_orientation = True
for i in range(3):
if keyboard.getKeyDown(mode_toggle_key) or (gearvr and gearvr_trigger):
alvr.head_position[i] = alvr.input_head_position[i] + offset[i] # + offset2[i]
#alvr.controller_position[controller][i] = alvr.input_controller_position[i] +
offset[i] + offset2[i]
alvr.controller_orientation[controller][i] = alvr.input_controller_orientation[i]
if False: #trigger_on:
# We need to change Y and Z axes
if False:
hw = 0.15 # estimated "hand width", from finger to wrist, in meters
r = 0.15 # estimated radius from axis used by ALVR to rotate the controller,
in meters
hhw = hw / 2.0
pitch = alvr.input_controller_orientation[2] # in radians. Doc says
[yaw,pitch,roll], though...
y1 = (r + hhw) * math.sin(pitch)
z1 = (r + hhw) * math.cos(pitch)
y2 = hhw * math.sin(pitch)
z2 = r + hw + hhw*math.cos(pitch+math.pi)
diagnostics.watch(pitch); diagnostics.watch(y1);diagnostics.watch(z1);
diagnostics.watch(y2);diagnostics.watch(z2)
alvr.controller_position[controller][0] = controller_pos[0] + offset[0]
alvr.controller_position[controller][1] = controller_pos[1] + offset[1] + y1 +
y2
alvr.controller_position[controller][2] = controller_pos[2] + offset[2] +
(r+hhw -z1) + z2
else:
for i in range(3):
alvr.controller_position[controller][i] = controller_pos[i] + offset[i] +
offset2[i]
controller_pos[i] = alvr.input_controller_position[i]
# Button remapping:
alvr.buttons[controller][alvr.Id(BACK_BUTTON_BINDING)] =
alvr.input_buttons[alvr.InputId("back")]
if gearvr:
gearvr_last_trigger = gearvr_trigger
if not True:
# watch variables on FreePIE debugger
diagnostics.watch(alvr.input_head_orientation[0])
diagnostics.watch(alvr.input_head_orientation[1])
diagnostics.watch(alvr.input_head_orientation[2])
diagnostics.watch(alvr.input_controller_orientation[0])
diagnostics.watch(alvr.input_controller_orientation[1])
diagnostics.watch(alvr.input_controller_orientation[2])
diagnostics.watch(alvr.input_head_position[0])
diagnostics.watch(alvr.input_head_position[1])
diagnostics.watch(alvr.input_head_position[2])
diagnostics.watch(alvr.input_controller_position[0])
diagnostics.watch(alvr.input_controller_position[1])
diagnostics.watch(alvr.input_controller_position[2])
diagnostics.watch(alvr.input_trackpad[0])
diagnostics.watch(alvr.input_trackpad[1])
diagnostics.watch(alvr.input_buttons[0])
diagnostics.watch(alvr.input_buttons[1])
diagnostics.watch(alvr.input_buttons[2])
diagnostics.watch(alvr.input_buttons[3])
diagnostics.watch(alvr.input_buttons[4])
diagnostics.watch(alvr.input_buttons[5])
diagnostics.watch(alvr.head_position[0])
diagnostics.watch(alvr.head_position[1])
diagnostics.watch(alvr.head_position[2])