mirror of
https://github.com/EyeTrackVR/EyeTrackVR.git
synced 2025-11-04 14:39:42 +08:00
Merge pull request #103 from lorow/fix/fix-v2-params
Fix: fix v2 params behaving not correctly
This commit is contained in:
commit
f5354ff1e3
6
.coveragerc
Normal file
6
.coveragerc
Normal file
@ -0,0 +1,6 @@
|
||||
[run]
|
||||
omit=
|
||||
tests/*
|
||||
conftest.py
|
||||
source =
|
||||
EyeTrackApp
|
||||
0
EyeTrackApp/__init__.py
Normal file
0
EyeTrackApp/__init__.py
Normal file
@ -1,12 +1,10 @@
|
||||
import json
|
||||
import os.path
|
||||
import shutil
|
||||
from eye import EyeId
|
||||
from EyeTrackApp.eye import EyeId
|
||||
from pydantic import BaseModel
|
||||
from typing import Union, List
|
||||
import psutil, os
|
||||
import sys
|
||||
|
||||
import os
|
||||
|
||||
|
||||
CONFIG_FILE_NAME: str = "eyetrack_settings.json"
|
||||
@ -30,7 +28,6 @@ class EyeTrackCameraConfig(BaseModel):
|
||||
calibration_points: List[List[Union[float, None]]] = []
|
||||
|
||||
|
||||
|
||||
class EyeTrackSettingsConfig(BaseModel):
|
||||
gui_flip_x_axis_left: bool = False
|
||||
gui_flip_x_axis_right: bool = False
|
||||
|
||||
@ -1,13 +1,12 @@
|
||||
from pythonosc import udp_client
|
||||
from pythonosc import osc_server
|
||||
from pythonosc import dispatcher
|
||||
from config import EyeTrackConfig
|
||||
from utils.misc_utils import PlaySound, SND_FILENAME, SND_ASYNC
|
||||
from EyeTrackApp.config import EyeTrackConfig
|
||||
from EyeTrackApp.utils.misc_utils import PlaySound, SND_FILENAME, SND_ASYNC
|
||||
from enum import IntEnum
|
||||
import queue
|
||||
import threading
|
||||
from enum import IntEnum
|
||||
import time
|
||||
import numpy as np
|
||||
|
||||
|
||||
class EyeId(IntEnum):
|
||||
@ -30,13 +29,8 @@ falloff = False
|
||||
|
||||
|
||||
def output_osc(eye_x, eye_y, eye_blink, last_blink, pupil_dilation, avg_velocity, self):
|
||||
# print(pupil_dilation)
|
||||
global se, falloff
|
||||
|
||||
# self.config.gui_osc_vrcft_v2
|
||||
# self.config.gui_osc_vrcft_v1
|
||||
# self.config.gui_vrc_native
|
||||
|
||||
if self.config.gui_osc_vrcft_v1:
|
||||
|
||||
if self.main_config.eye_display_id in [
|
||||
@ -48,9 +42,6 @@ def output_osc(eye_x, eye_y, eye_blink, last_blink, pupil_dilation, avg_velocity
|
||||
self.client.send_message(self.config.osc_left_eye_x_address, eye_x)
|
||||
self.client.send_message(self.config.osc_right_eye_x_address, eye_x)
|
||||
self.client.send_message(self.config.osc_eyes_y_address, eye_y)
|
||||
|
||||
self.config.osc_left_eye_close_address
|
||||
|
||||
self.client.send_message(
|
||||
self.config.osc_right_eye_close_address,
|
||||
eyelid_transformer(self, eye_blink),
|
||||
@ -68,9 +59,7 @@ def output_osc(eye_x, eye_y, eye_blink, last_blink, pupil_dilation, avg_velocity
|
||||
self.l_eye_velocity = avg_velocity
|
||||
|
||||
if self.l_eye_blink == 0.0:
|
||||
if (
|
||||
last_blink > 0.15
|
||||
): # when binary blink is on, blinks may be too fast for OSC so we repeat them.
|
||||
if last_blink > 0.15: # when binary blink is on, blinks may be too fast for OSC so we repeat them.
|
||||
for i in range(4):
|
||||
self.client.send_message(
|
||||
self.config.osc_left_eye_close_address,
|
||||
@ -94,9 +83,7 @@ def output_osc(eye_x, eye_y, eye_blink, last_blink, pupil_dilation, avg_velocity
|
||||
self.l_eye_velocity = avg_velocity
|
||||
|
||||
if self.r_eye_blink == 0.0:
|
||||
if (
|
||||
last_blink > 0.15
|
||||
): # when binary blink is on, blinks may be too fast for OSC so we repeat them.
|
||||
if last_blink > 0.15: # when binary blink is on, blinks may be too fast for OSC so we repeat them.
|
||||
# print("REPEATING R BLINK")
|
||||
for i in range(4):
|
||||
self.client.send_message(
|
||||
@ -105,9 +92,7 @@ def output_osc(eye_x, eye_y, eye_blink, last_blink, pupil_dilation, avg_velocity
|
||||
)
|
||||
last_blink = time.time() - last_blink
|
||||
if self.config.gui_outer_side_falloff:
|
||||
if (
|
||||
self.l_eye_blink == 0.0
|
||||
): # if both eyes closed and DEF is enables, blink
|
||||
if self.l_eye_blink == 0.0: # if both eyes closed and DEF is enables, blink
|
||||
self.client.send_message(
|
||||
self.config.osc_left_eye_close_address,
|
||||
eyelid_transformer(self, self.r_eye_blink),
|
||||
@ -127,11 +112,7 @@ def output_osc(eye_x, eye_y, eye_blink, last_blink, pupil_dilation, avg_velocity
|
||||
eyelid_transformer(self, self.r_eye_blink),
|
||||
)
|
||||
|
||||
if (
|
||||
self.main_config.eye_display_id in [EyeId.BOTH]
|
||||
and self.right_y != 621
|
||||
and self.left_y != 621
|
||||
):
|
||||
if self.main_config.eye_display_id in [EyeId.BOTH] and self.right_y != 621 and self.left_y != 621:
|
||||
y = (self.right_y + self.left_y) / 2
|
||||
self.client.send_message(self.config.osc_eyes_y_address, y)
|
||||
|
||||
@ -144,10 +125,7 @@ def output_osc(eye_x, eye_y, eye_blink, last_blink, pupil_dilation, avg_velocity
|
||||
se = True
|
||||
|
||||
self.client.send_message("/avatar/parameters/v2/EyeX", eye_x)
|
||||
self.client.send_message("/avatar/parameters/v2/EyeLeftX", eye_x)
|
||||
self.client.send_message("/avatar/parameters/v2/EyeRightX", eye_x)
|
||||
self.client.send_message("/avatar/parameters/v2/EyeLeftY", eye_y)
|
||||
self.client.send_message("/avatar/parameters/v2/EyeRightY", eye_y)
|
||||
self.client.send_message("/avatar/parameters/v2/EyeY", eye_y)
|
||||
self.client.send_message(
|
||||
"/avatar/parameters/v2/EyeLid",
|
||||
eyelid_transformer(self, eye_blink),
|
||||
@ -161,9 +139,7 @@ def output_osc(eye_x, eye_y, eye_blink, last_blink, pupil_dilation, avg_velocity
|
||||
self.r_eye_velocity = avg_velocity
|
||||
|
||||
if self.l_eye_blink == 0.0:
|
||||
if (
|
||||
last_blink > 0.15
|
||||
): # when binary blink is on, blinks may be too fast for OSC so we repeat them.
|
||||
if last_blink > 0.15: # when binary blink is on, blinks may be too fast for OSC so we repeat them.
|
||||
for i in range(4):
|
||||
self.client.send_message(
|
||||
"/avatar/parameters/v2/EyeLidLeft",
|
||||
@ -171,9 +147,7 @@ def output_osc(eye_x, eye_y, eye_blink, last_blink, pupil_dilation, avg_velocity
|
||||
)
|
||||
last_blink = time.time() - last_blink
|
||||
if self.config.gui_outer_side_falloff:
|
||||
if (
|
||||
self.r_eye_blink == 0.0
|
||||
): # if both eyes closed and DEF is enables, blink
|
||||
if self.r_eye_blink == 0.0: # if both eyes closed and DEF is enables, blink
|
||||
self.client.send_message(
|
||||
"/avatar/parameters/v2/EyeLidLeft",
|
||||
eyelid_transformer(self, self.l_eye_blink),
|
||||
@ -188,12 +162,10 @@ def output_osc(eye_x, eye_y, eye_blink, last_blink, pupil_dilation, avg_velocity
|
||||
self.left_y = eye_y
|
||||
|
||||
if self.left_y != 621:
|
||||
self.client.send_message(
|
||||
"/avatar/parameters/FT/v2/EyeLeftY", self.left_y
|
||||
)
|
||||
self.client.send_message("/avatar/parameters/v2/EyeLeftY", self.left_y)
|
||||
|
||||
self.client.send_message(
|
||||
"/avatar/parameters/FT/v2/EyeLidLeft",
|
||||
"/avatar/parameters/v2/EyeLidLeft",
|
||||
eyelid_transformer(self, self.l_eye_blink),
|
||||
)
|
||||
|
||||
@ -203,10 +175,7 @@ def output_osc(eye_x, eye_y, eye_blink, last_blink, pupil_dilation, avg_velocity
|
||||
self.r_eye_velocity = avg_velocity
|
||||
|
||||
if self.r_eye_blink == 0.0:
|
||||
if (
|
||||
last_blink > 0.15
|
||||
): # when binary blink is on, blinks may be too fast for OSC so we repeat them.
|
||||
# print("REPEATING R BLINK")
|
||||
if last_blink > 0.15: # when binary blink is on, blinks may be too fast for OSC so we repeat them.
|
||||
for i in range(4):
|
||||
self.client.send_message(
|
||||
"/avatar/parameters/v2/EyeLidRight",
|
||||
@ -214,9 +183,7 @@ def output_osc(eye_x, eye_y, eye_blink, last_blink, pupil_dilation, avg_velocity
|
||||
)
|
||||
last_blink = time.time() - last_blink
|
||||
if self.config.gui_outer_side_falloff:
|
||||
if (
|
||||
self.l_eye_blink == 0.0
|
||||
): # if both eyes closed and DEF is enables, blink
|
||||
if self.l_eye_blink == 0.0: # if both eyes closed and DEF is enables, blink
|
||||
self.client.send_message(
|
||||
"/avatar/parameters/v2/EyeLidLeft",
|
||||
eyelid_transformer(self, self.r_eye_blink),
|
||||
@ -232,23 +199,13 @@ def output_osc(eye_x, eye_y, eye_blink, last_blink, pupil_dilation, avg_velocity
|
||||
self.right_y = eye_y
|
||||
|
||||
if self.right_y != 621:
|
||||
self.client.send_message(
|
||||
"/avatar/parameters/v2/EyeRightY", self.right_y
|
||||
)
|
||||
self.client.send_message("/avatar/parameters/v2/EyeRightY", self.right_y)
|
||||
|
||||
self.client.send_message(
|
||||
"/avatar/parameters/v2/EyeLidRight",
|
||||
eyelid_transformer(self, self.r_eye_blink),
|
||||
)
|
||||
|
||||
if (
|
||||
self.main_config.eye_display_id in [EyeId.BOTH]
|
||||
and self.right_y != 621
|
||||
and self.left_y != 621
|
||||
):
|
||||
y = (self.right_y + self.left_y) / 2
|
||||
self.client.send_message("/avatar/parameters/v2/EyeY", y)
|
||||
|
||||
if self.config.gui_vrc_native: # VRC NATIVE
|
||||
|
||||
if self.main_config.eye_display_id in [
|
||||
@ -257,20 +214,14 @@ def output_osc(eye_x, eye_y, eye_blink, last_blink, pupil_dilation, avg_velocity
|
||||
]: # we are in single eye mode
|
||||
se = True
|
||||
if eye_blink == 0.0:
|
||||
if (
|
||||
last_blink > 0.2
|
||||
): # when binary blink is on, blinks may be too fast for OSC so we repeat them.
|
||||
if last_blink > 0.2: # when binary blink is on, blinks may be too fast for OSC so we repeat them.
|
||||
for i in range(5):
|
||||
self.client.send_message(
|
||||
"/tracking/eye/EyesClosedAmount", float(1 - eye_blink)
|
||||
)
|
||||
self.client.send_message("/tracking/eye/EyesClosedAmount", float(1 - eye_blink))
|
||||
eye_blink += 0.02 # TODO finish tuning value
|
||||
last_blink = time.time() - last_blink
|
||||
|
||||
else:
|
||||
self.client.send_message(
|
||||
"/tracking/eye/EyesClosedAmount", float(1 - eye_blink)
|
||||
)
|
||||
self.client.send_message("/tracking/eye/EyesClosedAmount", float(1 - eye_blink))
|
||||
self.client.send_message(
|
||||
"/tracking/eye/LeftRightVec",
|
||||
[float(eye_x), float(eye_y), 1.0, float(eye_x), float(eye_y), 1.0],
|
||||
@ -290,21 +241,13 @@ def output_osc(eye_x, eye_y, eye_blink, last_blink, pupil_dilation, avg_velocity
|
||||
)
|
||||
|
||||
if self.l_eye_blink == 0.0:
|
||||
if (
|
||||
last_blink > 0.2
|
||||
): # when binary blink is on, blinks may be too fast for OSC so we repeat them.
|
||||
if last_blink > 0.2: # when binary blink is on, blinks may be too fast for OSC so we repeat them.
|
||||
for i in range(5):
|
||||
self.client.send_message(
|
||||
"/tracking/eye/EyesClosedAmount", float(1 - eye_blink)
|
||||
)
|
||||
self.client.send_message("/tracking/eye/EyesClosedAmount", float(1 - eye_blink))
|
||||
last_blink = time.time() - last_blink
|
||||
if self.config.gui_outer_side_falloff:
|
||||
if (
|
||||
self.r_eye_blink == 0.0
|
||||
): # if both eyes closed and DEF is enables, blink
|
||||
self.client.send_message(
|
||||
"/tracking/eye/EyesClosedAmount", float(1 - eye_blink)
|
||||
)
|
||||
if self.r_eye_blink == 0.0: # if both eyes closed and DEF is enables, blink
|
||||
self.client.send_message("/tracking/eye/EyesClosedAmount", float(1 - eye_blink))
|
||||
self.l_eye_x = self.r_eye_x
|
||||
|
||||
elif self.eye_id in [EyeId.RIGHT] and not se: # Right eye, send data to right
|
||||
@ -318,48 +261,26 @@ def output_osc(eye_x, eye_y, eye_blink, last_blink, pupil_dilation, avg_velocity
|
||||
)
|
||||
|
||||
if self.r_eye_blink == 0.0:
|
||||
if (
|
||||
last_blink > 0.2
|
||||
): # when binary blink is on, blinks may be too fast for OSC so we repeat them.
|
||||
if last_blink > 0.2: # when binary blink is on, blinks may be too fast for OSC so we repeat them.
|
||||
for i in range(5):
|
||||
self.client.send_message(
|
||||
"/tracking/eye/EyesClosedAmount", float(1 - eye_blink)
|
||||
)
|
||||
self.client.send_message("/tracking/eye/EyesClosedAmount", float(1 - eye_blink))
|
||||
last_blink = time.time() - last_blink
|
||||
if self.config.gui_outer_side_falloff:
|
||||
if (
|
||||
self.l_eye_blink == 0.0
|
||||
): # if both eyes closed and DEF is enables, blink
|
||||
self.client.send_message(
|
||||
"/tracking/eye/EyesClosedAmount", float(0)
|
||||
)
|
||||
if self.l_eye_blink == 0.0: # if both eyes closed and DEF is enables, blink
|
||||
self.client.send_message("/tracking/eye/EyesClosedAmount", float(0))
|
||||
|
||||
self.r_eye_x = self.l_eye_x
|
||||
|
||||
if (
|
||||
self.main_config.eye_display_id in [EyeId.BOTH]
|
||||
and self.r_eye_blink != 621
|
||||
and self.r_eye_blink != 621
|
||||
):
|
||||
if self.main_config.eye_display_id in [EyeId.BOTH] and self.r_eye_blink != 621 and self.r_eye_blink != 621:
|
||||
if self.r_eye_blink == 0.0 or self.l_eye_blink == 0.0:
|
||||
if (
|
||||
last_blink > 0.2
|
||||
): # when binary blink is on, blinks may be too fast for OSC so we repeat them.
|
||||
if last_blink > 0.2: # when binary blink is on, blinks may be too fast for OSC so we repeat them.
|
||||
for i in range(5):
|
||||
self.client.send_message(
|
||||
"/tracking/eye/EyesClosedAmount", float(1)
|
||||
)
|
||||
self.client.send_message("/tracking/eye/EyesClosedAmount", float(1))
|
||||
last_blink = time.time() - last_blink
|
||||
eye_blink = (self.r_eye_blink + self.l_eye_blink) / 2
|
||||
self.client.send_message(
|
||||
"/tracking/eye/EyesClosedAmount", float(1 - eye_blink)
|
||||
)
|
||||
self.client.send_message("/tracking/eye/EyesClosedAmount", float(1 - eye_blink))
|
||||
|
||||
if (
|
||||
self.main_config.eye_display_id in [EyeId.BOTH]
|
||||
and self.right_y != 621
|
||||
and self.left_y != 621
|
||||
):
|
||||
if self.main_config.eye_display_id in [EyeId.BOTH] and self.right_y != 621 and self.left_y != 621:
|
||||
eye_y = (self.right_y + self.left_y) / 2
|
||||
|
||||
if not se:
|
||||
@ -426,9 +347,7 @@ class VRChatOSC:
|
||||
|
||||
|
||||
class VRChatOSCReceiver:
|
||||
def __init__(
|
||||
self, cancellation_event: threading.Event, main_config: EyeTrackConfig, eyes: []
|
||||
):
|
||||
def __init__(self, cancellation_event: threading.Event, main_config: EyeTrackConfig, eyes: []):
|
||||
self.config = main_config.settings
|
||||
self.cancellation_event = cancellation_event
|
||||
self.dispatcher = dispatcher.Dispatcher()
|
||||
@ -439,9 +358,7 @@ class VRChatOSCReceiver:
|
||||
self.dispatcher,
|
||||
)
|
||||
except:
|
||||
print(
|
||||
f"\033[91m[ERROR] OSC Receive port: {self.config.gui_osc_receiver_port} occupied.\033[0m"
|
||||
)
|
||||
print(f"\033[91m[ERROR] OSC Receive port: {self.config.gui_osc_receiver_port} occupied.\033[0m")
|
||||
|
||||
def shutdown(self):
|
||||
print("\033[94m[INFO] Exiting OSC Receiver\033[0m")
|
||||
@ -467,24 +384,13 @@ class VRChatOSCReceiver:
|
||||
PlaySound("Audio/start.wav", SND_FILENAME | SND_ASYNC)
|
||||
|
||||
def run(self):
|
||||
|
||||
# bind what function to run when specified OSC message is received
|
||||
try:
|
||||
self.dispatcher.map(
|
||||
self.config.gui_osc_recalibrate_address, self.recalibrate_eyes
|
||||
)
|
||||
self.dispatcher.map(
|
||||
self.config.gui_osc_recenter_address, self.recenter_eyes
|
||||
)
|
||||
self.dispatcher.map(self.config.gui_osc_recalibrate_address, self.recalibrate_eyes)
|
||||
self.dispatcher.map(self.config.gui_osc_recenter_address, self.recenter_eyes)
|
||||
# start the server
|
||||
print(
|
||||
"\033[92m[INFO] VRChatOSCReceiver serving on {}\033[0m".format(
|
||||
self.server.server_address
|
||||
)
|
||||
)
|
||||
print("\033[92m[INFO] VRChatOSCReceiver serving on {}\033[0m".format(self.server.server_address))
|
||||
self.server.serve_forever()
|
||||
|
||||
except:
|
||||
print(
|
||||
f"\033[91m[ERROR] OSC Receive port: {self.config.gui_osc_receiver_port} occupied.\033[0m"
|
||||
)
|
||||
print(f"\033[91m[ERROR] OSC Receive port: {self.config.gui_osc_receiver_port} occupied.\033[0m")
|
||||
|
||||
125
conftest.py
Normal file
125
conftest.py
Normal file
@ -0,0 +1,125 @@
|
||||
import pytest
|
||||
from EyeTrackApp.config import (
|
||||
EyeTrackConfig,
|
||||
EyeTrackCameraConfig,
|
||||
EyeTrackSettingsConfig,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def eyetrack_settings_config():
|
||||
return EyeTrackSettingsConfig(
|
||||
gui_flip_x_axis_left=False,
|
||||
gui_flip_x_axis_right=False,
|
||||
gui_flip_y_axis=False,
|
||||
gui_RANSAC3D=False,
|
||||
gui_HSF=False,
|
||||
gui_BLOB=False,
|
||||
gui_BLINK=False,
|
||||
gui_HSRAC=False,
|
||||
gui_AHSFRAC=False,
|
||||
gui_AHSF=False,
|
||||
gui_DADDY=False,
|
||||
gui_LEAP=True,
|
||||
gui_HSF_radius=15,
|
||||
gui_HSF_radius_left=10,
|
||||
gui_HSF_radius_right=10,
|
||||
gui_min_cutoff="0.0004",
|
||||
gui_speed_coefficient="0.9",
|
||||
gui_osc_address="127.0.0.1",
|
||||
gui_osc_port=8889,
|
||||
gui_osc_receiver_port=9001,
|
||||
gui_osc_recenter_address="/avatar/parameters/etvr_recenter",
|
||||
gui_osc_recalibrate_address="/avatar/parameters/etvr_recalibrate",
|
||||
gui_blob_maxsize=25.0,
|
||||
gui_blob_minsize=10.0,
|
||||
gui_recenter_eyes=False,
|
||||
tracker_single_eye=2,
|
||||
gui_threshold=65,
|
||||
gui_AHSFRACP=1,
|
||||
gui_AHSFP=2,
|
||||
gui_HSRACP=3,
|
||||
gui_HSFP=4,
|
||||
gui_DADDYP=5,
|
||||
gui_RANSAC3DP=6,
|
||||
gui_BLOBP=7,
|
||||
gui_LEAPP=8,
|
||||
gui_IBO=True,
|
||||
gui_skip_autoradius=False,
|
||||
gui_thresh_add=11,
|
||||
gui_update_check=False,
|
||||
gui_ROSC=False,
|
||||
gui_circular_crop_right=False,
|
||||
gui_circular_crop_left=False,
|
||||
ibo_filter_samples=400,
|
||||
ibo_average_output_samples=0,
|
||||
ibo_fully_close_eye_threshold=0.3,
|
||||
calibration_samples=600,
|
||||
osc_right_eye_close_address="/avatar/parameters/RightEyeLidExpandedSqueeze",
|
||||
osc_left_eye_close_address="/avatar/parameters/LeftEyeLidExpandedSqueeze",
|
||||
osc_left_eye_x_address="/avatar/parameters/LeftEyeX",
|
||||
osc_right_eye_x_address="/avatar/parameters/RightEyeX",
|
||||
osc_eyes_y_address="/avatar/parameters/EyesY",
|
||||
osc_invert_eye_close=False,
|
||||
gui_RANSACBLINK=False,
|
||||
gui_right_eye_dominant=False,
|
||||
gui_left_eye_dominant=False,
|
||||
gui_outer_side_falloff=False,
|
||||
gui_eye_dominant_diff_thresh=0.3,
|
||||
gui_legacy_ransac=False,
|
||||
gui_legacy_ransac_thresh_right=80,
|
||||
gui_legacy_ransac_thresh_left=80,
|
||||
gui_LEAP_lid=False,
|
||||
gui_osc_vrcft_v1=False,
|
||||
gui_osc_vrcft_v2=False,
|
||||
gui_vrc_native=False,
|
||||
gui_pupil_dilation=True,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def eyetrack_camera_config():
|
||||
return EyeTrackCameraConfig(
|
||||
rotation_angle=250,
|
||||
roi_window_x=67,
|
||||
roi_window_y=27,
|
||||
roi_window_w=96,
|
||||
roi_window_h=117,
|
||||
focal_length=30,
|
||||
capture_source="http://192.168.0.31/",
|
||||
calib_XMAX=122.5,
|
||||
calib_XMIN=38.0,
|
||||
calib_YMAX=118.0,
|
||||
calib_YMIN=6.0,
|
||||
calib_XOFF=40.0,
|
||||
calib_YOFF=63.0,
|
||||
calibration_points=[],
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def main_config(eyetrack_camera_config, eyetrack_settings_config):
|
||||
return EyeTrackConfig(
|
||||
right_eye=eyetrack_camera_config,
|
||||
left_eye=eyetrack_camera_config,
|
||||
settings=eyetrack_settings_config,
|
||||
eye_display_id=0,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def main_config_v1_params(main_config):
|
||||
main_config.settings.gui_osc_vrcft_v1 = True
|
||||
return main_config
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def main_config_v2_params(main_config):
|
||||
main_config.settings.gui_osc_vrcft_v2 = True
|
||||
return main_config
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def main_config_native_params(main_config):
|
||||
main_config.settings.gui_vrc_native = True
|
||||
return main_config
|
||||
130
poetry.lock
generated
130
poetry.lock
generated
@ -207,6 +207,70 @@ humanfriendly = ">=9.1"
|
||||
[package.extras]
|
||||
cron = ["capturer (>=2.4)"]
|
||||
|
||||
[[package]]
|
||||
name = "coverage"
|
||||
version = "7.4.1"
|
||||
description = "Code coverage measurement for Python"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "coverage-7.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:077d366e724f24fc02dbfe9d946534357fda71af9764ff99d73c3c596001bbd7"},
|
||||
{file = "coverage-7.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0193657651f5399d433c92f8ae264aff31fc1d066deee4b831549526433f3f61"},
|
||||
{file = "coverage-7.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d17bbc946f52ca67adf72a5ee783cd7cd3477f8f8796f59b4974a9b59cacc9ee"},
|
||||
{file = "coverage-7.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3277f5fa7483c927fe3a7b017b39351610265308f5267ac6d4c2b64cc1d8d25"},
|
||||
{file = "coverage-7.4.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6dceb61d40cbfcf45f51e59933c784a50846dc03211054bd76b421a713dcdf19"},
|
||||
{file = "coverage-7.4.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6008adeca04a445ea6ef31b2cbaf1d01d02986047606f7da266629afee982630"},
|
||||
{file = "coverage-7.4.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c61f66d93d712f6e03369b6a7769233bfda880b12f417eefdd4f16d1deb2fc4c"},
|
||||
{file = "coverage-7.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b9bb62fac84d5f2ff523304e59e5c439955fb3b7f44e3d7b2085184db74d733b"},
|
||||
{file = "coverage-7.4.1-cp310-cp310-win32.whl", hash = "sha256:f86f368e1c7ce897bf2457b9eb61169a44e2ef797099fb5728482b8d69f3f016"},
|
||||
{file = "coverage-7.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:869b5046d41abfea3e381dd143407b0d29b8282a904a19cb908fa24d090cc018"},
|
||||
{file = "coverage-7.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b8ffb498a83d7e0305968289441914154fb0ef5d8b3157df02a90c6695978295"},
|
||||
{file = "coverage-7.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3cacfaefe6089d477264001f90f55b7881ba615953414999c46cc9713ff93c8c"},
|
||||
{file = "coverage-7.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d6850e6e36e332d5511a48a251790ddc545e16e8beaf046c03985c69ccb2676"},
|
||||
{file = "coverage-7.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18e961aa13b6d47f758cc5879383d27b5b3f3dcd9ce8cdbfdc2571fe86feb4dd"},
|
||||
{file = "coverage-7.4.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dfd1e1b9f0898817babf840b77ce9fe655ecbe8b1b327983df485b30df8cc011"},
|
||||
{file = "coverage-7.4.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6b00e21f86598b6330f0019b40fb397e705135040dbedc2ca9a93c7441178e74"},
|
||||
{file = "coverage-7.4.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:536d609c6963c50055bab766d9951b6c394759190d03311f3e9fcf194ca909e1"},
|
||||
{file = "coverage-7.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7ac8f8eb153724f84885a1374999b7e45734bf93a87d8df1e7ce2146860edef6"},
|
||||
{file = "coverage-7.4.1-cp311-cp311-win32.whl", hash = "sha256:f3771b23bb3675a06f5d885c3630b1d01ea6cac9e84a01aaf5508706dba546c5"},
|
||||
{file = "coverage-7.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:9d2f9d4cc2a53b38cabc2d6d80f7f9b7e3da26b2f53d48f05876fef7956b6968"},
|
||||
{file = "coverage-7.4.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f68ef3660677e6624c8cace943e4765545f8191313a07288a53d3da188bd8581"},
|
||||
{file = "coverage-7.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:23b27b8a698e749b61809fb637eb98ebf0e505710ec46a8aa6f1be7dc0dc43a6"},
|
||||
{file = "coverage-7.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e3424c554391dc9ef4a92ad28665756566a28fecf47308f91841f6c49288e66"},
|
||||
{file = "coverage-7.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e0860a348bf7004c812c8368d1fc7f77fe8e4c095d661a579196a9533778e156"},
|
||||
{file = "coverage-7.4.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe558371c1bdf3b8fa03e097c523fb9645b8730399c14fe7721ee9c9e2a545d3"},
|
||||
{file = "coverage-7.4.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3468cc8720402af37b6c6e7e2a9cdb9f6c16c728638a2ebc768ba1ef6f26c3a1"},
|
||||
{file = "coverage-7.4.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:02f2edb575d62172aa28fe00efe821ae31f25dc3d589055b3fb64d51e52e4ab1"},
|
||||
{file = "coverage-7.4.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ca6e61dc52f601d1d224526360cdeab0d0712ec104a2ce6cc5ccef6ed9a233bc"},
|
||||
{file = "coverage-7.4.1-cp312-cp312-win32.whl", hash = "sha256:ca7b26a5e456a843b9b6683eada193fc1f65c761b3a473941efe5a291f604c74"},
|
||||
{file = "coverage-7.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:85ccc5fa54c2ed64bd91ed3b4a627b9cce04646a659512a051fa82a92c04a448"},
|
||||
{file = "coverage-7.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8bdb0285a0202888d19ec6b6d23d5990410decb932b709f2b0dfe216d031d218"},
|
||||
{file = "coverage-7.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:918440dea04521f499721c039863ef95433314b1db00ff826a02580c1f503e45"},
|
||||
{file = "coverage-7.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:379d4c7abad5afbe9d88cc31ea8ca262296480a86af945b08214eb1a556a3e4d"},
|
||||
{file = "coverage-7.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b094116f0b6155e36a304ff912f89bbb5067157aff5f94060ff20bbabdc8da06"},
|
||||
{file = "coverage-7.4.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2f5968608b1fe2a1d00d01ad1017ee27efd99b3437e08b83ded9b7af3f6f766"},
|
||||
{file = "coverage-7.4.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:10e88e7f41e6197ea0429ae18f21ff521d4f4490aa33048f6c6f94c6045a6a75"},
|
||||
{file = "coverage-7.4.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a4a3907011d39dbc3e37bdc5df0a8c93853c369039b59efa33a7b6669de04c60"},
|
||||
{file = "coverage-7.4.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6d224f0c4c9c98290a6990259073f496fcec1b5cc613eecbd22786d398ded3ad"},
|
||||
{file = "coverage-7.4.1-cp38-cp38-win32.whl", hash = "sha256:23f5881362dcb0e1a92b84b3c2809bdc90db892332daab81ad8f642d8ed55042"},
|
||||
{file = "coverage-7.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:a07f61fc452c43cd5328b392e52555f7d1952400a1ad09086c4a8addccbd138d"},
|
||||
{file = "coverage-7.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8e738a492b6221f8dcf281b67129510835461132b03024830ac0e554311a5c54"},
|
||||
{file = "coverage-7.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:46342fed0fff72efcda77040b14728049200cbba1279e0bf1188f1f2078c1d70"},
|
||||
{file = "coverage-7.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9641e21670c68c7e57d2053ddf6c443e4f0a6e18e547e86af3fad0795414a628"},
|
||||
{file = "coverage-7.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aeb2c2688ed93b027eb0d26aa188ada34acb22dceea256d76390eea135083950"},
|
||||
{file = "coverage-7.4.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d12c923757de24e4e2110cf8832d83a886a4cf215c6e61ed506006872b43a6d1"},
|
||||
{file = "coverage-7.4.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0491275c3b9971cdbd28a4595c2cb5838f08036bca31765bad5e17edf900b2c7"},
|
||||
{file = "coverage-7.4.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:8dfc5e195bbef80aabd81596ef52a1277ee7143fe419efc3c4d8ba2754671756"},
|
||||
{file = "coverage-7.4.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1a78b656a4d12b0490ca72651fe4d9f5e07e3c6461063a9b6265ee45eb2bdd35"},
|
||||
{file = "coverage-7.4.1-cp39-cp39-win32.whl", hash = "sha256:f90515974b39f4dea2f27c0959688621b46d96d5a626cf9c53dbc653a895c05c"},
|
||||
{file = "coverage-7.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:64e723ca82a84053dd7bfcc986bdb34af8d9da83c521c19d6b472bc6880e191a"},
|
||||
{file = "coverage-7.4.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:32a8d985462e37cfdab611a6f95b09d7c091d07668fdc26e47a725ee575fe166"},
|
||||
{file = "coverage-7.4.1.tar.gz", hash = "sha256:1ed4b95480952b1a26d863e546fa5094564aa0065e1e5f0d4d0041f293251d04"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
toml = ["tomli"]
|
||||
|
||||
[[package]]
|
||||
name = "flake8"
|
||||
version = "5.0.4"
|
||||
@ -291,6 +355,17 @@ pyav = ["av"]
|
||||
test = ["fsspec[github]", "pytest", "pytest-cov"]
|
||||
tifffile = ["tifffile"]
|
||||
|
||||
[[package]]
|
||||
name = "iniconfig"
|
||||
version = "2.0.0"
|
||||
description = "brain-dead simple config-ini parsing"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"},
|
||||
{file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy-loader"
|
||||
version = "0.3"
|
||||
@ -665,6 +740,21 @@ files = [
|
||||
docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"]
|
||||
test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"]
|
||||
|
||||
[[package]]
|
||||
name = "pluggy"
|
||||
version = "1.4.0"
|
||||
description = "plugin and hook calling mechanisms for python"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pluggy-1.4.0-py3-none-any.whl", hash = "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981"},
|
||||
{file = "pluggy-1.4.0.tar.gz", hash = "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
dev = ["pre-commit", "tox"]
|
||||
testing = ["pytest", "pytest-benchmark"]
|
||||
|
||||
[[package]]
|
||||
name = "protobuf"
|
||||
version = "4.25.1"
|
||||
@ -991,6 +1081,44 @@ files = [
|
||||
{file = "PySimpleGUI-4.60.5.tar.gz", hash = "sha256:31014d1cc5eef1373d7e93564ff2604662645cc774a939b1f01aa253e7f9d78b"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pytest"
|
||||
version = "8.0.0"
|
||||
description = "pytest: simple powerful testing with Python"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pytest-8.0.0-py3-none-any.whl", hash = "sha256:50fb9cbe836c3f20f0dfa99c565201fb75dc54c8d76373cd1bde06b06657bdb6"},
|
||||
{file = "pytest-8.0.0.tar.gz", hash = "sha256:249b1b0864530ba251b7438274c4d251c58d868edaaec8762893ad4a0d71c36c"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
colorama = {version = "*", markers = "sys_platform == \"win32\""}
|
||||
iniconfig = "*"
|
||||
packaging = "*"
|
||||
pluggy = ">=1.3.0,<2.0"
|
||||
|
||||
[package.extras]
|
||||
testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
|
||||
|
||||
[[package]]
|
||||
name = "pytest-cov"
|
||||
version = "4.1.0"
|
||||
description = "Pytest plugin for measuring coverage."
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "pytest-cov-4.1.0.tar.gz", hash = "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6"},
|
||||
{file = "pytest_cov-4.1.0-py3-none-any.whl", hash = "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
coverage = {version = ">=5.2.1", extras = ["toml"]}
|
||||
pytest = ">=4.6"
|
||||
|
||||
[package.extras]
|
||||
testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"]
|
||||
|
||||
[[package]]
|
||||
name = "python-osc"
|
||||
version = "1.8.3"
|
||||
@ -1251,4 +1379,4 @@ files = [
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "~3.11.0"
|
||||
content-hash = "01b325e85a4f1b92329d326db3871acd7051a0756b27b7dd230daf4ffa9c18bd"
|
||||
content-hash = "51c416718d7c51b683ad74bee318c227ced271bc97307643b7c8072921cc4928"
|
||||
|
||||
@ -23,6 +23,8 @@ winotify = [
|
||||
onnxruntime = "^1.13.1"
|
||||
colorama = "^0.4.6"
|
||||
taskipy = "^1.10.4"
|
||||
pytest = "^8.0.0"
|
||||
pytest-cov = "^4.1.0"
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
black = "^22.10.0"
|
||||
pyinstaller = "^5.6.2"
|
||||
@ -31,6 +33,16 @@ flake8 = "^5.0.4"
|
||||
[tool.taskipy.tasks]
|
||||
dev = "python eyetrackapp.py"
|
||||
|
||||
[tool.black]
|
||||
line-length = 120
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core>=1.0.0"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
addopts = "-ra -q --cov=. --cov-report html --cov-report term"
|
||||
pythonpath = "."
|
||||
python_files = [
|
||||
"test_*.py"
|
||||
]
|
||||
0
tests/__init__.py
Normal file
0
tests/__init__.py
Normal file
314
tests/test_osc.py
Normal file
314
tests/test_osc.py
Normal file
@ -0,0 +1,314 @@
|
||||
import dataclasses
|
||||
import threading
|
||||
from queue import Queue
|
||||
from time import sleep
|
||||
from unittest import mock
|
||||
|
||||
import pytest
|
||||
|
||||
from EyeTrackApp.osc import VRChatOSC
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class EyeInfoMock:
|
||||
x: int
|
||||
y: int
|
||||
blink: float
|
||||
pupil_dilation: float
|
||||
avg_velocity: float
|
||||
|
||||
|
||||
class SimpleUDPClientMock:
|
||||
def __init__(self, osc_address, port):
|
||||
self.osc_address = osc_address
|
||||
self.port = port
|
||||
self.messages = []
|
||||
|
||||
def send_message(self, address, value):
|
||||
self.messages.append((address, value))
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"eye_id,messages,expected_outcome",
|
||||
[
|
||||
(
|
||||
0,
|
||||
[
|
||||
EyeInfoMock(
|
||||
x=0,
|
||||
y=0,
|
||||
blink=1,
|
||||
pupil_dilation=0,
|
||||
avg_velocity=0,
|
||||
),
|
||||
],
|
||||
[
|
||||
("/avatar/parameters/v2/EyeX", 0),
|
||||
("/avatar/parameters/v2/EyeY", 0),
|
||||
("/avatar/parameters/v2/EyeLid", 1.0),
|
||||
],
|
||||
),
|
||||
(
|
||||
1,
|
||||
[
|
||||
EyeInfoMock(
|
||||
x=0,
|
||||
y=0,
|
||||
blink=1,
|
||||
pupil_dilation=0,
|
||||
avg_velocity=0,
|
||||
),
|
||||
],
|
||||
[
|
||||
("/avatar/parameters/v2/EyeX", 0),
|
||||
("/avatar/parameters/v2/EyeY", 0),
|
||||
("/avatar/parameters/v2/EyeLid", 1.0),
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_send_command_v2_params_single_eye(main_config_v2_params, eye_id, messages, expected_outcome):
|
||||
with mock.patch("EyeTrackApp.osc.udp_client.SimpleUDPClient", SimpleUDPClientMock):
|
||||
cancellation_event = threading.Event()
|
||||
msg_queue = Queue()
|
||||
client = VRChatOSC(
|
||||
main_config=main_config_v2_params,
|
||||
msg_queue=msg_queue,
|
||||
cancellation_event=cancellation_event,
|
||||
)
|
||||
|
||||
osc_thread = threading.Thread(target=client.run)
|
||||
osc_thread.start()
|
||||
|
||||
for message in messages:
|
||||
sleep(0.01)
|
||||
msg_queue.put((eye_id, message))
|
||||
|
||||
cancellation_event.set()
|
||||
osc_thread.join()
|
||||
|
||||
assert msg_queue.empty()
|
||||
assert client.client.messages == expected_outcome
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"eye_data,expected_outcome",
|
||||
[
|
||||
(
|
||||
[
|
||||
(
|
||||
0,
|
||||
EyeInfoMock(
|
||||
x=0,
|
||||
y=0,
|
||||
blink=1,
|
||||
pupil_dilation=1,
|
||||
avg_velocity=0,
|
||||
),
|
||||
),
|
||||
(
|
||||
1,
|
||||
EyeInfoMock(
|
||||
x=10,
|
||||
y=5,
|
||||
blink=0.5,
|
||||
pupil_dilation=1,
|
||||
avg_velocity=0,
|
||||
),
|
||||
),
|
||||
],
|
||||
[
|
||||
("/avatar/parameters/v2/EyeRightX", 0),
|
||||
("/avatar/parameters/v2/EyeRightY", 0),
|
||||
("/avatar/parameters/v2/EyeLidRight", 1.0),
|
||||
("/avatar/parameters/v2/EyeLeftX", 10),
|
||||
("/avatar/parameters/v2/EyeLeftY", 5),
|
||||
("/avatar/parameters/v2/EyeLidLeft", 0.5),
|
||||
],
|
||||
),
|
||||
# binary blink
|
||||
(
|
||||
[
|
||||
(
|
||||
0,
|
||||
EyeInfoMock(
|
||||
x=0,
|
||||
y=0,
|
||||
blink=0,
|
||||
pupil_dilation=1,
|
||||
avg_velocity=0,
|
||||
),
|
||||
),
|
||||
(
|
||||
1,
|
||||
EyeInfoMock(
|
||||
x=10,
|
||||
y=5,
|
||||
blink=0,
|
||||
pupil_dilation=1,
|
||||
avg_velocity=0,
|
||||
),
|
||||
),
|
||||
],
|
||||
[
|
||||
("/avatar/parameters/v2/EyeLidRight", 0.0),
|
||||
("/avatar/parameters/v2/EyeLidRight", 0.0),
|
||||
("/avatar/parameters/v2/EyeLidRight", 0.0),
|
||||
("/avatar/parameters/v2/EyeLidRight", 0.0),
|
||||
("/avatar/parameters/v2/EyeRightX", 0),
|
||||
("/avatar/parameters/v2/EyeRightY", 0),
|
||||
("/avatar/parameters/v2/EyeLidRight", 0.0),
|
||||
("/avatar/parameters/v2/EyeLidLeft", 0.0),
|
||||
("/avatar/parameters/v2/EyeLidLeft", 0.0),
|
||||
("/avatar/parameters/v2/EyeLidLeft", 0.0),
|
||||
("/avatar/parameters/v2/EyeLidLeft", 0.0),
|
||||
("/avatar/parameters/v2/EyeLeftX", 0),
|
||||
("/avatar/parameters/v2/EyeLeftY", 5),
|
||||
("/avatar/parameters/v2/EyeLidLeft", 0.0),
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_send_command_v2_params_dual_eye(main_config_v2_params, eye_data, expected_outcome):
|
||||
main_config_v2_params.eye_display_id = 2
|
||||
|
||||
with mock.patch("EyeTrackApp.osc.udp_client.SimpleUDPClient", SimpleUDPClientMock):
|
||||
cancellation_event = threading.Event()
|
||||
msg_queue = Queue()
|
||||
client = VRChatOSC(
|
||||
main_config=main_config_v2_params,
|
||||
msg_queue=msg_queue,
|
||||
cancellation_event=cancellation_event,
|
||||
)
|
||||
|
||||
osc_thread = threading.Thread(target=client.run)
|
||||
osc_thread.start()
|
||||
|
||||
for eye_id, message in eye_data:
|
||||
sleep(0.01)
|
||||
msg_queue.put((eye_id, message))
|
||||
|
||||
cancellation_event.set()
|
||||
osc_thread.join()
|
||||
|
||||
assert msg_queue.empty()
|
||||
assert client.client.messages == expected_outcome
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"eye_data,expected_outcome",
|
||||
[
|
||||
(
|
||||
[
|
||||
(
|
||||
0,
|
||||
EyeInfoMock(
|
||||
x=0,
|
||||
y=0,
|
||||
blink=0,
|
||||
pupil_dilation=1,
|
||||
avg_velocity=0,
|
||||
),
|
||||
),
|
||||
(
|
||||
1,
|
||||
EyeInfoMock(
|
||||
x=10,
|
||||
y=5,
|
||||
blink=0,
|
||||
pupil_dilation=1,
|
||||
avg_velocity=0,
|
||||
),
|
||||
),
|
||||
],
|
||||
[
|
||||
("/avatar/parameters/v2/EyeLidRight", 0.0),
|
||||
("/avatar/parameters/v2/EyeLidRight", 0.0),
|
||||
("/avatar/parameters/v2/EyeLidRight", 0.0),
|
||||
("/avatar/parameters/v2/EyeLidRight", 0.0),
|
||||
("/avatar/parameters/v2/EyeRightX", 0),
|
||||
("/avatar/parameters/v2/EyeRightY", 0),
|
||||
("/avatar/parameters/v2/EyeLidRight", 0.0),
|
||||
("/avatar/parameters/v2/EyeLidLeft", 0.0),
|
||||
("/avatar/parameters/v2/EyeLidLeft", 0.0),
|
||||
("/avatar/parameters/v2/EyeLidLeft", 0.0),
|
||||
("/avatar/parameters/v2/EyeLidLeft", 0.0),
|
||||
("/avatar/parameters/v2/EyeLidLeft", 0.0),
|
||||
("/avatar/parameters/v2/EyeLidRight", 0.0),
|
||||
("/avatar/parameters/v2/EyeLeftX", 0),
|
||||
("/avatar/parameters/v2/EyeLeftY", 5),
|
||||
("/avatar/parameters/v2/EyeLidLeft", 0.0),
|
||||
],
|
||||
),
|
||||
(
|
||||
[
|
||||
(
|
||||
0,
|
||||
EyeInfoMock(
|
||||
x=0,
|
||||
y=0,
|
||||
blink=0,
|
||||
pupil_dilation=1,
|
||||
avg_velocity=0,
|
||||
),
|
||||
),
|
||||
(
|
||||
1,
|
||||
EyeInfoMock(
|
||||
x=10,
|
||||
y=5,
|
||||
blink=0,
|
||||
pupil_dilation=1,
|
||||
avg_velocity=0,
|
||||
),
|
||||
),
|
||||
],
|
||||
[
|
||||
# binary blink
|
||||
("/avatar/parameters/v2/EyeLidRight", 0.0),
|
||||
("/avatar/parameters/v2/EyeLidRight", 0.0),
|
||||
("/avatar/parameters/v2/EyeLidRight", 0.0),
|
||||
("/avatar/parameters/v2/EyeLidRight", 0.0),
|
||||
("/avatar/parameters/v2/EyeRightX", 0),
|
||||
("/avatar/parameters/v2/EyeRightY", 0),
|
||||
# side falloff
|
||||
("/avatar/parameters/v2/EyeLidRight", 0.0),
|
||||
("/avatar/parameters/v2/EyeLidLeft", 0.0),
|
||||
# binary blink again
|
||||
("/avatar/parameters/v2/EyeLidLeft", 0.0),
|
||||
("/avatar/parameters/v2/EyeLidLeft", 0.0),
|
||||
("/avatar/parameters/v2/EyeLidLeft", 0.0),
|
||||
("/avatar/parameters/v2/EyeLidLeft", 0.0),
|
||||
("/avatar/parameters/v2/EyeLidRight", 0.0),
|
||||
("/avatar/parameters/v2/EyeLeftX", 0),
|
||||
("/avatar/parameters/v2/EyeLeftY", 5),
|
||||
("/avatar/parameters/v2/EyeLidLeft", 0.0),
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_send_command_v2_params_eye_outer_side_falloff(main_config_v2_params, eye_data, expected_outcome):
|
||||
main_config_v2_params.eye_display_id = 2
|
||||
main_config_v2_params.settings.gui_outer_side_falloff = True
|
||||
|
||||
with mock.patch("EyeTrackApp.osc.udp_client.SimpleUDPClient", SimpleUDPClientMock):
|
||||
cancellation_event = threading.Event()
|
||||
msg_queue = Queue()
|
||||
client = VRChatOSC(
|
||||
main_config=main_config_v2_params,
|
||||
msg_queue=msg_queue,
|
||||
cancellation_event=cancellation_event,
|
||||
)
|
||||
|
||||
osc_thread = threading.Thread(target=client.run)
|
||||
osc_thread.start()
|
||||
|
||||
for eye_id, message in eye_data:
|
||||
sleep(0.01)
|
||||
msg_queue.put((eye_id, message))
|
||||
|
||||
cancellation_event.set()
|
||||
osc_thread.join()
|
||||
|
||||
assert msg_queue.empty()
|
||||
assert client.client.messages == expected_outcome
|
||||
Loading…
Reference in New Issue
Block a user