mod active_cameras; mod bundle; #[allow(clippy::module_inception)] mod camera; mod projection; pub use active_cameras::*; use bevy_transform::components::GlobalTransform; use bevy_utils::HashMap; use bevy_window::{WindowId, Windows}; pub use bundle::*; pub use camera::*; pub use projection::*; use crate::{ primitives::Aabb, view::{ComputedVisibility, ExtractedView, Visibility, VisibleEntities}, RenderApp, RenderStage, }; use bevy_app::{App, CoreStage, Plugin}; use bevy_ecs::prelude::*; #[derive(Default)] pub struct CameraPlugin; impl CameraPlugin { pub const CAMERA_2D: &'static str = "camera_2d"; pub const CAMERA_3D: &'static str = "camera_3d"; } impl Plugin for CameraPlugin { fn build(&self, app: &mut App) { let mut active_cameras = ActiveCameras::default(); active_cameras.add(Self::CAMERA_2D); active_cameras.add(Self::CAMERA_3D); app.register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .insert_resource(active_cameras) .add_system_to_stage(CoreStage::PostUpdate, crate::camera::active_cameras_system) .add_system_to_stage( CoreStage::PostUpdate, crate::camera::camera_system::, ) .add_system_to_stage( CoreStage::PostUpdate, crate::camera::camera_system::, ); app.sub_app(RenderApp) .init_resource::() .add_system_to_stage(RenderStage::Extract, extract_cameras); } } #[derive(Default)] pub struct ExtractedCameraNames { pub entities: HashMap, } #[derive(Component, Debug)] pub struct ExtractedCamera { pub window_id: WindowId, pub name: Option, } fn extract_cameras( mut commands: Commands, active_cameras: Res, windows: Res, query: Query<(Entity, &Camera, &GlobalTransform, &VisibleEntities)>, ) { let mut entities = HashMap::default(); for camera in active_cameras.iter() { let name = &camera.name; if let Some((entity, camera, transform, visible_entities)) = camera.entity.and_then(|e| query.get(e).ok()) { if let Some(window) = windows.get(camera.window) { entities.insert(name.clone(), entity); commands.get_or_spawn(entity).insert_bundle(( ExtractedCamera { window_id: camera.window, name: camera.name.clone(), }, ExtractedView { projection: camera.projection_matrix, transform: *transform, width: window.physical_width().max(1), height: window.physical_height().max(1), near: camera.near, far: camera.far, }, visible_entities.clone(), )); } } } commands.insert_resource(ExtractedCameraNames { entities }) }