diff --git a/EyeTrackApp/Audio/compleated.wav b/EyeTrackApp/Audio/compleated.wav deleted file mode 100644 index 7527a1c..0000000 Binary files a/EyeTrackApp/Audio/compleated.wav and /dev/null differ diff --git a/EyeTrackApp/config.py b/EyeTrackApp/config.py index e25f7a9..26d5d2f 100644 --- a/EyeTrackApp/config.py +++ b/EyeTrackApp/config.py @@ -61,6 +61,7 @@ class EyeTrackSettingsConfig(BaseModel): gui_thresh_add: int = 11 gui_update_check: bool = False gui_ROSC: bool = False + gui_vrc_native: bool = True class EyeTrackConfig(BaseModel): diff --git a/EyeTrackApp/eye_processor.py b/EyeTrackApp/eye_processor.py index 57cfce3..a41c4de 100644 --- a/EyeTrackApp/eye_processor.py +++ b/EyeTrackApp/eye_processor.py @@ -22,7 +22,7 @@ HSR By: PallasNeko (Optimization Wizard, Contributor), Summer#2406 (Main Algorithm Engineer) RANSAC 3D By: Summer#2406 (Main Algorithm Engineer), Pupil Labs (pye3d), PallasNeko (Optimization) BLOB By: Prohurtz#0001 (Main App Developer) -Algorithm App Implimentations By: Prohurtz#0001, qdot (Inital App Creator) +Algorithm App Implementations By: Prohurtz#0001, qdot (Initial App Creator) Additional Contributors: [Assassin], Summer404NotFound, lorow, ZanzyTHEbar @@ -76,8 +76,8 @@ class EyeInformation: info_type: InformationOrigin x: float y: float - pupil_dialation: int - blink: bool + pupil_dialation: float + blink: float lowb = np.array(0) @@ -96,7 +96,7 @@ def run_once(f): async def delayed_setting_change(setting, value): await asyncio.sleep(5) setting = value - PlaySound('Audio/compleated.wav', SND_FILENAME | SND_ASYNC) + PlaySound('Audio/completed.wav', SND_FILENAME | SND_ASYNC) diff --git a/EyeTrackApp/intensity_eye_open.py b/EyeTrackApp/intensity_eye_open.py index be6fc16..77b3337 100644 --- a/EyeTrackApp/intensity_eye_open.py +++ b/EyeTrackApp/intensity_eye_open.py @@ -244,7 +244,7 @@ class IntensityBasedOpeness: eyeopen = ((intensity - maxp) / (minp - maxp)) #for whatever reason when input and maxp are too close it outputs high eyeopen = 1 - eyeopen - print(eyeopen, intensity, maxp, minp, x, y) + # print(eyeopen, intensity, maxp, minp, x, y) #if maxp - minp < 1.6: # eyeopen = 0.0 # eyeopen = eyeopen - 0.2 diff --git a/EyeTrackApp/osc.py b/EyeTrackApp/osc.py index 1e4f6f4..544b8bb 100644 --- a/EyeTrackApp/osc.py +++ b/EyeTrackApp/osc.py @@ -19,65 +19,137 @@ se = False def output_osc(eye_x, eye_y, eye_blink, last_blink, self): global se - if self.main_config.eye_display_id in [EyeId.RIGHT, EyeId.LEFT]: #we are in single eye mode - se = True - # self.client.send_message("/tracking/eye/LeftRightPitchYaw", [float(eye_y * 100), float(eye_x * 100), float(eye_y * 100), float(eye_x * 101)]) #vrc native ET test - # self.client.send_message("/tracking/eye/EyesClosedAmount", float(1 - eye_blink)) + if not self.config.gui_vrc_native: - self.client.send_message("/avatar/parameters/LeftEyeX", eye_x) - self.client.send_message("/avatar/parameters/RightEyeX", eye_x) - self.client.send_message("/avatar/parameters/EyesY", eye_y) + if self.main_config.eye_display_id in [EyeId.RIGHT, EyeId.LEFT]: #we are in single eye mode + se = True - self.client.send_message("/avatar/parameters/RightEyeLidExpandedSqueeze", float(eye_blink)) - self.client.send_message("/avatar/parameters/LeftEyeLidExpandedSqueeze", float(eye_blink)) - else: - se = False + self.client.send_message("/avatar/parameters/LeftEyeX", eye_x) + self.client.send_message("/avatar/parameters/RightEyeX", eye_x) + self.client.send_message("/avatar/parameters/EyesY", eye_y) - if self.eye_id in [EyeId.LEFT] and not se: #left eye, send data to left - self.l_eye_x = eye_x - self.l_eye_blink = eye_blink + self.client.send_message("/avatar/parameters/RightEyeLidExpandedSqueeze", float(eye_blink)) + self.client.send_message("/avatar/parameters/LeftEyeLidExpandedSqueeze", float(eye_blink)) + else: + se = False - if self.l_eye_blink == 0.0: - if last_blink > 0.7: #when bianary blink is on, blinks may be too fast for OSC so we repeate them. - for i in range(5): - self.client.send_message("/avatar/parameters/LeftEyeLidExpandedSqueeze", float(self.l_eye_blink)) - last_blink = time.time() - last_blink - if self.config.gui_eye_falloff: - if self.r_eye_blink == 0.0: #if both eyes closed and DEF is enables, blink - self.client.send_message("/avatar/parameters/LeftEyeLidExpandedSqueeze", float(self.l_eye_blink)) - self.client.send_message("/avatar/parameters/RightEyeLidExpandedSqueeze", float(self.l_eye_blink)) - self.l_eye_x = self.r_eye_x + if self.eye_id in [EyeId.LEFT] and not se: #left eye, send data to left + self.l_eye_x = eye_x + self.l_eye_blink = eye_blink - self.client.send_message("/avatar/parameters/LeftEyeX", self.l_eye_x) - self.left_y = eye_y + if self.l_eye_blink == 0.0: + if last_blink > 0.7: #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("/avatar/parameters/LeftEyeLidExpandedSqueeze", float(self.l_eye_blink)) + last_blink = time.time() - last_blink + if self.config.gui_eye_falloff: + if self.r_eye_blink == 0.0: #if both eyes closed and DEF is enables, blink + self.client.send_message("/avatar/parameters/LeftEyeLidExpandedSqueeze", float(self.l_eye_blink)) + self.client.send_message("/avatar/parameters/RightEyeLidExpandedSqueeze", float(self.l_eye_blink)) + self.l_eye_x = self.r_eye_x - self.client.send_message("/avatar/parameters/LeftEyeLidExpandedSqueeze", float(self.l_eye_blink)) + self.client.send_message("/avatar/parameters/LeftEyeX", self.l_eye_x) + self.left_y = eye_y + + self.client.send_message("/avatar/parameters/LeftEyeLidExpandedSqueeze", float(self.l_eye_blink)) - elif self.eye_id in [EyeId.RIGHT] and not se: #Right eye, send data to right - self.r_eye_x = eye_x - self.r_eye_blink = eye_blink + elif self.eye_id in [EyeId.RIGHT] and not se: #Right eye, send data to right + self.r_eye_x = eye_x + self.r_eye_blink = eye_blink - if self.r_eye_blink == 0.0: - if last_blink > 0.7: #when bianary blink is on, blinks may be too fast for OSC so we repeate them. - for i in range(5): - self.client.send_message("/avatar/parameters/LeftEyeLidExpandedSqueeze", float(self.r_eye_blink)) - last_blink = time.time() - last_blink - if self.config.gui_eye_falloff: - if self.l_eye_blink == 0.0: #if both eyes closed and DEF is enables, blink - self.client.send_message("/avatar/parameters/LeftEyeLidExpandedSqueeze", float(self.r_eye_blink)) - self.client.send_message("/avatar/parameters/RightEyeLidExpandedSqueeze", float(self.r_eye_blink)) - - self.r_eye_x = self.l_eye_x + if self.r_eye_blink == 0.0: + if last_blink > 0.7: #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("/avatar/parameters/LeftEyeLidExpandedSqueeze", float(self.r_eye_blink)) + last_blink = time.time() - last_blink + if self.config.gui_eye_falloff: + if self.l_eye_blink == 0.0: #if both eyes closed and DEF is enables, blink + self.client.send_message("/avatar/parameters/LeftEyeLidExpandedSqueeze", float(self.r_eye_blink)) + self.client.send_message("/avatar/parameters/RightEyeLidExpandedSqueeze", float(self.r_eye_blink)) - self.client.send_message("/avatar/parameters/RightEyeX", eye_x) - self.right_y = eye_y + self.r_eye_x = self.l_eye_x - self.client.send_message("/avatar/parameters/RightEyeLidExpandedSqueeze", float(self.r_eye_blink)) + self.client.send_message("/avatar/parameters/RightEyeX", eye_x) + self.right_y = eye_y - 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/EyesY", y) + self.client.send_message("/avatar/parameters/RightEyeLidExpandedSqueeze", float(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/EyesY", y) + + + + else: # VRC NATIVE + + if self.main_config.eye_display_id in [EyeId.RIGHT, EyeId.LEFT]: # we are in single eye mode + se = True + + 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]) # vrc native ET + + else: + se = False + + if self.eye_id in [EyeId.LEFT] and not se: # left eye, send data to left + self.l_eye_x = eye_x + self.l_eye_blink = eye_blink + + if self.l_eye_blink == 0.0: + if last_blink > 0.7: # 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)) + last_blink = time.time() - last_blink + if self.config.gui_eye_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)) + self.l_eye_x = self.r_eye_x + + self.left_y = eye_y + + + + elif self.eye_id in [EyeId.RIGHT] and not se: # Right eye, send data to right + self.r_eye_x = eye_x + self.r_eye_blink = eye_blink + + if self.r_eye_blink == 0.0: + if last_blink > 0.7: # 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)) + last_blink = time.time() - last_blink + if self.config.gui_eye_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)) + + self.r_eye_x = self.l_eye_x + + self.right_y = eye_y + + + 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.7: # 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.r_eye_blink + self.l_eye_blink) / 2 + 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: + eye_y = (self.right_y + self.left_y) / 2 + + if not se: + self.client.send_message("/tracking/eye/LeftRightVec", + [float(self.l_eye_x), float(eye_y), 0.8, float(self.r_eye_x), float(eye_y), + 0.8]) # vrc native ET (z values may need tweaking, they act like a scalar) class VRChatOSC: @@ -121,10 +193,10 @@ class VRChatOSCReceiver: try: self.server = osc_server.OSCUDPServer((self.config.gui_osc_address, int(self.config.gui_osc_receiver_port)), self.dispatcher) except: - print(f"\033[91m[ERROR] OSC Recieve 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") + print("\033[94m[INFO] Exiting OSC Receiver\033[0m") try: self.server.shutdown() except: @@ -154,4 +226,4 @@ class VRChatOSCReceiver: self.server.serve_forever() except: - print(f"\033[91m[ERROR] OSC Recieve port: {self.config.gui_osc_receiver_port} occupied.\033[0m") \ No newline at end of file + print(f"\033[91m[ERROR] OSC Receive port: {self.config.gui_osc_receiver_port} occupied.\033[0m") \ No newline at end of file diff --git a/EyeTrackApp/osc_calibrate_filter.py b/EyeTrackApp/osc_calibrate_filter.py index 1c187d1..3be9fce 100644 --- a/EyeTrackApp/osc_calibrate_filter.py +++ b/EyeTrackApp/osc_calibrate_filter.py @@ -22,7 +22,13 @@ class cal(): self.calibration_frame_counter = None self.config.calib_XOFF = cx self.config.calib_YOFF = cy - PlaySound('Audio/compleated.wav', SND_FILENAME | SND_ASYNC) + PlaySound('Audio/completed.wav', SND_FILENAME | SND_ASYNC) + if self.calibration_frame_counter == 300: + self.config.calib_XMAX = -69420 + self.config.calib_XMIN = 69420 + self.config.calib_YMAX = -69420 + self.config.calib_YMIN = 69420 + self.calibration_frame_counter -= 1 elif self.calibration_frame_counter != None: self.settings.gui_recenter_eyes = False if cx > self.config.calib_XMAX: @@ -40,7 +46,7 @@ class cal(): self.config.calib_YOFF = cy if self.ts == 0: self.settings.gui_recenter_eyes = False - PlaySound('Audio/compleated.wav', SND_FILENAME | SND_ASYNC) + PlaySound('Audio/completed.wav', SND_FILENAME | SND_ASYNC) else: self.ts = self.ts - 1 else: diff --git a/EyeTrackApp/ransac.py b/EyeTrackApp/ransac.py index 06d7c40..8683fba 100644 --- a/EyeTrackApp/ransac.py +++ b/EyeTrackApp/ransac.py @@ -20,7 +20,7 @@ @@@@@@@@@@@@@( RANSAC 3D By: Summer#2406 (Main Algorithm Engineer), Pupil Labs (pye3d), PallasNeko (Optimization) -Algorithm App Implimentations By: Prohurtz#0001, qdot (Inital App Creator) +Algorithm App Implementations By: Prohurtz#0001, qdot (Initial App Creator) Copyright (c) 2022 EyeTrackVR <3 ------------------------------------------------------------------------------------------------------ diff --git a/EyeTrackApp/settings_widget.py b/EyeTrackApp/settings_widget.py index 64fbb29..02b9458 100644 --- a/EyeTrackApp/settings_widget.py +++ b/EyeTrackApp/settings_widget.py @@ -41,6 +41,7 @@ class SettingsWidget: self.gui_BLOBP = f"-BLOBP{widget_id}-" self.gui_thresh_add = f"-THRESHADD{widget_id}-" self.gui_ROSC = f"-ROSC{widget_id}-" + self.gui_vrc_native = f"-VRCNATIVE{widget_id}-" self.gui_update_check = f"-UPDATECHECK{widget_id}-" self.gui_threshold_slider = f"-BLOBTHRESHOLD{widget_id}-" @@ -78,6 +79,13 @@ class SettingsWidget: ), ], [sg.Checkbox( + "VRC Native Eyetracking", + default=self.config.gui_vrc_native, + key=self.gui_vrc_native, + background_color='#424042', + tooltip = "Toggle VRCFT output or VRC native", + ), + sg.Checkbox( "Dual Eye Falloff", default=self.config.gui_eye_falloff, key=self.gui_eye_falloff, @@ -450,6 +458,10 @@ class SettingsWidget: self.config.gui_HSF = values[self.gui_HSF] changed = True + if self.config.gui_vrc_native != values[self.gui_vrc_native]: + self.config.gui_vrc_native = values[self.gui_vrc_native] + changed = True + if self.config.gui_DADDYP != int(values[self.gui_DADDYP]): self.config.gui_DADDYP = int(values[self.gui_DADDYP]) changed = True