From db560197472070167707b8b522b1f9083682ec75 Mon Sep 17 00:00:00 2001 From: misyaguziya Date: Tue, 7 May 2024 16:43:05 +0900 Subject: [PATCH] =?UTF-8?q?=F0=9F=91=8D=EF=B8=8F[Update]=20Model=20:=20ren?= =?UTF-8?q?ame=20overlay=5F2.py=20->=20overlay.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- model.py | 2 +- models/overlay/overlay.py | 345 +++++++++++++++--------------------- models/overlay/overlay_2.py | 205 --------------------- 3 files changed, 148 insertions(+), 404 deletions(-) delete mode 100644 models/overlay/overlay_2.py diff --git a/model.py b/model.py index 251adf03..39eacd56 100644 --- a/model.py +++ b/model.py @@ -26,7 +26,7 @@ from models.translation.translation_languages import translation_lang from models.transcription.transcription_languages import transcription_lang from models.translation.translation_utils import checkCTranslate2Weight from models.transcription.transcription_whisper import checkWhisperWeight -from models.overlay.overlay_2 import Overlay +from models.overlay.overlay import Overlay from models.overlay.overlay_image import OverlayImage from config import config diff --git a/models/overlay/overlay.py b/models/overlay/overlay.py index a2787151..68918baa 100644 --- a/models/overlay/overlay.py +++ b/models/overlay/overlay.py @@ -1,18 +1,15 @@ -import psutil +import os +import ctypes +from psutil import process_iter +# from os import path as os_path import ctypes import time -import asyncio import openvr from PIL import Image +# from queue import Queue +from threading import Thread +import OverlayImage -def checkSteamvrRunning(): - for proc in psutil.process_iter(): - if "vrserver.exe" == proc.name().lower(): - return True - return False - -# This code is based on the following source: -# [GOpy](https://github.com/MeroFune/GOpy) def mat34Id(): arr = openvr.HmdMatrix34_t() arr[0][0] = 1 @@ -20,51 +17,91 @@ def mat34Id(): arr[2][2] = 1 return arr -class UIElement: - def __init__(self, overlayRoot, key: str, name: str, settings: dict = None) -> None: - """ - pos is a 2-tuple representing (x, y) normalized position of the overlay on the screen - """ - self.overlay = overlayRoot - self.overlayKey = key - self.overlayName = name +class Overlay: + def __init__(self, x, y , depth, fade_time, fade_interval, opacity, ui_scaling): + self.initialized = False + settings = { + "color": [1, 1, 1], + "opacity": opacity, + "x_pos": x, + "y_pos": y, + "depth": depth, + "fade_time": fade_time, + "fade_interval": fade_interval, + "ui_scaling": ui_scaling, + } self.settings = settings - self.handle = self.overlay.createOverlay(self.overlayKey, self.overlayName) + self.system = None + self.overlay = None + self.handle = None + self.lastUpdate = time.monotonic() + self.thread_overlay = None + self.fadeRatio = 1 + self.loop = True - self.setImage(Image.new("RGBA", (1, 1), (0, 0, 0, 0))) # blank image for default - self.setColor(self.settings['Color']) - self.setTransparency(self.settings['Transparency']) - self.overlay.setOverlayWidthInMeters( - self.handle, - self.settings['Ui_scaling'] - ) + def init(self): + try: + self.system = openvr.init(openvr.VRApplication_Background) + self.overlay = openvr.IVROverlay() + self.handle = self.overlay.createOverlay("Overlay_Speaker2log", "SOverlay_Speaker2log_UI") - self.updatePosition() - self.overlay.showOverlay(self.handle) + self.updateImage(Image.new("RGBA", (1, 1), (0, 0, 0, 0))) + self.updateColor(self.settings["color"]) + self.updateOpacity(self.settings["opacity"]) + self.updateUiScaling(self.settings["Ui_scaling"]) + self.updatePosition( + (self.settings["x_pos"], self.settings["y_pos"]), + self.settings["depth"] + ) + self.overlay.showOverlay(self.handle) + self.initialized = True + except Exception as e: + print("Could not initialise OpenVR", e) - def setImage(self, img): - # configure overlay appearance + def updateImage(self, img): width, height = img.size img = img.tobytes() img = (ctypes.c_char * len(img)).from_buffer_copy(img) self.overlay.setOverlayRaw(self.handle, img, width, height, 4) + self.updateOpacity(self.settings["opacity"]) + self.lastUpdate = time.monotonic() - def setColor(self, col): + def clearImage(self): + self.updateImage(Image.new("RGBA", (1, 1), (0, 0, 0, 0))) + + def updateColor(self, col): """ col is a 3-tuple representing (r, g, b) """ - self.overlay.setOverlayColor(self.handle, col[0], col[1], col[2]) + self.settings["color"] = col + r, g, b = self.settings["color"] + self.overlay.setOverlayColor(self.handle, r, g, b) - def setTransparency(self, a): - self.overlay.setOverlayAlpha(self.handle, a) + def updateOpacity(self, opacity, with_fade=False): + self.settings["opacity"] = opacity + self.overlay.setOverlayAlpha( + self.handle, + self.settings["opacity"] if with_fade is False else self.settings["opacity"] * self.fadeRatio) + + def updateUiScaling(self, ui_scaling): + self.settings['ui_scaling'] = ui_scaling + self.overlay.setOverlayWidthInMeters(self.handle, self.settings['ui_scaling']) + + def updatePosition(self, pos, depth): + """ + pos is a 2-tuple representing normalized (x, y) + depth is a float representing the depth of the icon plane + """ + self.settings["x_pos"] = pos[0] + self.settings["y_pos"] = pos[1] + self.settings["depth"] = depth - def updatePosition(self): self.transform = mat34Id() # no rotation required for HMD attachment # assign position - self.transform[0][3] = self.settings["Normalized_icon_X_position"] * self.settings['Icon_plane_depth'] - self.transform[1][3] = self.settings["Normalized_icon_Y_position"] * self.settings['Icon_plane_depth'] - self.transform[2][3] = - self.settings['Icon_plane_depth'] + self.transform[0][3] = self.settings["x_pos"] * self.settings['depth'] + self.transform[1][3] = self.settings["y_pos"] * self.settings['depth'] + self.transform[2][3] = - self.settings['depth'] self.overlay.setOverlayTransformTrackedDeviceRelative( self.handle, @@ -72,127 +109,11 @@ class UIElement: self.transform ) - def setPosition(self, pos): - """ - pos is a 2-tuple representing normalized (x, y) - """ - self.settings["Normalized_icon_X_position"] = pos[0] - self.settings["Normalized_icon_Y_position"] = pos[1] + def updateDisplayDuration(self, display_duration): + self.settings['display_duration'] = display_duration - def setDepth(self, depth): - self.settings["Icon_plane_depth"] = depth - - def setUiScaling(self, ui_scaling): - self.overlay.setOverlayWidthInMeters( - self.handle, - ui_scaling, - ) - -class UIManager: - def __init__(self, overlay_key, overlay_name, settings): - self.overlay = openvr.IVROverlay() - self.settings = settings - self.overlayUI = UIElement( - self.overlay, - overlay_key, - overlay_name, - self.settings, - ) - self.fadeRatio = 1 - self.lastUpdate = time.monotonic() - - def update(self): - currTime = time.monotonic() - if self.settings['Fade_interval'] != 0: - self.evaluateTransparencyFade(self.lastUpdate, currTime) - - def uiClear(self): - self.overlayUI.setImage(Image.new("RGBA", (1, 1), (0, 0, 0, 0))) - self.overlayUI.setTransparency(self.settings['Transparency']) - self.lastUpdate = time.monotonic() - - def uiUpdate(self, img): - self.overlayUI.setImage(img) - self.overlayUI.setTransparency(self.settings['Transparency']) - self.lastUpdate = time.monotonic() - - def evaluateTransparencyFade(self, lastUpdate, currentTime): - if (currentTime - lastUpdate) > self.settings['Fade_time']: - timeThroughInterval = currentTime - lastUpdate - self.settings['Fade_time'] - self.fadeRatio = 1 - timeThroughInterval / self.settings['Fade_interval'] - if self.fadeRatio < 0: - self.fadeRatio = 0 - - self.overlayUI.setTransparency(self.fadeRatio * self.settings['Transparency']) - - def posUpdate(self): - self.overlayUI.updatePosition() - - def setPosition(self, pos): - self.overlayUI.setPosition(pos) - - def setDepth(self, depth): - self.overlayUI.setDepth(depth) - - def setFadeTime(self, fade_time): - self.settings["Fade_time"] = fade_time - - def setFadeInterval(self, fade_interval): - self.settings["Fade_interval"] = fade_interval - - def setUiScaling(self, ui_scaling): - self.overlayUI.setUiScaling(ui_scaling) - - def setTransparency(self, transparency): - self.settings["Transparency"] = transparency - self.overlayUI.setTransparency(self.fadeRatio * self.settings['Transparency']) - -class Overlay: - def __init__(self, x, y , depth, fade_time, fade_interval, transparency, ui_scaling): - self.initialized = False - settings = { - "Color": [1, 1, 1], - "Transparency": transparency, - "Normalized_icon_X_position": x, - "Normalized_icon_Y_position": y, - "Icon_plane_depth": depth, - "Fade_time": fade_time, - "Fade_interval": fade_interval, - "Ui_scaling": ui_scaling, - } - self.settings = settings - self.system = None - - def init(self): - try: - if checkSteamvrRunning() is True: - self.system = openvr.init(openvr.VRApplication_Background) - self.initialized = True - except Exception as e: - print("Could not initialise OpenVR") - print(e) - - async def mainLoop(self): - while self.checkActive() is True: - startTime = time.monotonic() - self.uiManager.update() - - sleepTime = (1 / 60) - (time.monotonic() - startTime) - if sleepTime > 0: - await asyncio.sleep(sleepTime) - - async def initMain(self): - if self.initialized is True: - self.uiManager = UIManager("Overlay_Speaker2log", "SOverlay_Speaker2log_UI", self.settings) - await self.mainLoop() - - def startOverlay(self): - asyncio.run(self.initMain()) - - def shutdown(self): - self.system = None - self.initialized = False - openvr.shutdown() + def updateFadeoutDuration(self, fadeout_duration): + self.settings['fadeout_duration'] = fadeout_duration def checkActive(self): try: @@ -200,7 +121,6 @@ class Overlay: new_event = openvr.VREvent_t() while self.system.pollNextEvent(new_event): if new_event.eventType == openvr.VREvent_Quit: - self.shutdown() return False return True except Exception as e: @@ -208,49 +128,78 @@ class Overlay: print(e) return False + def evaluateOpacityFade(self, lastUpdate, currentTime): + if (currentTime - lastUpdate) > self.settings['display_duration']: + timeThroughInterval = currentTime - lastUpdate - self.settings['display_duration'] + self.fadeRatio = 1 - timeThroughInterval / self.settings['fadeout_duration'] + if self.fadeRatio < 0: + self.fadeRatio = 0 + self.overlay.setOverlayAlpha(self.handle, self.fadeRatio * self.settings['opacity']) + + def update(self): + currTime = time.monotonic() + if self.settings['fadeout_duration'] != 0: + self.evaluateOpacityFade(self.lastUpdate, currTime) + else: + self.updateOpacity(self.settings["opacity"]) + + def mainloop(self): + self.loop = True + while self.checkActive() is True and self.loop is True: + startTime = time.monotonic() + self.update() + sleepTime = (1 / 16) - (time.monotonic() - startTime) + if sleepTime > 0: + time.sleep(sleepTime) + self.shutdownOverlay() + + def main(self): + self.init() + if self.initialized is True: + self.mainloop() + + def startOverlay(self): + self.thread_overlay = Thread(target=self.main) + self.thread_overlay.daemon = True + self.thread_overlay.start() + + def setStopOverlay(self): + self.loop = False + + def shutdownOverlay(self): + if self.thread_overlay is not None: + self.thread_overlay.join() + self.thread_overlay = None + if self.overlay is not None: + self.overlay.destroyOverlay(self.handle) + self.overlay = None + if self.system is not None: + openvr.shutdown() + self.system = None + self.initialized = False + + @staticmethod + def checkSteamvrRunning() -> bool: + _proc_name = "vrmonitor.exe" if os.name == 'nt' else "vrmonitor" + return _proc_name in (p.name() for p in process_iter()) + if __name__ == '__main__': from overlay_image import OverlayImage - from threading import Thread, Event - class threadFnc(Thread): - def __init__(self, fnc, end_fnc=None, daemon=True, *args, **kwargs): - super(threadFnc, self).__init__(daemon=daemon, *args, **kwargs) - self.fnc = fnc - self.end_fnc = end_fnc - self._stop = Event() - def stop(self): - self._stop.set() - def stopped(self): - return self._stop.is_set() - def run(self): - while True: - if self.stopped(): - if callable(self.end_fnc): - self.end_fnc() - return - self.fnc(*self._args, **self._kwargs) - - overlay = Overlay(0, 0, 1, 1, 1, 1, 1) overlay_image = OverlayImage() - if overlay.initialized is False: - overlay.init() - if overlay.initialized is True: - t = threadFnc(overlay.startOverlay) - t.start() + for i in range(100): + print(i) + overlay = Overlay(0, 0, 1, 1, 1, 1, 1) + overlay.startOverlay() + time.sleep(1) - time.sleep(1) - img = overlay_image.createOverlayImageShort("こんにちは、世界!さようなら", "Japanese", "Hello,World!Goodbye", "Japanese", ui_type="sakura") - # img = overlay_image.createOverlayImageShort("こんにちは、世界!さようなら", "Japanese", ui_type="sakura") - if overlay.initialized is True: - overlay.uiManager.uiUpdate(img) - time.sleep(10) + # Example usage + img = overlay_image.createOverlayImageShort("こんにちは、世界!さようなら", "Japanese", "Hello,World!Goodbye", "Japanese", ui_type="sakura") + overlay.updateImage(img) + time.sleep(0.5) - img = overlay_image.createOverlayImageShort("こんにちは、世界!さようなら", "Japanese", "안녕하세요, 세계!안녕", "Korean") - if overlay.initialized is True: - overlay.uiManager.uiUpdate(img) - time.sleep(10) + img = overlay_image.createOverlayImageShort("こんにちは、世界!さようなら", "Japanese", "Hello,World!Goodbye", "Japanese") + overlay.updateImage(img) + time.sleep(0.5) - img = overlay_image.createOverlayImageShort("こんにちは、世界!さようなら", "Japanese", "你好世界!再见", "Chinese Simplified") - if overlay.initialized is True: - overlay.uiManager.uiUpdate(img) - time.sleep(10) \ No newline at end of file + overlay.shutdown() diff --git a/models/overlay/overlay_2.py b/models/overlay/overlay_2.py deleted file mode 100644 index 68918baa..00000000 --- a/models/overlay/overlay_2.py +++ /dev/null @@ -1,205 +0,0 @@ -import os -import ctypes -from psutil import process_iter -# from os import path as os_path -import ctypes -import time -import openvr -from PIL import Image -# from queue import Queue -from threading import Thread -import OverlayImage - -def mat34Id(): - arr = openvr.HmdMatrix34_t() - arr[0][0] = 1 - arr[1][1] = 1 - arr[2][2] = 1 - return arr - -class Overlay: - def __init__(self, x, y , depth, fade_time, fade_interval, opacity, ui_scaling): - self.initialized = False - settings = { - "color": [1, 1, 1], - "opacity": opacity, - "x_pos": x, - "y_pos": y, - "depth": depth, - "fade_time": fade_time, - "fade_interval": fade_interval, - "ui_scaling": ui_scaling, - } - self.settings = settings - self.system = None - self.overlay = None - self.handle = None - self.lastUpdate = time.monotonic() - self.thread_overlay = None - self.fadeRatio = 1 - self.loop = True - - def init(self): - try: - self.system = openvr.init(openvr.VRApplication_Background) - self.overlay = openvr.IVROverlay() - self.handle = self.overlay.createOverlay("Overlay_Speaker2log", "SOverlay_Speaker2log_UI") - - self.updateImage(Image.new("RGBA", (1, 1), (0, 0, 0, 0))) - self.updateColor(self.settings["color"]) - self.updateOpacity(self.settings["opacity"]) - self.updateUiScaling(self.settings["Ui_scaling"]) - self.updatePosition( - (self.settings["x_pos"], self.settings["y_pos"]), - self.settings["depth"] - ) - self.overlay.showOverlay(self.handle) - self.initialized = True - except Exception as e: - print("Could not initialise OpenVR", e) - - def updateImage(self, img): - width, height = img.size - img = img.tobytes() - img = (ctypes.c_char * len(img)).from_buffer_copy(img) - self.overlay.setOverlayRaw(self.handle, img, width, height, 4) - self.updateOpacity(self.settings["opacity"]) - self.lastUpdate = time.monotonic() - - def clearImage(self): - self.updateImage(Image.new("RGBA", (1, 1), (0, 0, 0, 0))) - - def updateColor(self, col): - """ - col is a 3-tuple representing (r, g, b) - """ - self.settings["color"] = col - r, g, b = self.settings["color"] - self.overlay.setOverlayColor(self.handle, r, g, b) - - def updateOpacity(self, opacity, with_fade=False): - self.settings["opacity"] = opacity - self.overlay.setOverlayAlpha( - self.handle, - self.settings["opacity"] if with_fade is False else self.settings["opacity"] * self.fadeRatio) - - def updateUiScaling(self, ui_scaling): - self.settings['ui_scaling'] = ui_scaling - self.overlay.setOverlayWidthInMeters(self.handle, self.settings['ui_scaling']) - - def updatePosition(self, pos, depth): - """ - pos is a 2-tuple representing normalized (x, y) - depth is a float representing the depth of the icon plane - """ - self.settings["x_pos"] = pos[0] - self.settings["y_pos"] = pos[1] - self.settings["depth"] = depth - - self.transform = mat34Id() # no rotation required for HMD attachment - - # assign position - self.transform[0][3] = self.settings["x_pos"] * self.settings['depth'] - self.transform[1][3] = self.settings["y_pos"] * self.settings['depth'] - self.transform[2][3] = - self.settings['depth'] - - self.overlay.setOverlayTransformTrackedDeviceRelative( - self.handle, - openvr.k_unTrackedDeviceIndex_Hmd, - self.transform - ) - - def updateDisplayDuration(self, display_duration): - self.settings['display_duration'] = display_duration - - def updateFadeoutDuration(self, fadeout_duration): - self.settings['fadeout_duration'] = fadeout_duration - - def checkActive(self): - try: - if self.system is not None and self.initialized is True: - new_event = openvr.VREvent_t() - while self.system.pollNextEvent(new_event): - if new_event.eventType == openvr.VREvent_Quit: - return False - return True - except Exception as e: - print("Could not check SteamVR running") - print(e) - return False - - def evaluateOpacityFade(self, lastUpdate, currentTime): - if (currentTime - lastUpdate) > self.settings['display_duration']: - timeThroughInterval = currentTime - lastUpdate - self.settings['display_duration'] - self.fadeRatio = 1 - timeThroughInterval / self.settings['fadeout_duration'] - if self.fadeRatio < 0: - self.fadeRatio = 0 - self.overlay.setOverlayAlpha(self.handle, self.fadeRatio * self.settings['opacity']) - - def update(self): - currTime = time.monotonic() - if self.settings['fadeout_duration'] != 0: - self.evaluateOpacityFade(self.lastUpdate, currTime) - else: - self.updateOpacity(self.settings["opacity"]) - - def mainloop(self): - self.loop = True - while self.checkActive() is True and self.loop is True: - startTime = time.monotonic() - self.update() - sleepTime = (1 / 16) - (time.monotonic() - startTime) - if sleepTime > 0: - time.sleep(sleepTime) - self.shutdownOverlay() - - def main(self): - self.init() - if self.initialized is True: - self.mainloop() - - def startOverlay(self): - self.thread_overlay = Thread(target=self.main) - self.thread_overlay.daemon = True - self.thread_overlay.start() - - def setStopOverlay(self): - self.loop = False - - def shutdownOverlay(self): - if self.thread_overlay is not None: - self.thread_overlay.join() - self.thread_overlay = None - if self.overlay is not None: - self.overlay.destroyOverlay(self.handle) - self.overlay = None - if self.system is not None: - openvr.shutdown() - self.system = None - self.initialized = False - - @staticmethod - def checkSteamvrRunning() -> bool: - _proc_name = "vrmonitor.exe" if os.name == 'nt' else "vrmonitor" - return _proc_name in (p.name() for p in process_iter()) - -if __name__ == '__main__': - from overlay_image import OverlayImage - overlay_image = OverlayImage() - - for i in range(100): - print(i) - overlay = Overlay(0, 0, 1, 1, 1, 1, 1) - overlay.startOverlay() - time.sleep(1) - - # Example usage - img = overlay_image.createOverlayImageShort("こんにちは、世界!さようなら", "Japanese", "Hello,World!Goodbye", "Japanese", ui_type="sakura") - overlay.updateImage(img) - time.sleep(0.5) - - img = overlay_image.createOverlayImageShort("こんにちは、世界!さようなら", "Japanese", "Hello,World!Goodbye", "Japanese") - overlay.updateImage(img) - time.sleep(0.5) - - overlay.shutdown()