Mercurial > code > home > repos > light9
annotate blender/time_sync/time_from_graph.py @ 2453:b23afde50bc2
blender addons get thier own pdm setup for now. fix time_from_graph startup race
author | drewp@bigasterisk.com |
---|---|
date | Sun, 18 May 2025 20:08:35 -0700 |
parents | src/light9/blender/time_sync/time_from_graph.py@e683b449506b |
children | 405abed9a45c |
rev | line source |
---|---|
2432 | 1 import threading |
2 import time | |
3 | |
4 import bpy # type: ignore | |
5 from bpy.app.handlers import persistent # type: ignore | |
2453
b23afde50bc2
blender addons get thier own pdm setup for now. fix time_from_graph startup race
drewp@bigasterisk.com
parents:
2436
diff
changeset
|
6 from light9_sync.asyncio_thread import startLoopInThread |
2432 | 7 from rdfdb.syncedgraph.syncedgraph import SyncedGraph |
8 | |
9 from light9 import networking | |
10 from light9.namespaces import L9 | |
11 from light9.run_local import log | |
2453
b23afde50bc2
blender addons get thier own pdm setup for now. fix time_from_graph startup race
drewp@bigasterisk.com
parents:
2436
diff
changeset
|
12 from light9.typedgraph import typedValue |
2432 | 13 |
14 | |
15 def clamp(lo, hi, x): | |
16 return max(lo, min(hi, x)) | |
17 | |
18 | |
19 UPDATE_PERIOD = 1 / 20 | |
20 | |
21 | |
22 class Sync: | |
23 lock = threading.Lock() | |
24 duration: float = 1 | |
25 wallStartTime: float | None = None | |
26 pausedSongTime: float | None = None | |
2433 | 27 playing = False |
2432 | 28 latestTime: float |
29 | |
30 def __init__(self): | |
31 # main thread | |
32 self.lastSetFrame = -1 | |
33 self.lastGraphFrame = -1 | |
34 startLoopInThread(self.task()) | |
2453
b23afde50bc2
blender addons get thier own pdm setup for now. fix time_from_graph startup race
drewp@bigasterisk.com
parents:
2436
diff
changeset
|
35 # need persistent because `blender --addons ...` seems to start addon |
b23afde50bc2
blender addons get thier own pdm setup for now. fix time_from_graph startup race
drewp@bigasterisk.com
parents:
2436
diff
changeset
|
36 # before loading scene. |
b23afde50bc2
blender addons get thier own pdm setup for now. fix time_from_graph startup race
drewp@bigasterisk.com
parents:
2436
diff
changeset
|
37 bpy.app.timers.register(self.update, persistent=True) |
2432 | 38 bpy.app.handlers.frame_change_post.append(self.on_frame_change_post) |
39 | |
2433 | 40 ## updates from graph -> self |
2432 | 41 |
42 async def task(self): | |
43 # bg thread with asyncio loop | |
44 self.graph = SyncedGraph(networking.rdfdb.url, "time_sync") | |
45 self.graph.addHandler(self.syncFromGraph) | |
46 | |
47 def syncFromGraph(self): | |
48 # bg thread | |
49 with self.lock: | |
50 asco = L9['ascoltami'] | |
2433 | 51 self.wallStartTime = typedValue(float | None, self.graph, asco, L9['wallStartTime']) |
52 self.pausedSongTime = typedValue(float | None, self.graph, asco, L9['pausedSongTime']) | |
53 self.duration = typedValue(float | None, self.graph, asco, L9['duration']) or 1.0 | |
2436
e683b449506b
blender effect that sets lights to match blender lights
drewp@bigasterisk.com
parents:
2434
diff
changeset
|
54 self.playing = typedValue(bool | None, self.graph, asco, L9['playing']) or False |
2432 | 55 |
56 def currentTime(self) -> float | None: | |
57 if self.wallStartTime is not None: | |
58 return time.time() - self.wallStartTime | |
59 if self.pausedSongTime is not None: | |
60 return self.pausedSongTime | |
61 log.warn('no time data') | |
62 return None | |
63 | |
64 ## graph time -> blender time | |
65 | |
2453
b23afde50bc2
blender addons get thier own pdm setup for now. fix time_from_graph startup race
drewp@bigasterisk.com
parents:
2436
diff
changeset
|
66 # @persistent |
2432 | 67 def update(self): |
68 # main thread? wherever blender runs timers | |
69 if self.playing: | |
70 with self.lock: | |
71 t = self.currentTime() | |
72 if t is not None: | |
73 self.setBlenderTime(t, self.duration) | |
74 return UPDATE_PERIOD | |
75 | |
76 def setBlenderTime(self, t: float, duration: float): | |
77 scene = bpy.context.scene | |
78 fps = scene.render.fps | |
79 scene.frame_start = 0 | |
80 scene.frame_end = int(duration * fps) | |
81 fr = int(clamp(t, 0, duration) * fps) | |
82 self.lastSetFrame = fr | |
83 scene.frame_set(fr) | |
84 | |
85 ## blender time -> graph time | |
86 | |
87 @persistent | |
88 def on_frame_change_post(self, scene, deps): | |
89 if scene.frame_current != self.lastSetFrame: | |
90 # self.setGraphTime(scene.frame_current / scene.render.fps, self.duration) | |
91 self.lastSetFrame = scene.frame_current | |
92 t = scene.frame_current / scene.render.fps | |
93 self.setInGraph(t) | |
94 | |
95 def setInGraph(self, t: float): | |
2434
9b101d8bd7ea
discover annotated lights in blender; send their color to the graph (temporary stmt)
drewp@bigasterisk.com
parents:
2433
diff
changeset
|
96 log.warning(f'todo: set graph to {t:.2f}') |