Skip to content

Commit bf6de89

Browse files
jakobhellermanncart
andcommitted
use marker components for cameras instead of name strings (#3635)
**Problem** - whenever you want more than one of the builtin cameras (for example multiple windows, split screen, portals), you need to add a render graph node that executes the correct sub graph, extract the camera into the render world and add the correct `RenderPhase<T>` components - querying for the 3d camera is annoying because you need to compare the camera's name to e.g. `CameraPlugin::CAMERA_3d` **Solution** - Introduce the marker types `Camera3d`, `Camera2d` and `CameraUi` -> `Query<&mut Transform, With<Camera3d>>` works - `PerspectiveCameraBundle::new_3d()` and `PerspectiveCameraBundle::<Camera3d>::default()` contain the `Camera3d` marker - `OrthographicCameraBundle::new_3d()` has `Camera3d`, `OrthographicCameraBundle::new_2d()` has `Camera2d` - remove `ActiveCameras`, `ExtractedCameraNames` - run 2d, 3d and ui passes for every camera of their respective marker -> no custom setup for multiple windows example needed **Open questions** - do we need a replacement for `ActiveCameras`? What about a component `ActiveCamera { is_active: bool }` similar to `Visibility`? Co-authored-by: Carter Anderson <[email protected]>
1 parent 0e821da commit bf6de89

File tree

16 files changed

+289
-392
lines changed

16 files changed

+289
-392
lines changed

crates/bevy_core_pipeline/src/lib.rs

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use bevy_app::{App, Plugin};
2323
use bevy_core::FloatOrd;
2424
use bevy_ecs::prelude::*;
2525
use bevy_render::{
26-
camera::{ActiveCameras, CameraPlugin, RenderTarget},
26+
camera::{ActiveCamera, Camera2d, Camera3d, RenderTarget},
2727
color::Color,
2828
render_graph::{EmptyNode, RenderGraph, SlotInfo, SlotType},
2929
render_phase::{
@@ -367,23 +367,20 @@ pub fn extract_clear_color(
367367

368368
pub fn extract_core_pipeline_camera_phases(
369369
mut commands: Commands,
370-
active_cameras: Res<ActiveCameras>,
370+
active_2d: Res<ActiveCamera<Camera2d>>,
371+
active_3d: Res<ActiveCamera<Camera3d>>,
371372
) {
372-
if let Some(camera_2d) = active_cameras.get(CameraPlugin::CAMERA_2D) {
373-
if let Some(entity) = camera_2d.entity {
374-
commands
375-
.get_or_spawn(entity)
376-
.insert(RenderPhase::<Transparent2d>::default());
377-
}
378-
}
379-
if let Some(camera_3d) = active_cameras.get(CameraPlugin::CAMERA_3D) {
380-
if let Some(entity) = camera_3d.entity {
381-
commands.get_or_spawn(entity).insert_bundle((
382-
RenderPhase::<Opaque3d>::default(),
383-
RenderPhase::<AlphaMask3d>::default(),
384-
RenderPhase::<Transparent3d>::default(),
385-
));
386-
}
373+
if let Some(entity) = active_2d.get() {
374+
commands
375+
.get_or_spawn(entity)
376+
.insert(RenderPhase::<Transparent2d>::default());
377+
}
378+
if let Some(entity) = active_3d.get() {
379+
commands.get_or_spawn(entity).insert_bundle((
380+
RenderPhase::<Opaque3d>::default(),
381+
RenderPhase::<AlphaMask3d>::default(),
382+
RenderPhase::<Transparent3d>::default(),
383+
));
387384
}
388385
}
389386

crates/bevy_core_pipeline/src/main_pass_driver.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use bevy_ecs::world::World;
22
use bevy_render::{
3-
camera::{CameraPlugin, ExtractedCameraNames},
3+
camera::{ActiveCamera, Camera2d, Camera3d},
44
render_graph::{Node, NodeRunError, RenderGraphContext, SlotValue},
55
renderer::RenderContext,
66
};
@@ -14,18 +14,17 @@ impl Node for MainPassDriverNode {
1414
_render_context: &mut RenderContext,
1515
world: &World,
1616
) -> Result<(), NodeRunError> {
17-
let extracted_cameras = world.resource::<ExtractedCameraNames>();
18-
if let Some(camera_2d) = extracted_cameras.entities.get(CameraPlugin::CAMERA_2D) {
17+
if let Some(camera_2d) = world.resource::<ActiveCamera<Camera2d>>().get() {
1918
graph.run_sub_graph(
2019
crate::draw_2d_graph::NAME,
21-
vec![SlotValue::Entity(*camera_2d)],
20+
vec![SlotValue::Entity(camera_2d)],
2221
)?;
2322
}
2423

25-
if let Some(camera_3d) = extracted_cameras.entities.get(CameraPlugin::CAMERA_3D) {
24+
if let Some(camera_3d) = world.resource::<ActiveCamera<Camera3d>>().get() {
2625
graph.run_sub_graph(
2726
crate::draw_3d_graph::NAME,
28-
vec![SlotValue::Entity(*camera_3d)],
27+
vec![SlotValue::Entity(camera_3d)],
2928
)?;
3029
}
3130

crates/bevy_gltf/src/loader.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use bevy_pbr::{
1212
};
1313
use bevy_render::{
1414
camera::{
15-
Camera, CameraPlugin, CameraProjection, OrthographicProjection, PerspectiveProjection,
15+
Camera, Camera2d, Camera3d, CameraProjection, OrthographicProjection, PerspectiveProjection,
1616
},
1717
color::Color,
1818
mesh::{Indices, Mesh, VertexAttributeValues},
@@ -494,11 +494,10 @@ fn load_node(
494494
};
495495

496496
node.insert(Camera {
497-
name: Some(CameraPlugin::CAMERA_2D.to_owned()),
498497
projection_matrix: orthographic_projection.get_projection_matrix(),
499498
..Default::default()
500499
});
501-
node.insert(orthographic_projection);
500+
node.insert(orthographic_projection).insert(Camera2d);
502501
}
503502
gltf::camera::Projection::Perspective(perspective) => {
504503
let mut perspective_projection: PerspectiveProjection = PerspectiveProjection {
@@ -513,13 +512,13 @@ fn load_node(
513512
perspective_projection.aspect_ratio = aspect_ratio;
514513
}
515514
node.insert(Camera {
516-
name: Some(CameraPlugin::CAMERA_3D.to_owned()),
517515
projection_matrix: perspective_projection.get_projection_matrix(),
518516
near: perspective_projection.near,
519517
far: perspective_projection.far,
520518
..Default::default()
521519
});
522520
node.insert(perspective_projection);
521+
node.insert(Camera3d);
523522
}
524523
}
525524
}

crates/bevy_render/src/camera/active_cameras.rs

Lines changed: 0 additions & 73 deletions
This file was deleted.
Lines changed: 57 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,48 @@
11
use crate::{
2-
camera::{
3-
Camera, CameraPlugin, DepthCalculation, OrthographicProjection, PerspectiveProjection,
4-
ScalingMode,
5-
},
2+
camera::{Camera, DepthCalculation, OrthographicProjection, PerspectiveProjection},
63
primitives::Frustum,
74
view::VisibleEntities,
85
};
9-
use bevy_ecs::bundle::Bundle;
6+
use bevy_ecs::{bundle::Bundle, prelude::Component};
107
use bevy_math::Vec3;
118
use bevy_transform::components::{GlobalTransform, Transform};
129

13-
use super::CameraProjection;
10+
use super::{CameraProjection, ScalingMode};
11+
12+
#[derive(Component, Default)]
13+
pub struct Camera3d;
14+
15+
#[derive(Component, Default)]
16+
pub struct Camera2d;
1417

1518
/// Component bundle for camera entities with perspective projection
1619
///
1720
/// Use this for 3D rendering.
1821
#[derive(Bundle)]
19-
pub struct PerspectiveCameraBundle {
22+
pub struct PerspectiveCameraBundle<M: Component> {
2023
pub camera: Camera,
2124
pub perspective_projection: PerspectiveProjection,
2225
pub visible_entities: VisibleEntities,
2326
pub frustum: Frustum,
2427
pub transform: Transform,
2528
pub global_transform: GlobalTransform,
29+
pub marker: M,
30+
}
31+
32+
impl Default for PerspectiveCameraBundle<Camera3d> {
33+
fn default() -> Self {
34+
PerspectiveCameraBundle::new_3d()
35+
}
2636
}
2737

28-
impl PerspectiveCameraBundle {
38+
impl PerspectiveCameraBundle<Camera3d> {
2939
pub fn new_3d() -> Self {
30-
Default::default()
40+
PerspectiveCameraBundle::new()
3141
}
42+
}
3243

33-
pub fn with_name(name: &str) -> Self {
44+
impl<M: Component + Default> PerspectiveCameraBundle<M> {
45+
pub fn new() -> Self {
3446
let perspective_projection = PerspectiveProjection::default();
3547
let view_projection = perspective_projection.get_projection_matrix();
3648
let frustum = Frustum::from_view_projection(
@@ -41,7 +53,6 @@ impl PerspectiveCameraBundle {
4153
);
4254
PerspectiveCameraBundle {
4355
camera: Camera {
44-
name: Some(name.to_string()),
4556
near: perspective_projection.near,
4657
far: perspective_projection.far,
4758
..Default::default()
@@ -51,30 +62,56 @@ impl PerspectiveCameraBundle {
5162
frustum,
5263
transform: Default::default(),
5364
global_transform: Default::default(),
65+
marker: M::default(),
5466
}
5567
}
5668
}
5769

58-
impl Default for PerspectiveCameraBundle {
59-
fn default() -> Self {
60-
PerspectiveCameraBundle::with_name(CameraPlugin::CAMERA_3D)
61-
}
62-
}
63-
6470
/// Component bundle for camera entities with orthographic projection
6571
///
6672
/// Use this for 2D games, isometric games, CAD-like 3D views.
6773
#[derive(Bundle)]
68-
pub struct OrthographicCameraBundle {
74+
pub struct OrthographicCameraBundle<M: Component> {
6975
pub camera: Camera,
7076
pub orthographic_projection: OrthographicProjection,
7177
pub visible_entities: VisibleEntities,
7278
pub frustum: Frustum,
7379
pub transform: Transform,
7480
pub global_transform: GlobalTransform,
81+
pub marker: M,
82+
}
83+
84+
impl OrthographicCameraBundle<Camera3d> {
85+
pub fn new_3d() -> Self {
86+
let orthographic_projection = OrthographicProjection {
87+
scaling_mode: ScalingMode::FixedVertical,
88+
depth_calculation: DepthCalculation::Distance,
89+
..Default::default()
90+
};
91+
let view_projection = orthographic_projection.get_projection_matrix();
92+
let frustum = Frustum::from_view_projection(
93+
&view_projection,
94+
&Vec3::ZERO,
95+
&Vec3::Z,
96+
orthographic_projection.far(),
97+
);
98+
OrthographicCameraBundle {
99+
camera: Camera {
100+
near: orthographic_projection.near,
101+
far: orthographic_projection.far,
102+
..Default::default()
103+
},
104+
orthographic_projection,
105+
visible_entities: VisibleEntities::default(),
106+
frustum,
107+
transform: Default::default(),
108+
global_transform: Default::default(),
109+
marker: Camera3d,
110+
}
111+
}
75112
}
76113

77-
impl OrthographicCameraBundle {
114+
impl OrthographicCameraBundle<Camera2d> {
78115
/// Create an orthographic projection camera to render 2D content.
79116
///
80117
/// The projection creates a camera space where X points to the right of the screen,
@@ -112,7 +149,6 @@ impl OrthographicCameraBundle {
112149
);
113150
OrthographicCameraBundle {
114151
camera: Camera {
115-
name: Some(CameraPlugin::CAMERA_2D.to_string()),
116152
near: orthographic_projection.near,
117153
far: orthographic_projection.far,
118154
..Default::default()
@@ -122,58 +158,7 @@ impl OrthographicCameraBundle {
122158
frustum,
123159
transform,
124160
global_transform: Default::default(),
125-
}
126-
}
127-
128-
pub fn new_3d() -> Self {
129-
let orthographic_projection = OrthographicProjection {
130-
scaling_mode: ScalingMode::FixedVertical,
131-
depth_calculation: DepthCalculation::Distance,
132-
..Default::default()
133-
};
134-
let view_projection = orthographic_projection.get_projection_matrix();
135-
let frustum = Frustum::from_view_projection(
136-
&view_projection,
137-
&Vec3::ZERO,
138-
&Vec3::Z,
139-
orthographic_projection.far(),
140-
);
141-
OrthographicCameraBundle {
142-
camera: Camera {
143-
name: Some(CameraPlugin::CAMERA_3D.to_string()),
144-
near: orthographic_projection.near,
145-
far: orthographic_projection.far,
146-
..Default::default()
147-
},
148-
orthographic_projection,
149-
visible_entities: VisibleEntities::default(),
150-
frustum,
151-
transform: Default::default(),
152-
global_transform: Default::default(),
153-
}
154-
}
155-
156-
pub fn with_name(name: &str) -> Self {
157-
let orthographic_projection = OrthographicProjection::default();
158-
let view_projection = orthographic_projection.get_projection_matrix();
159-
let frustum = Frustum::from_view_projection(
160-
&view_projection,
161-
&Vec3::ZERO,
162-
&Vec3::Z,
163-
orthographic_projection.far(),
164-
);
165-
OrthographicCameraBundle {
166-
camera: Camera {
167-
name: Some(name.to_string()),
168-
near: orthographic_projection.near,
169-
far: orthographic_projection.far,
170-
..Default::default()
171-
},
172-
orthographic_projection,
173-
visible_entities: VisibleEntities::default(),
174-
frustum,
175-
transform: Default::default(),
176-
global_transform: Default::default(),
161+
marker: Camera2d,
177162
}
178163
}
179164
}

0 commit comments

Comments
 (0)