workshop rework

This commit is contained in:
Vysyr committed 2026-10-31 17:03:41 +01:00
1 parent a3a80dfa16
commit fb39e290c0
115 files changed
+1865 -497

No files matched your search

+81
View File
@@ -0,0 +1,81 @@
"""Frame-based Sequencer helpers. Ranges are [start, end), rotations roll/pitch/yaw."""
import unreal
from .paths import GENERATED, slug
class Sequence:
def __init__(self, scene, name="Shot", fps=24, frames=48):
if not isinstance(fps, int) or fps < 1 or not isinstance(frames, int) or frames < 1:
raise ValueError("FPS i liczba klatek musza byc dodatnimi liczbami calkowitymi.")
self.scene, self.fps, self.frames = scene, fps, frames
path = f"{GENERATED}/{scene.name}/LS_{slug(name)}"
self.asset = unreal.load_asset(path)
if self.asset and unreal.LevelSequenceEditorBlueprintLibrary.get_current_level_sequence() == self.asset:
unreal.LevelSequenceEditorBlueprintLibrary.close_level_sequence()
if self.asset is None:
self.asset = unreal.AssetToolsHelpers.get_asset_tools().create_asset(
"LS_" + name, f"{GENERATED}/{scene.name}", unreal.LevelSequence,
unreal.LevelSequenceFactoryNew())
for binding in self.asset.get_bindings():
binding.remove()
for track in self.asset.get_tracks():
self.asset.remove_track(track)
self.asset.set_display_rate(unreal.FrameRate(fps, 1))
self.asset.set_playback_start(0)
self.asset.set_playback_end(frames)
self._bindings = {}
self._transforms = {}
def bind(self, actor):
key = actor.get_path_name()
if key not in self._bindings:
self._bindings[key] = self.asset.add_possessable(actor)
return self._bindings[key]
def camera(self, actor):
binding = self.bind(actor)
tracks = self.asset.find_tracks_by_type(unreal.MovieSceneCameraCutTrack)
track = tracks[0] if tracks else self.asset.add_track(unreal.MovieSceneCameraCutTrack)
for old in track.get_sections():
track.remove_section(old)
section = track.add_section()
section.set_range(0, self.frames)
binding_id = unreal.MovieSceneObjectBindingID()
binding_id.set_editor_property("guid", binding.get_id())
section.set_camera_binding_id(binding_id)
def transform_key(self, actor, frame, location=None, rotation=None, scale=None, interpolation="linear"):
if not isinstance(frame, int) or not 0 <= frame < self.frames:
raise ValueError(f"Klatka musi nalezec do 0..{self.frames - 1}.")
modes = {"linear": unreal.MovieSceneKeyInterpolation.LINEAR,
"auto": unreal.MovieSceneKeyInterpolation.AUTO,
"constant": unreal.MovieSceneKeyInterpolation.CONSTANT}
if interpolation not in modes:
raise ValueError("Interpolacja: linear, auto lub constant.")
key = actor.get_path_name()
if key not in self._transforms:
track = self.bind(actor).add_track(unreal.MovieScene3DTransformTrack)
section = track.add_section()
section.set_range(0, self.frames)
channels = section.get_all_channels()
initial = actor.get_actor_transform()
r = initial.rotation.rotator()
defaults = [*initial.translation.to_tuple(), r.roll, r.pitch, r.yaw,
*initial.scale3d.to_tuple()]
for channel, value in zip(channels, defaults):
channel.set_default(float(value))
self._transforms[key] = channels
channels = self._transforms[key]
for offset, values in [(0, location), (3, rotation), (6, scale)]:
if values is not None:
if len(values) != 3:
raise ValueError("Transformacja wymaga trzech wartosci.")
for channel, value in zip(channels[offset:offset + 3], values):
channel.add_key(unreal.FrameNumber(frame), float(value), interpolation=modes[interpolation])
def save(self, open_editor=True):
self.scene.save()
unreal.EditorAssetLibrary.save_loaded_asset(self.asset)
if open_editor:
unreal.LevelSequenceEditorBlueprintLibrary.open_level_sequence(self.asset)