mirror of
https://github.com/EyeTrackVR/EyeTrackVR.git
synced 2025-11-04 14:39:42 +08:00
Merge 4050b7df5a into b001b15ed8
This commit is contained in:
commit
925cc055ce
106
EyeTrackApp/OVR/OpenVRService.py
Normal file
106
EyeTrackApp/OVR/OpenVRService.py
Normal file
@ -0,0 +1,106 @@
|
||||
import openvr
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
from logging import getLogger, ERROR, WARN
|
||||
from config import EyeTrackConfig
|
||||
from eye import EyeId
|
||||
from colorama import Fore
|
||||
import PySimpleGUI as sg
|
||||
|
||||
class OpenVRException(Exception):
|
||||
pass
|
||||
|
||||
class OpenVRService:
|
||||
appKey: str = "etvr.etvrapp"
|
||||
manifest = {
|
||||
"source": "builtin",
|
||||
"applications": [
|
||||
{
|
||||
"app_key": appKey,
|
||||
"launch_type": "binary",
|
||||
"binary_path_windows": sys.executable,
|
||||
"is_dashboard_overlay": True,
|
||||
|
||||
"strings": {
|
||||
"en_us": {
|
||||
"name": "EyeTrackVR",
|
||||
"description": "EyeTrackVR allow translating a camera feed into face tracking datas."
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
manifestPath: str = os.path.abspath("app.vrmanifest")
|
||||
|
||||
# Write openvr manifest file
|
||||
def write_manifest() -> None:
|
||||
with open(OpenVRService.manifestPath, 'w') as f:
|
||||
json.dump(OpenVRService.manifest, f)
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.is_initialized: bool = False
|
||||
self.logger = getLogger(__name__)
|
||||
|
||||
# Initialize the openvr connection if it wasn't already
|
||||
def initialize(self):
|
||||
if self.is_initialized:
|
||||
return
|
||||
|
||||
try:
|
||||
openvr.init(openvr.VRApplication_Background)
|
||||
except openvr.error_code.InitError_Init_NoServerForBackgroundApp:
|
||||
raise OpenVRException("SteamVR is not running")
|
||||
except (openvr.error_code.InitError_Init_HmdNotFound,
|
||||
openvr.error_code.InitError_Init_HmdNotFoundPresenceFailed):
|
||||
raise OpenVRException("No headset connected")
|
||||
except openvr.error_code.InitError_Init_PathRegistryNotFound:
|
||||
raise OpenVRException("SteamVR might not be installed")
|
||||
except Exception as e:
|
||||
raise OpenVRException(f"Unknown SteamVR initialization error ({e.__class__.__name__})")
|
||||
|
||||
def set_autostart(self, enabled: bool):
|
||||
if enabled:
|
||||
self.initialize()
|
||||
|
||||
self.app = openvr.IVRApplications()
|
||||
# Write the manifest dynamically depending on current executable path
|
||||
OpenVRService.write_manifest()
|
||||
try:
|
||||
self.app.addApplicationManifest(OpenVRService.manifestPath)
|
||||
self.app.setApplicationAutoLaunch(OpenVRService.appKey, True)
|
||||
except openvr.error_code.ApplicationError_UnknownApplication:
|
||||
self.logger.log(ERROR, f"{Fore.RED}[ERROR] Could not register app in SteamVR")
|
||||
raise OpenVRException("Could not register SteamVR app")
|
||||
except Exception as e:
|
||||
raise OpenVRException(f"Unknown error enabling auto launch: {e.__class__.__name__}")
|
||||
else:
|
||||
if os.path.exists(OpenVRService.manifestPath):
|
||||
if self.initialize():
|
||||
try:
|
||||
self.app.removeApplicationManifest(OpenVRService.manifestPath)
|
||||
except openvr.error_code.ApplicationError_UnknownApplication:
|
||||
pass
|
||||
# App won't autostart if the manifest doesn't exit anymore when SteamVR starts.
|
||||
os.remove(OpenVRService.manifestPath)
|
||||
|
||||
|
||||
# Called when general settings get updated in case autostart option is modified
|
||||
def on_config_update(self, data):
|
||||
if "gui_openvr_autostart" in data:
|
||||
try:
|
||||
self.set_autostart(data["gui_openvr_autostart"])
|
||||
except OpenVRException as e:
|
||||
# Uncheck the autostart option if we failed to toggle it on
|
||||
self.window[f"-OPENVRAUTOSTART{EyeId.SETTINGS}-"].update(False)
|
||||
self.logger.log(WARN, f"{Fore.YELLOW}[WARN] Cannot enable steamvr autostart: {e.args[0]}")
|
||||
sg.popup_ok(
|
||||
f"Cannot enable steamvr autostart: {e.args[0]}",
|
||||
title="Warning",
|
||||
text_color="#ffae42",
|
||||
background_color="#292929"
|
||||
)
|
||||
|
||||
|
||||
openvr_service = OpenVRService()
|
||||
@ -217,6 +217,8 @@ class EyeTrackSettingsConfig(BaseModel):
|
||||
gui_OutputMultiplier: float = 1
|
||||
gui_use_module: bool = False
|
||||
|
||||
gui_openvr_autostart: bool = False
|
||||
|
||||
|
||||
class EyeTrackConfig(BaseModel):
|
||||
version: int = 1
|
||||
|
||||
@ -37,7 +37,8 @@ from settings.general_settings_widget import SettingsWidget
|
||||
from settings.algo_settings_widget import AlgoSettingsWidget
|
||||
from osc.osc import OSCManager
|
||||
from osc.OSCMessage import OSCMessage
|
||||
from utils.misc_utils import is_nt, resource_path
|
||||
from utils.misc_utils import is_nt, is_macos, resource_path
|
||||
|
||||
import cv2
|
||||
import numpy as np
|
||||
import uuid
|
||||
@ -226,6 +227,19 @@ def main():
|
||||
config.save()
|
||||
|
||||
cancellation_event = threading.Event()
|
||||
|
||||
# Start openvr service if autostart with openvr option is enabled
|
||||
# Allow the app to be closed when SteamVR closes
|
||||
if config.settings.gui_openvr_autostart and not is_macos:
|
||||
from OVR.OpenVRService import openvr_service, OpenVRException
|
||||
try:
|
||||
openvr_service.initialize()
|
||||
except OpenVRException:
|
||||
pass
|
||||
|
||||
config.register_listener_callback(openvr_service.on_config_update)
|
||||
|
||||
|
||||
# Check to see if we can connect to our video source first. If not, bring up camera finding
|
||||
# dialog.
|
||||
try:
|
||||
@ -284,6 +298,7 @@ def main():
|
||||
config.register_listener_callback(eyes[0].on_config_update)
|
||||
config.register_listener_callback(eyes[1].on_config_update)
|
||||
|
||||
|
||||
osc_manager.register_listeners(
|
||||
config.settings.gui_osc_recenter_address,
|
||||
[
|
||||
@ -332,7 +347,10 @@ def main():
|
||||
|
||||
# First off, check for any events from the GUI
|
||||
window = create_window(config, settings, eyes)
|
||||
|
||||
|
||||
# Allow openvr service to access the windows to dynamically update the settings (uncheck autostart box)
|
||||
if not is_macos:
|
||||
openvr_service.window = window
|
||||
|
||||
while True:
|
||||
event, values = window.read(timeout=tint) # this higher timeout saves some cpu usage
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
# -*- mode: python ; coding: utf-8 -*-
|
||||
|
||||
import sys ; sys.setrecursionlimit(sys.getrecursionlimit() * 5)
|
||||
import openvr
|
||||
|
||||
block_cipher = None
|
||||
|
||||
@ -9,7 +10,10 @@ resources=[("Audio/*", "Audio"), ("Images/*", "Images/"), ("pye3d/refraction_mod
|
||||
a = Analysis(
|
||||
['eyetrackapp.py'],
|
||||
pathex=[],
|
||||
binaries=[],
|
||||
binaries=[
|
||||
(os.path.abspath(openvr.__file__ + "\\..\\libopenvr_api_32.dll"), "openvr"),
|
||||
(os.path.abspath(openvr.__file__ + "\\..\\libopenvr_api_64.dll"), "openvr"),
|
||||
],
|
||||
datas=resources,
|
||||
hiddenimports=['cv2', 'numpy', 'PySimpleGui', 'pkg_resources.extern'],
|
||||
hookspath=[],
|
||||
|
||||
@ -12,6 +12,7 @@ class GeneralSettingsValidationModel(BaseValidationModel):
|
||||
gui_right_eye_dominant: bool
|
||||
gui_left_eye_dominant: bool
|
||||
gui_eye_dominant_diff_thresh: float
|
||||
gui_openvr_autostart: bool
|
||||
|
||||
|
||||
class GeneralSettingsModule(BaseSettingsModule):
|
||||
@ -26,6 +27,7 @@ class GeneralSettingsModule(BaseSettingsModule):
|
||||
self.gui_left_eye_dominant = f"-LEFTEYEDOMINANT{widget_id}-"
|
||||
self.gui_right_eye_dominant = f"-RIGHTEYEDOMINANT{widget_id}-"
|
||||
self.gui_update_check = f"-UPDATECHECK{widget_id}-"
|
||||
self.gui_openvr_autostart = f"-OPENVRAUTOSTART{widget_id}-"
|
||||
|
||||
# gui_right_eye_dominant: bool = False
|
||||
# gui_left_eye_dominant: bool = False
|
||||
@ -69,6 +71,15 @@ class GeneralSettingsModule(BaseSettingsModule):
|
||||
tooltip="Toggle update check on launch.",
|
||||
),
|
||||
],
|
||||
[
|
||||
sg.Checkbox(
|
||||
"Start and stop with SteamVR",
|
||||
default=self.config.gui_openvr_autostart,
|
||||
key=self.gui_openvr_autostart,
|
||||
background_color="#424042",
|
||||
tooltip="Start the EyeTrackVR app when SteamVR starts, Stop the EyeTrackVRApp when SteamVR stops. Needs SteamVR running to be enabled",
|
||||
),
|
||||
],
|
||||
[
|
||||
sg.Text("Eye Falloff Settings:", background_color="#242224"),
|
||||
],
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import os
|
||||
import typing
|
||||
import sys
|
||||
|
||||
from pathlib import Path
|
||||
from typing import Union
|
||||
|
||||
is_nt = True if os.name == "nt" else False
|
||||
is_macos = True if os.uname().sysname == "Darwin" else False
|
||||
|
||||
|
||||
def PlaySound(*args, **kwargs):
|
||||
|
||||
1258
poetry.lock
generated
1258
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
@ -20,6 +20,9 @@ pyserial = "^3.5"
|
||||
winotify = [
|
||||
{ version = "^1.1.0", platform = 'win32' }
|
||||
]
|
||||
openvr = [
|
||||
{ version = "^2.5.101", platform = 'win32' }
|
||||
]
|
||||
onnxruntime = "^1.13.1"
|
||||
colorama = "^0.4.6"
|
||||
taskipy = "^1.10.4"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user