advanced example
This commit is contained in:
1 parent
8c0a639fba
commit
6fe57915e8
99 files changed
+1329
-56
No files matched your search
@@ -0,0 +1,57 @@
|
||||
"""Uruchom plik w UE: File > Execute Python Script. Zmieniaj i uruchamiaj ponownie."""
|
||||
import importlib
|
||||
import sys
|
||||
|
||||
# Ponowny import bibliotek (ue cachuje zaimportowaną biblioteke i jeśli nie bedzie
|
||||
# jawnego reloadu/restartu edytora to będzie wykonywał stary kod)
|
||||
if "ue_workshop" in sys.modules:
|
||||
_render_module = sys.modules.get("ue_workshop.render")
|
||||
if _render_module is not None and _render_module.is_rendering():
|
||||
raise RuntimeError("Poczekaj na zakonczenie renderu przed przeladowaniem biblioteki.")
|
||||
# Najpierw zaleznosci, potem moduly, ktore z nich korzystaja.
|
||||
for _name in ("paths", "progress", "video", "materials", "camera", "lighting", "assets",
|
||||
"_gltf", "blender", "characters", "skeletal", "scene", "sequence", "render"):
|
||||
_module = sys.modules.get("ue_workshop." + _name)
|
||||
if _module is not None:
|
||||
importlib.reload(_module)
|
||||
importlib.reload(sys.modules["ue_workshop"])
|
||||
|
||||
from ue_workshop import Scene, Sequence, Renderer, camera, lighting, materials
|
||||
from ue_workshop.paths import PROJECT
|
||||
from ue_workshop.characters import FIGHTER_MODEL, CREATURE_MODEL
|
||||
|
||||
|
||||
# POSTACIE
|
||||
|
||||
# 1. MODEL I SCENA. Jednostki: centymetry. Os Z wskazuje gore.
|
||||
scene = Scene("MyShot")
|
||||
floor = materials.color("Floor", rgb=(0.07, 0.08, 0.11))
|
||||
character_fighter = scene.skeletal_model(FIGHTER_MODEL, name="Fighter", height=200)
|
||||
#character_creature = scene.skeletal_model(CREATURE_MODEL, name="Creature", height=300)
|
||||
|
||||
scene.primitive("Cube", name="Floor", location=(0, 0, -10), scale=(20, 20, 0.2), material=floor)
|
||||
lighting.studio(scene, key_color=(1.0, 0.75, 0.5), fill_color=(0.3, 0.6, 1.0))
|
||||
cam = camera.create(scene, location=(450, -550, 300), fov=40)
|
||||
|
||||
# 2. ANIMACJA. 120 klatek przy 24 FPS = 5 sekund. Ostatnia klatka ma numer 119.
|
||||
shot = Sequence(scene, fps=24, frames=120)
|
||||
shot.camera(cam)
|
||||
|
||||
shot.animation(character_fighter, "draw_a_great_sword_1", start=0, end=60)
|
||||
|
||||
|
||||
|
||||
# shot.animation(character_fighter, "great_sword_idle", start=0, end=60)
|
||||
# shot.animation(character_fighter, "great_sword_attack", start=48, end=120)
|
||||
# shot.transform_key(character_fighter, 70, location=(0, 0, 0), interpolation="auto")
|
||||
# shot.transform_key(character_fighter, 100, location=(0, 200, 0), interpolation="auto")
|
||||
shot.save()
|
||||
|
||||
# 3. WYNIK. Najpierw obejrzyj animacje w Sequencerze, potem zmien RENDER na True.
|
||||
RENDER = False
|
||||
renderer = Renderer(width=1920, height=1080, samples=4, warmup=32, mp4=True)
|
||||
# Mozesz tez zaczac od presetu i nadpisac wybrane wartosci:
|
||||
# renderer = Renderer.from_preset("final", width=1920, height=1080)
|
||||
if RENDER:
|
||||
renderer.render(shot)
|
||||
# Szybki podglad zamiast filmu: renderer.render(shot, single_frame=24)
|
||||
@@ -0,0 +1,35 @@
|
||||
"""Zadanie: stworz ciekawa 15-sekundowa scene. Punkt wyjscia: jedna postac i dwa klipy.
|
||||
|
||||
Uruchom w UE: File > Execute Python Script. Zrob wlasna kopie pliku przed edycja.
|
||||
"""
|
||||
from ue_workshop import Scene, Sequence, Renderer, camera, lighting, materials
|
||||
from ue_workshop.characters import CREATURE_MODEL, _clips
|
||||
|
||||
REIMPORT = False # True: ponowny import modelu i klipow; False: istniejace assety UE
|
||||
|
||||
scene = Scene("AnimationStarter")
|
||||
clips = _clips(CREATURE_MODEL)
|
||||
character = scene.skeletal_model(
|
||||
CREATURE_MODEL, name="Creature", height=200, rotation=(0, 0, 180), reimport=REIMPORT,
|
||||
animations={name: clips[name] for name in ("mutant_idle", "mutant_swiping")},
|
||||
)
|
||||
floor = materials.color("Floor", (0.07, 0.08, 0.11))
|
||||
scene.primitive("Cube", name="Floor", location=(0, 0, -10), scale=(20, 20, 0.2), material=floor)
|
||||
lighting.studio(scene)
|
||||
cam = camera.create(scene, location=(450, -550, 300), fov=45)
|
||||
|
||||
# 360 klatek przy 24 FPS = 15 sekund. Koniec zakresu jest wylaczny.
|
||||
shot = Sequence(scene, fps=24, frames=360)
|
||||
shot.camera(cam)
|
||||
# 12 wspolnych klatek = plynne przejscie przez 0.5 sekundy.
|
||||
shot.animation(character, "mutant_idle", start=0, end=132)
|
||||
shot.animation(character, "mutant_swiping", start=120, end=360)
|
||||
|
||||
# Dodaj ruch postaci, kamery, kolejne klipy lub druga postac.
|
||||
# shot.transform_key(character, 120, location=(0, 0, 0))
|
||||
# shot.transform_key(character, 239, location=(150, 0, 0))
|
||||
# Wszystkie klipy: docs/animations.md. Usun animations=... powyzej, aby udostepnic wszystkie.
|
||||
shot.save()
|
||||
|
||||
renderer = Renderer(width=1280, height=720, samples=4, warmup=16, mp4=True)
|
||||
# renderer.render(shot)
|
||||
@@ -0,0 +1,43 @@
|
||||
"""Podstawy: wlasny model z Blendera i kamera robiaca pelne 360 stopni.
|
||||
|
||||
Uruchom w UE: File > Execute Python Script. Zapisz model w Blenderze przed uruchomieniem.
|
||||
"""
|
||||
import math
|
||||
|
||||
from ue_workshop import Scene, Sequence, Renderer, camera, lighting, materials
|
||||
from ue_workshop.paths import PROJECT
|
||||
|
||||
REIMPORT = False # True po zmianie modelu w Blenderze; False uzywa assetu z UE
|
||||
|
||||
# 1. SCENA. Zmien model, kolor podlogi i swiatla.
|
||||
scene = Scene("Basics")
|
||||
character = scene.model(
|
||||
PROJECT / "source_assets/character/character_custom.blend",
|
||||
name="CustomCharacter", height=200, reimport=REIMPORT,
|
||||
)
|
||||
floor = materials.color("Floor", (0.07, 0.08, 0.11))
|
||||
scene.primitive("Cube", name="Floor", location=(0, 0, -10), scale=(20, 20, 0.2), material=floor)
|
||||
lighting.studio(scene)
|
||||
|
||||
# 2. KAMERA. Jednostki: centymetry; FOV w stopniach.
|
||||
radius = 550
|
||||
height = 260
|
||||
target = (0, 0, 100)
|
||||
cam = camera.create(scene, location=(radius, 0, height), target=target, fov=45)
|
||||
|
||||
# 3. ANIMACJA. 192 klatki przy 24 FPS = 8 sekund.
|
||||
shot = Sequence(scene, fps=24, frames=192)
|
||||
shot.camera(cam)
|
||||
pitch = -math.degrees(math.atan2(height - target[2], radius))
|
||||
for frame in range(shot.frames):
|
||||
angle = 360 * frame / (shot.frames - 1)
|
||||
x = radius * math.cos(math.radians(angle))
|
||||
y = radius * math.sin(math.radians(angle))
|
||||
# Rotacja: roll, pitch, yaw. Ciagly yaw zapobiega obrotowi wstecz przy 180 stopniach.
|
||||
shot.transform_key(cam, frame, location=(x, y, height), rotation=(0, pitch, angle + 180))
|
||||
shot.save()
|
||||
|
||||
# 4. RENDER. Najpierw obejrzyj scene w Sequencerze.
|
||||
renderer = Renderer(width=1280, height=720, samples=4, warmup=16, mp4=True)
|
||||
# renderer.render(shot)
|
||||
# Zamiast filmu: renderer.render(shot, single_frame=96)
|
||||
+46
-22
@@ -10,7 +10,7 @@ if "ue_workshop" in sys.modules:
|
||||
raise RuntimeError("Poczekaj na zakonczenie renderu przed przeladowaniem biblioteki.")
|
||||
# Najpierw zaleznosci, potem moduly, ktore z nich korzystaja.
|
||||
for _name in ("paths", "progress", "video", "materials", "camera", "lighting", "assets",
|
||||
"_gltf", "blender", "scene", "sequence", "render"):
|
||||
"_gltf", "blender", "characters", "skeletal", "scene", "sequence", "render"):
|
||||
_module = sys.modules.get("ue_workshop." + _name)
|
||||
if _module is not None:
|
||||
importlib.reload(_module)
|
||||
@@ -18,12 +18,17 @@ if "ue_workshop" in sys.modules:
|
||||
|
||||
from ue_workshop import Scene, Sequence, Renderer, camera, lighting, materials
|
||||
from ue_workshop.paths import PROJECT
|
||||
from ue_workshop.characters import FIGHTER_MODEL, CREATURE_MODEL
|
||||
|
||||
# WYBOR POSTACI: "primitive", "robot", "pilot" lub "file".
|
||||
MODEL = "file"
|
||||
MODEL_FILE = PROJECT / "source_assets/character/character_custom.blend"
|
||||
# WYBOR POSTACI: "fighter", "creature", "primitive" lub "file".
|
||||
MODEL = "fighter"
|
||||
REIMPORT = False # True: ponowny import modelu i klipow; False: istniejace assety UE
|
||||
ANIMATION = "great_sword_attack" # wszystkie nazwy: docs/animations.md; creature: mutant_swiping
|
||||
MODEL_FILE = PROJECT / "source_assets/character/my_mixamo_character.fbx"
|
||||
SKELETAL = True # dla MODEL="file"; False dla statycznego GLB/FBX/OBJ/.blend
|
||||
ANIMATION_FILE = None # None: animacja w MODEL_FILE; albo FBX Without Skin tej samej postaci
|
||||
MODEL_HEIGHT = 200 # centymetry; None zachowuje oryginalny rozmiar
|
||||
MODEL_ROTATION = (0, 0, 0) # roll, pitch, yaw; np. (0, 0, 90) obraca model
|
||||
MODEL_ROTATION = (0, 0, 180) # roll, pitch, yaw; obrot modeli Mixamo przodem do kamery
|
||||
|
||||
# 1. MODEL I SCENA. Jednostki: centymetry. Os Z wskazuje gore.
|
||||
scene = Scene("MyShot")
|
||||
@@ -32,33 +37,52 @@ if MODEL == "primitive":
|
||||
blue = materials.color("Character", rgb=(0.04, 0.35, 0.8), metallic=0.2)
|
||||
character = scene.character(material=blue, head_scale=1.0)
|
||||
else:
|
||||
sources = {
|
||||
"robot": (PROJECT / "DemoAssets/RobotPolice/RobotPolice.fbx", "RobotPolice"),
|
||||
"pilot": (PROJECT / "DemoAssets/pilot/pilot.fbx", "Pilot"),
|
||||
"file": (MODEL_FILE, "CustomCharacter"),
|
||||
presets = {
|
||||
"fighter": (FIGHTER_MODEL, "Fighter"),
|
||||
"creature": (CREATURE_MODEL, "Creature"),
|
||||
}
|
||||
if MODEL not in sources:
|
||||
raise ValueError("MODEL: primitive, robot, pilot lub file.")
|
||||
source, name = sources[MODEL]
|
||||
character = scene.model(source, name=name, height=MODEL_HEIGHT, rotation=MODEL_ROTATION)
|
||||
if MODEL in presets:
|
||||
source, name = presets[MODEL]
|
||||
character = scene.skeletal_model(source, name=name, height=MODEL_HEIGHT,
|
||||
rotation=MODEL_ROTATION,
|
||||
reimport=REIMPORT)
|
||||
elif MODEL == "file":
|
||||
if SKELETAL:
|
||||
character = scene.skeletal_model(MODEL_FILE, name="CustomCharacter", height=MODEL_HEIGHT,
|
||||
rotation=MODEL_ROTATION,
|
||||
animations={"custom": ANIMATION_FILE} if ANIMATION_FILE else None,
|
||||
reimport=REIMPORT)
|
||||
else:
|
||||
character = scene.model(MODEL_FILE, name="CustomCharacter", height=MODEL_HEIGHT,
|
||||
rotation=MODEL_ROTATION, reimport=REIMPORT)
|
||||
else:
|
||||
raise ValueError("MODEL: fighter, creature, primitive lub file.")
|
||||
scene.primitive("Cube", name="Floor", location=(0, 0, -10), scale=(20, 20, 0.2), material=floor)
|
||||
lighting.studio(scene, key_color=(1.0, 0.75, 0.5), fill_color=(0.3, 0.6, 1.0))
|
||||
cam = camera.create(scene, location=(450, -550, 300), focal_length=45)
|
||||
cam = camera.create(scene, location=(450, -550, 300), fov=40)
|
||||
|
||||
# 2. ANIMACJA. 48 klatek przy 24 FPS = 2 sekundy. Ostatnia klatka ma numer 47.
|
||||
shot = Sequence(scene, fps=24, frames=48)
|
||||
# 2. ANIMACJA. 120 klatek przy 24 FPS = 5 sekund. Ostatnia klatka ma numer 119.
|
||||
shot = Sequence(scene, fps=24, frames=120)
|
||||
shot.camera(cam)
|
||||
if MODEL in ("fighter", "creature"):
|
||||
idle = "great_sword_idle" if MODEL == "fighter" else "mutant_idle"
|
||||
shot.animation(character, idle, start=0, end=60)
|
||||
shot.animation(character, ANIMATION, start=48, end=120)
|
||||
elif MODEL == "file" and SKELETAL:
|
||||
shot.animation(character, "custom" if ANIMATION_FILE else None)
|
||||
else:
|
||||
shot.transform_key(character, 0, rotation=(0, 0, 0))
|
||||
shot.transform_key(character, 119, rotation=(0, 0, 360))
|
||||
# Rotacja: (roll, pitch, yaw), w stopniach.
|
||||
shot.transform_key(character, 0, rotation=(0, 0, 0))
|
||||
shot.transform_key(character, 47, rotation=(0, 0, 360))
|
||||
# Opcjonalny podskok (dziala tak samo dla robota i wlasnego modelu):
|
||||
# Klucze transformacji dzialaja tez razem z animacja kosci.
|
||||
# Opcjonalny podskok:
|
||||
# shot.transform_key(character, 0, location=(0, 0, 0), interpolation="auto")
|
||||
# shot.transform_key(character, 24, location=(0, 0, 80), interpolation="auto")
|
||||
# shot.transform_key(character, 47, location=(0, 0, 0), interpolation="auto")
|
||||
# shot.transform_key(character, 60, location=(0, 0, 80), interpolation="auto")
|
||||
# shot.transform_key(character, 119, location=(0, 0, 0), interpolation="auto")
|
||||
shot.save()
|
||||
|
||||
# 3. WYNIK. Najpierw obejrzyj animacje w Sequencerze, potem zmien RENDER na True.
|
||||
RENDER = True
|
||||
RENDER = False
|
||||
renderer = Renderer(width=1920, height=1080, samples=4, warmup=32, mp4=True)
|
||||
# Mozesz tez zaczac od presetu i nadpisac wybrane wartosci:
|
||||
# renderer = Renderer.from_preset("final", width=1920, height=1080)
|
||||
|
||||
Reference in new issue
Block a user