mirror of
https://github.com/storytold/storyteller-bevy.git
synced 2026-10-18 07:35:19 +00:00
Timeline Saving/Loading, Cameras, and Headless Playback (#98)
This commit is contained in:
+42
-1
@@ -9,6 +9,7 @@ use space_editor::prelude::{EditorEvent, EditorPrefabPath};
|
||||
use wgpu::Extent3d;
|
||||
|
||||
use crate::{
|
||||
anim::timeline_animation::{Keyframe, TimelineInteractionEvent},
|
||||
bvh::{BvhAnimCompleteEvent, TestBvh},
|
||||
scene::SceneState,
|
||||
screenshot::{ScreenCapture, ScreenShotPlugin},
|
||||
@@ -24,6 +25,14 @@ pub enum HeadlessMode {
|
||||
None,
|
||||
}
|
||||
|
||||
#[derive(Resource)]
|
||||
pub enum CameraMotion {
|
||||
Orbit(f32),
|
||||
Pan(f32),
|
||||
Zoom(f32),
|
||||
Static,
|
||||
}
|
||||
|
||||
pub fn start_headless(
|
||||
mode: HeadlessMode,
|
||||
fps: u32,
|
||||
@@ -39,6 +48,8 @@ pub fn start_headless(
|
||||
max_frames: frames_to_capture,
|
||||
output_dims: image_res,
|
||||
output_dir: outout_dir.to_string(),
|
||||
fps: fps as f32,
|
||||
frame_delta: 1.0 / (fps as f32),
|
||||
});
|
||||
|
||||
app.add_plugins((
|
||||
@@ -80,7 +91,8 @@ pub fn start_headless(
|
||||
cmd.insert_resource(SkyboxId(skybox.clone()));
|
||||
ew.send(EditorEvent::Load(EditorPrefabPath::File(scene.clone())))
|
||||
},
|
||||
);
|
||||
)
|
||||
.add_systems(OnEnter(SceneState::Active), start_timeline_animation);
|
||||
}
|
||||
HeadlessMode::Mixamo(mixamo_path, skybox) => {
|
||||
app.add_plugins(MixamoPlugin);
|
||||
@@ -120,6 +132,8 @@ pub struct HeadlessSettings {
|
||||
pub output_dims: Extent3d,
|
||||
pub output_dir: String,
|
||||
pub max_frames: u32,
|
||||
pub fps: f32,
|
||||
pub frame_delta: f32,
|
||||
}
|
||||
|
||||
impl Default for HeadlessSettings {
|
||||
@@ -132,6 +146,8 @@ impl Default for HeadlessSettings {
|
||||
},
|
||||
output_dir: "./screen_shots/".to_string(),
|
||||
max_frames: u32::MAX,
|
||||
fps: 24.0,
|
||||
frame_delta: 1.0 / 24.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -172,3 +188,28 @@ fn check_for_mixamo_capture_complete(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn start_timeline_animation(
|
||||
mut headless_settings: ResMut<HeadlessSettings>,
|
||||
keyframes: Query<&Keyframe>,
|
||||
camera: Query<Entity, With<MainCamera>>,
|
||||
mut commands: Commands,
|
||||
mut ev: EventWriter<TimelineInteractionEvent>,
|
||||
) {
|
||||
if keyframes.is_empty() {
|
||||
return;
|
||||
}
|
||||
commands.remove_resource::<CameraMotion>();
|
||||
let total_time = keyframes
|
||||
.iter()
|
||||
.fold(0f32, |previous, keyframe| previous.max(keyframe.time));
|
||||
let frames = (total_time * headless_settings.fps).ceil() as u32;
|
||||
headless_settings.max_frames = frames;
|
||||
ev.send(TimelineInteractionEvent::Play);
|
||||
let camera = camera.single();
|
||||
commands.entity(camera).insert(
|
||||
ScreenCapture::from_out(&headless_settings.output_dir)
|
||||
//Part of quick hack, see screenshot.rs#261
|
||||
.with_max_frames(headless_settings.max_frames + 3),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user