Moved Parameter definition from keyframe to track

This commit is contained in:
Maximilian Giller 2025-09-21 16:50:34 +02:00
parent 4b598679f6
commit 5970b70d7e

View file

@ -161,9 +161,6 @@ class Keyframe:
time: Decimal time: Decimal
"""Point of time of the keyframe. Stored as decimal for high precision.""" """Point of time of the keyframe. Stored as decimal for high precision."""
parameter: Parameter
"""Parameter targeted by frame value."""
value: KeyframeValue = None value: KeyframeValue = None
"""Targeted state value reached by reaching the keyframe.""" """Targeted state value reached by reaching the keyframe."""
@ -175,27 +172,17 @@ class Keyframe:
class EngineKeyframe: class EngineKeyframe:
"""A keyframe for engine use during rendering.""" """A keyframe for engine use during rendering."""
keyframes: list[Keyframe] frame: Keyframe
"""Reference keyframes.""" """Reference keyframe."""
delta: Decimal delta: Decimal
"""Remaining time in seconds relative to previous keyframes.""" """Remaining time in seconds relative to previous keyframes."""
def __iter__(self) -> Iterator[Keyframe]:
return iter(self.keyframes)
def get(self, parameter: Parameter) -> Keyframe:
"""Get keyframe for parameter found among the keyframes. Assumed to exist only once. Exception raised, if parameter not defined by keyframes."""
for k in self.keyframes:
if k.parameter == parameter:
return k
raise ValueError(f"Parameter [{parameter}] not given among keyframes.")
@dataclass_json @dataclass_json
@dataclass @dataclass
class Track: class Track:
"""Contains a sequence of keyframes for specified fixtures.""" """Contains a sequence of keyframes for specified fixtures and parameter."""
id: str id: str
"""Unique identifier for track.""" """Unique identifier for track."""
@ -203,6 +190,9 @@ class Track:
name: str name: str
"""Human readable name.""" """Human readable name."""
parameter: Parameter
"""Parameter targeted by frame value."""
fixture_ids: list[str] fixture_ids: list[str]
"""Fixtures by ids targeted by track.""" """Fixtures by ids targeted by track."""
@ -218,10 +208,10 @@ class EngineTrack:
"""Reference track.""" """Reference track."""
keyframes: list[EngineKeyframe] = field(default_factory=list) keyframes: list[EngineKeyframe] = field(default_factory=list)
"""Relative keyframes of track.""" """Relative engine keyframes of track."""
current: EngineKeyframe | None = None current: EngineKeyframe | None = None
"""Keyframes before the next keyframes. Trigger time has been reached.""" """Keyframe before the next keyframe. Trigger time has been reached."""
@property @property
def next(self) -> EngineKeyframe | None: def next(self) -> EngineKeyframe | None:
@ -238,20 +228,12 @@ class EngineTrack:
def __post_init__(self): def __post_init__(self):
# Calculate relative keyframes # Calculate relative keyframes
sorted_keyframes = sorted(self.track.keyframes, key=lambda k: k.time) sorted_keyframes = sorted(self.track.keyframes, key=lambda k: k.time)
prev_time: Decimal = Decimal.from_float(0) # Make keyframe time relative for engine use
curr_time: Decimal = Decimal.from_float(0) for previous, current in zip([None, *sorted_keyframes[1:]], sorted_keyframes):
keyframes = [] delta = current.time
for k, next in zip(sorted_keyframes, [*sorted_keyframes[1:], None]): if previous:
curr_time = k.time delta -= previous.time
keyframes.append(k) self.keyframes.append(EngineKeyframe(current, delta))
if next is None or k.time != next.time:
self.keyframes.append(EngineKeyframe(keyframes, curr_time - prev_time))
if next is not None:
keyframes = []
prev_time = curr_time
curr_time = next.time
def step(self, step_size: Decimal): def step(self, step_size: Decimal):
"""Step keyframes forward by given step.""" """Step keyframes forward by given step."""
@ -340,8 +322,9 @@ if __name__ == "__main__":
Track( Track(
"89idf", "89idf",
"Ceiling flicker", "Ceiling flicker",
Parameter.BRIGHTNESS,
["98iwd"], ["98iwd"],
[Keyframe(Decimal.from_float(0), Parameter.BRIGHTNESS, 1)], [Keyframe(Decimal.from_float(0), 1)],
) )
], ],
) )