Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to manually start and stop capturing? #1

Closed
katopz opened this issue May 17, 2023 · 2 comments
Closed

How to manually start and stop capturing? #1

katopz opened this issue May 17, 2023 · 2 comments

Comments

@katopz
Copy link

katopz commented May 17, 2023

I want to capture all angle of an object so...

  1. I rotate camera around object.
  2. I let camera look at object.
  3. I take screenshot.

everything work fine, images output correctly in output folder as expected but...

  1. i can't find how to start/stop the capturing after it done rotation. // Seem like it capture every frame while rendering.
  2. it's not render on screen. // i also need to see each captured result on screen while capturing.

Any hint is welcome.

@paulkre
Copy link
Owner

paulkre commented May 18, 2023

  1. To stop capturing you have to despawn the entity holding the ImageExportBundle.
  2. To render the scene to file and to screen simultaneously, you have to spawn two cameras: One responsible for exporting and the other for screen rendering. In order to make sure both cameras always render the same image, you can parent one camera to the other.

Check out the following example:

use bevy::{
    prelude::*,
    render::{
        camera::RenderTarget,
        render_resource::{
            Extent3d, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages,
        },
    },
    window::WindowResolution,
    winit::WinitSettings,
};
use bevy_image_export::{ImageExportBundle, ImageExportPlugin, ImageExportSource};
use std::f32::consts::TAU;

fn main() {
    let export_plugin = ImageExportPlugin::default();
    let export_threads = export_plugin.threads.clone();

    App::new()
        .insert_resource(WinitSettings {
            return_from_run: true,
            ..default()
        })
        .add_plugins(DefaultPlugins.set(WindowPlugin {
            primary_window: Some(Window {
                resolution: WindowResolution::new(768.0, 768.0).with_scale_factor_override(1.0),
                ..default()
            }),
            ..default()
        }))
        .add_plugin(export_plugin)
        .insert_resource(AmbientLight {
            color: Color::WHITE,
            brightness: 1.0,
        })
        .add_startup_system(setup)
        .add_system(update)
        .run();

    export_threads.finish();
}

fn setup(
    mut commands: Commands,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<StandardMaterial>>,
    mut images: ResMut<Assets<Image>>,
    mut export_sources: ResMut<Assets<ImageExportSource>>,
) {
    let output_texture_handle = {
        let size = Extent3d {
            width: 768,
            height: 768,
            ..default()
        };
        let mut export_texture = Image {
            texture_descriptor: TextureDescriptor {
                label: None,
                size,
                dimension: TextureDimension::D2,
                format: TextureFormat::Rgba8UnormSrgb,
                mip_level_count: 1,
                sample_count: 1,
                usage: TextureUsages::COPY_DST
                    | TextureUsages::COPY_SRC
                    | TextureUsages::RENDER_ATTACHMENT,
                view_formats: &[],
            },
            ..default()
        };
        export_texture.resize(size);

        images.add(export_texture)
    };

    commands
        .spawn((
            VisibilityBundle::default(),
            TransformBundle::default(),
            Turntable,
        ))
        .with_children(|parent| {
            parent
                .spawn(Camera3dBundle {
                    transform: Transform::from_translation(4.2 * Vec3::Z),
                    ..default()
                })
                .with_children(|parent| {
                    parent.spawn(Camera3dBundle {
                        camera: Camera {
                            target: RenderTarget::Image(output_texture_handle.clone()),
                            ..default()
                        },
                        ..default()
                    });
                });
        });

    commands.spawn((
        ImageExportBundle {
            source: export_sources.add(output_texture_handle.into()),
            ..default()
        },
        ExportBundleMarker,
    ));

    commands.spawn(PbrBundle {
        mesh: meshes.add(Mesh::try_from(shape::Cube::default()).unwrap()),
        material: materials.add(Color::rgb(1.0, 0.0, 0.0).into()),
        transform: Transform::from_rotation(Quat::from_euler(EulerRot::XYZ, 0.5, 0.0, 0.5)),
        ..default()
    });
}

#[derive(Component)]
struct Turntable;

#[derive(Component)]
struct ExportBundleMarker;

fn update(
    mut commands: Commands,
    export_bundles: Query<Entity, With<ExportBundleMarker>>,
    mut transforms: Query<&mut Transform, With<Turntable>>,
    mut frame: Local<u32>,
) {
    if *frame == 360 {
        commands.entity(export_bundles.single()).despawn();
    } else {
        let theta = TAU * *frame as f32 / 360.0;
        for mut transform in &mut transforms {
            transform.rotation = Quat::from_euler(EulerRot::XYZ, 0.0, theta, 0.0);
        }
    }
    *frame += 1;
}

@katopz
Copy link
Author

katopz commented May 18, 2023

Cooool! Many thanks! despawn and more Camera did the trick! 🙏🥳

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants