use crate::interaction::Preview;
use bevy::render::render_resource::{
Extent3d, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages,
};
use bevy::{
core_pipeline::tonemapping::Tonemapping,
ecs::system::SystemState,
prelude::*,
render::{
camera::{Exposure, RenderTarget},
view::RenderLayers,
},
};
use bevy_egui::{egui::TextureId, EguiContexts};
use rmf_site_camera::*;
use rmf_site_format::Model;
#[derive(Resource)]
pub struct ModelPreviewCamera {
pub camera_entity: Entity,
pub egui_handle: TextureId,
pub model_entity: Entity,
pub light_entity: Entity,
}
pub struct ModelPreviewPlugin;
impl FromWorld for ModelPreviewCamera {
fn from_world(mut world: &mut World) -> Self {
let image_size = Extent3d {
width: 320,
height: 240,
depth_or_array_layers: 1,
};
let mut preview_image = Image {
texture_descriptor: TextureDescriptor {
label: None,
size: image_size,
dimension: TextureDimension::D2,
format: TextureFormat::Rgba8UnormSrgb,
mip_level_count: 1,
sample_count: 1,
usage: TextureUsages::TEXTURE_BINDING
| TextureUsages::COPY_DST
| TextureUsages::RENDER_ATTACHMENT,
view_formats: &[],
},
..default()
};
preview_image.resize(image_size);
let mut images = world.get_resource_mut::<Assets<Image>>().unwrap();
let preview_image = images.add(preview_image);
let mut system_state: SystemState<EguiContexts> = SystemState::new(&mut world);
let mut egui_context = system_state.get_mut(&mut world);
let egui_handle = egui_context.add_image(preview_image.clone());
let camera_entity = world
.spawn(Camera3d::default())
.insert((
Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Z),
Camera {
target: RenderTarget::Image(preview_image.into()),
..default()
},
Tonemapping::ReinhardLuminance,
Exposure {
ev100: DEFAULT_CAMERA_EV100,
},
))
.insert(RenderLayers::from_layers(&[MODEL_PREVIEW_LAYER]))
.id();
let model_entity = world
.spawn((
RenderLayers::from_layers(&[MODEL_PREVIEW_LAYER]),
Preview,
Model::default(),
))
.id();
let light_entity = world
.spawn(RenderLayers::from_layers(&[MODEL_PREVIEW_LAYER]))
.insert((
DirectionalLight {
illuminance: 50.0,
..default()
},
Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Z),
))
.id();
Self {
camera_entity,
egui_handle,
model_entity,
light_entity,
}
}
}
impl Plugin for ModelPreviewPlugin {
fn build(&self, app: &mut App) {
app.init_resource::<ModelPreviewCamera>();
}
}