mirror of
https://github.com/storytold/storyteller-bevy.git
synced 2026-10-26 08:38:10 +00:00
Studio Headless Mode (#36)
This PR adds the capaibility to run Stroyteller studio from the command line, rendering the result to images. This is the basic functionality, and there are somethings that I am saving for later when we make this a more fully fledged feature. Limitations: - Right now, you cannot do image output resolutions that aren't 2^n. This is a bug I plan on tackling later. If you have questions on how the command line works, use the --help argument. Let me know what you think! --------- Co-authored-by: Danny McGee <dannymcgee@gmail.com>
This commit is contained in:
+61
-3
@@ -9,19 +9,22 @@ use bevy::{
|
||||
math::vec2,
|
||||
pbr::ShadowFilteringMethod,
|
||||
prelude::*,
|
||||
render::primitives::Aabb,
|
||||
render::{camera::RenderTarget, primitives::Aabb},
|
||||
scene::InstanceId,
|
||||
};
|
||||
|
||||
use space_editor::{prelude::PrefabMarker, space_prefab::component::SceneAutoChild};
|
||||
#[cfg(feature = "wasm")]
|
||||
use wasm_bindgen::prelude::wasm_bindgen;
|
||||
use wgpu::{TextureDescriptor, TextureUsages};
|
||||
|
||||
use crate::{
|
||||
camera_controller::{CameraController, CameraControllerBundle},
|
||||
debug::DebugPoint,
|
||||
is_headless, is_not_headless,
|
||||
math::{Combinable, Extrema},
|
||||
MainCamera,
|
||||
screenshot::ScreenCapture,
|
||||
HeadlessSettings, MainCamera,
|
||||
};
|
||||
|
||||
pub struct ScenePlugin;
|
||||
@@ -35,7 +38,13 @@ impl Plugin for ScenePlugin {
|
||||
.insert_resource(Msaa::Off)
|
||||
.add_state::<SceneState>()
|
||||
.add_event::<LoadSceneEvent>()
|
||||
.add_systems(Startup, initialize)
|
||||
.add_systems(
|
||||
Startup,
|
||||
(
|
||||
initialize.run_if(is_not_headless),
|
||||
initialiaze_headless.run_if(is_headless),
|
||||
),
|
||||
)
|
||||
.add_systems(Update, init_scene_loading.in_set(SceneSpawnerSystem))
|
||||
.add_systems(
|
||||
OnEnter(SceneState::Active),
|
||||
@@ -210,6 +219,55 @@ fn initialize(mut cmd: Commands) {
|
||||
));
|
||||
}
|
||||
|
||||
fn initialiaze_headless(
|
||||
mut cmd: Commands,
|
||||
mut image_assets: ResMut<Assets<Image>>,
|
||||
headless_settings: Res<HeadlessSettings>,
|
||||
) {
|
||||
// Camera, graphics settings
|
||||
let focus = Vec3::ZERO;
|
||||
let camera_xform = Transform::from_xyz(-2.5, 4.5, 5.0).looking_at(focus, Vec3::Y);
|
||||
|
||||
let mut test_image = Image {
|
||||
texture_descriptor: TextureDescriptor {
|
||||
label: Some("render_texture"),
|
||||
size: headless_settings.output_dims,
|
||||
mip_level_count: 1,
|
||||
sample_count: 1,
|
||||
dimension: wgpu::TextureDimension::D2,
|
||||
format: wgpu::TextureFormat::Rgba8UnormSrgb,
|
||||
usage: TextureUsages::TEXTURE_BINDING
|
||||
| TextureUsages::COPY_SRC
|
||||
| TextureUsages::COPY_DST
|
||||
| TextureUsages::RENDER_ATTACHMENT,
|
||||
view_formats: &[],
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
test_image.resize(headless_settings.output_dims);
|
||||
|
||||
cmd.spawn((
|
||||
Name::new("Main Camera"),
|
||||
MainCamera,
|
||||
Camera3dBundle {
|
||||
transform: camera_xform,
|
||||
tonemapping: Tonemapping::BlenderFilmic,
|
||||
camera: Camera {
|
||||
hdr: false,
|
||||
target: RenderTarget::Image(image_assets.add(test_image)),
|
||||
..Default::default()
|
||||
},
|
||||
..default()
|
||||
},
|
||||
CameraControllerBundle::new(focus, camera_xform.translation),
|
||||
ScreenCapture::number_of_frames(
|
||||
headless_settings.frames_to_capture,
|
||||
&headless_settings.output_dir,
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
fn init_scene_loading(mut cmd: Commands, mut er: EventReader<LoadSceneEvent>) {
|
||||
if let Some(id) = er.read().last() {
|
||||
info!("Loading scene: {}", id.0);
|
||||
|
||||
Reference in New Issue
Block a user