From 28073fbd81cfa68a6fa373770f0c79e015262927 Mon Sep 17 00:00:00 2001 From: misyaguziya Date: Tue, 7 May 2024 16:40:45 +0900 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=A7=20[WIP/TEST]=20Model=20:=20Overlay?= =?UTF-8?q?=20=E3=83=AA=E3=83=95=E3=82=A1=E3=82=AF=E3=82=BF=E3=83=AA?= =?UTF-8?q?=E3=83=B3=E3=82=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- img/test_chatbox.png | Bin 33053 -> 0 bytes model.py | 15 ++--- models/overlay/overlay_2.py | 129 +++++++++++++++++------------------- 3 files changed, 66 insertions(+), 78 deletions(-) delete mode 100644 img/test_chatbox.png diff --git a/img/test_chatbox.png b/img/test_chatbox.png deleted file mode 100644 index 9d96629967f0fae35ef0392ab6eb3b7dfaf43e09..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33053 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%0AfkfgHl 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 diff --git a/model.py b/model.py index 6c220c41..251adf03 100644 --- a/model.py +++ b/model.py @@ -613,25 +613,24 @@ class Model: def updateOverlayPosition(self): pos = (config.OVERLAY_SMALL_LOG_SETTINGS["x_pos"], config.OVERLAY_SMALL_LOG_SETTINGS["y_pos"]) - self.overlay.setPosition(pos) depth = config.OVERLAY_SMALL_LOG_SETTINGS["depth"] - self.overlay.setDepth(depth) + self.overlay.updatePosition(pos, depth) def updateOverlayTimes(self): display_duration = config.OVERLAY_SMALL_LOG_SETTINGS["display_duration"] - self.overlay.setFadeTime(display_duration) + self.overlay.updateDisplayDuration(display_duration) fadeout_duration = config.OVERLAY_SMALL_LOG_SETTINGS["fadeout_duration"] - self.overlay.setFadeInterval(fadeout_duration) + self.overlay.updateFadeoutDuration(fadeout_duration) def updateOverlayImageOpacity(self): opacity = config.OVERLAY_SETTINGS["opacity"] - self.overlay.setTransparency(opacity) + self.overlay.updateOpacity(opacity, with_fade=True) def updateOverlayImageUiScaling(self): ui_scaling = config.OVERLAY_SETTINGS["ui_scaling"] - self.overlay.setUiScaling(ui_scaling) + self.overlay.updateUiScaling(ui_scaling) - def shutdownOverlay(self): - self.overlay.shutdown() + def stopOverlay(self): + self.overlay.setStopOverlay() model = Model() \ No newline at end of file diff --git a/models/overlay/overlay_2.py b/models/overlay/overlay_2.py index 929be276..68918baa 100644 --- a/models/overlay/overlay_2.py +++ b/models/overlay/overlay_2.py @@ -8,6 +8,7 @@ import openvr from PIL import Image # from queue import Queue from threading import Thread +import OverlayImage def mat34Id(): arr = openvr.HmdMatrix34_t() @@ -17,25 +18,26 @@ def mat34Id(): return arr class Overlay: - def __init__(self, x, y , depth, fade_time, fade_interval, transparency, ui_scaling): + def __init__(self, x, y , depth, fade_time, fade_interval, opacity, 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, + "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.image_queue = Queue() self.lastUpdate = time.monotonic() self.thread_overlay = None + self.fadeRatio = 1 + self.loop = True def init(self): try: @@ -44,76 +46,62 @@ class Overlay: self.handle = self.overlay.createOverlay("Overlay_Speaker2log", "SOverlay_Speaker2log_UI") self.updateImage(Image.new("RGBA", (1, 1), (0, 0, 0, 0))) - self.setColor(self.settings['Color']) - self.updateColor() - self.setTransparency(self.settings['Transparency']) - self.updateTransparency() - self.setUiScaling(self.settings['Ui_scaling']) - self.updateUiScaling() - self.setPosition((self.settings["Normalized_icon_X_position"], self.settings["Normalized_icon_Y_position"])) - self.updatePosition() + 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): - # self.image_queue.put(img) - def updateImage(self, img): - # _ = self.image_queue.get() - # img = Image.open(os_path.join(os_path.dirname(os_path.dirname(os_path.dirname(__file__))), "img", "test_chatbox.png")) 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.updateTransparency() + self.updateOpacity(self.settings["opacity"]) self.lastUpdate = time.monotonic() def clearImage(self): - # while self.image_queue.empty() is False: - # self.image_queue.get() self.updateImage(Image.new("RGBA", (1, 1), (0, 0, 0, 0))) - def setColor(self, col): + def updateColor(self, col): """ col is a 3-tuple representing (r, g, b) """ - self.settings["Color"] = col - - def updateColor(self): - r, g, b = self.settings["Color"] + self.settings["color"] = col + r, g, b = self.settings["color"] self.overlay.setOverlayColor(self.handle, r, g, b) - def setTransparency(self, transparency): - self.settings['Transparency'] = transparency + 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 updateTransparency(self): - self.overlay.setOverlayAlpha(self.handle, self.settings['Transparency']) + def updateUiScaling(self, ui_scaling): + self.settings['ui_scaling'] = ui_scaling + self.overlay.setOverlayWidthInMeters(self.handle, self.settings['ui_scaling']) - def setUiScaling(self, ui_scaling): - self.settings['Ui_scaling'] = ui_scaling - - def updateUiScaling(self): - self.overlay.setOverlayWidthInMeters(self.handle, self.settings['Ui_scaling']) - - def setPosition(self, pos): + 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["Normalized_icon_X_position"] = pos[0] - self.settings["Normalized_icon_Y_position"] = pos[1] + self.settings["x_pos"] = pos[0] + self.settings["y_pos"] = pos[1] + self.settings["depth"] = depth - def setDepth(self, depth): - self.settings["Icon_plane_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, @@ -121,11 +109,11 @@ class Overlay: self.transform ) - def setFadeTime(self, fade_time): - self.settings['Fade_time'] = fade_time + def updateDisplayDuration(self, display_duration): + self.settings['display_duration'] = display_duration - def setFadeInterval(self, fade_interval): - self.settings['Fade_interval'] = fade_interval + def updateFadeoutDuration(self, fadeout_duration): + self.settings['fadeout_duration'] = fadeout_duration def checkActive(self): try: @@ -140,32 +128,30 @@ class Overlay: print(e) return False - 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'] + 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['Transparency']) + self.overlay.setOverlayAlpha(self.handle, self.fadeRatio * self.settings['opacity']) def update(self): - # self.updateUiScaling() - # self.updatePosition() - currTime = time.monotonic() - if self.settings['Fade_interval'] != 0: - self.evaluateTransparencyFade(self.lastUpdate, currTime) + if self.settings['fadeout_duration'] != 0: + self.evaluateOpacityFade(self.lastUpdate, currTime) else: - self.updateTransparency() + self.updateOpacity(self.settings["opacity"]) def mainloop(self): - while self.checkActive() is True: + 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.shutdown() + self.shutdownOverlay() def main(self): self.init() @@ -177,9 +163,12 @@ class Overlay: self.thread_overlay.daemon = True self.thread_overlay.start() - def shutdown(self): + def setStopOverlay(self): + self.loop = False + + def shutdownOverlay(self): if self.thread_overlay is not None: - ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(self.thread_overlay.ident), ctypes.py_object(SystemExit)) + self.thread_overlay.join() self.thread_overlay = None if self.overlay is not None: self.overlay.destroyOverlay(self.handle)