bevy/crates/bevy_render/src/camera/mod.rs
Daniel McNab ed9d45fae5 Add an example 'showcasing' using multiple windows (#3367)
# Objective

- The multiple windows example which was viciously murdered in #3175.
- cart asked me to

## Solution

- Rework the example to work on pipelined-rendering, based on the work from #2898
2021-12-18 19:38:05 +00:00

108 lines
3.5 KiB
Rust

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::<Camera>()
.register_type::<Visibility>()
.register_type::<ComputedVisibility>()
.register_type::<OrthographicProjection>()
.register_type::<PerspectiveProjection>()
.register_type::<VisibleEntities>()
.register_type::<WindowOrigin>()
.register_type::<ScalingMode>()
.register_type::<DepthCalculation>()
.register_type::<Aabb>()
.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::<OrthographicProjection>,
)
.add_system_to_stage(
CoreStage::PostUpdate,
crate::camera::camera_system::<PerspectiveProjection>,
);
app.sub_app(RenderApp)
.init_resource::<ExtractedCameraNames>()
.add_system_to_stage(RenderStage::Extract, extract_cameras);
}
}
#[derive(Default)]
pub struct ExtractedCameraNames {
pub entities: HashMap<String, Entity>,
}
#[derive(Component, Debug)]
pub struct ExtractedCamera {
pub window_id: WindowId,
pub name: Option<String>,
}
fn extract_cameras(
mut commands: Commands,
active_cameras: Res<ActiveCameras>,
windows: Res<Windows>,
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 })
}