Skip to content

Commit 08654ad

Browse files
stepanchegatlv24
andauthored
CameraProjection::compute_frustum (bevyengine#11139)
Frustum computation is nontrivial amount of code private in `update_frusta` system. Make it public. This is needed to decide which entities to spawn/despawn in `Update` based on camera changes. But if `Update` also changed camera, frustum is not yet recomputed. Technically it is probably possible to run an iteration of `update_frusta` system by a user in `Update` schedule after propagating `GlobalTransform` to the cameras, but it is easier to just compute frustum manually using API added in this PR. Also replace two places where this code is used. --------- Co-authored-by: vero <email@atlasdostal.com>
1 parent 1974723 commit 08654ad

File tree

3 files changed

+20
-24
lines changed

3 files changed

+20
-24
lines changed

crates/bevy_core_pipeline/src/core_2d/camera_2d.rs

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,7 @@ impl Default for Camera2dBundle {
4545
..Default::default()
4646
};
4747
let transform = Transform::default();
48-
let view_projection =
49-
projection.get_projection_matrix() * transform.compute_matrix().inverse();
50-
let frustum = Frustum::from_view_projection_custom_far(
51-
&view_projection,
52-
&transform.translation,
53-
&transform.back(),
54-
projection.far(),
55-
);
48+
let frustum = projection.compute_frustum(&GlobalTransform::from(transform));
5649
Self {
5750
camera_render_graph: CameraRenderGraph::new(SubGraph2d),
5851
projection,
@@ -84,14 +77,7 @@ impl Camera2dBundle {
8477
..Default::default()
8578
};
8679
let transform = Transform::from_xyz(0.0, 0.0, far - 0.1);
87-
let view_projection =
88-
projection.get_projection_matrix() * transform.compute_matrix().inverse();
89-
let frustum = Frustum::from_view_projection_custom_far(
90-
&view_projection,
91-
&transform.translation,
92-
&transform.back(),
93-
projection.far(),
94-
);
80+
let frustum = projection.compute_frustum(&GlobalTransform::from(transform));
9581
Self {
9682
camera_render_graph: CameraRenderGraph::new(SubGraph3d),
9783
projection,

crates/bevy_render/src/camera/projection.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
use std::marker::PhantomData;
22
use std::ops::{Div, DivAssign, Mul, MulAssign};
33

4+
use crate::primitives::Frustum;
45
use bevy_app::{App, Plugin, PostStartup, PostUpdate};
56
use bevy_ecs::{prelude::*, reflect::ReflectComponent};
67
use bevy_math::{AspectRatio, Mat4, Rect, Vec2, Vec3A};
78
use bevy_reflect::{
89
std_traits::ReflectDefault, GetTypeRegistration, Reflect, ReflectDeserialize, ReflectSerialize,
910
};
11+
use bevy_transform::components::GlobalTransform;
1012
use serde::{Deserialize, Serialize};
1113

1214
/// Adds [`Camera`](crate::camera::Camera) driver systems for a given projection type.
@@ -60,6 +62,21 @@ pub trait CameraProjection {
6062
fn update(&mut self, width: f32, height: f32);
6163
fn far(&self) -> f32;
6264
fn get_frustum_corners(&self, z_near: f32, z_far: f32) -> [Vec3A; 8];
65+
66+
/// Compute camera frustum for camera with given projection and transform.
67+
///
68+
/// This code is called by [`update_frusta`](crate::view::visibility::update_frusta) system
69+
/// for each camera to update its frustum.
70+
fn compute_frustum(&self, camera_transform: &GlobalTransform) -> Frustum {
71+
let view_projection =
72+
self.get_projection_matrix() * camera_transform.compute_matrix().inverse();
73+
Frustum::from_view_projection_custom_far(
74+
&view_projection,
75+
&camera_transform.translation(),
76+
&camera_transform.back(),
77+
self.far(),
78+
)
79+
}
6380
}
6481

6582
/// A configurable [`CameraProjection`] that can select its projection type at runtime.

crates/bevy_render/src/view/visibility/mod.rs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -281,14 +281,7 @@ pub fn update_frusta<T: Component + CameraProjection + Send + Sync + 'static>(
281281
>,
282282
) {
283283
for (transform, projection, mut frustum) in &mut views {
284-
let view_projection =
285-
projection.get_projection_matrix() * transform.compute_matrix().inverse();
286-
*frustum = Frustum::from_view_projection_custom_far(
287-
&view_projection,
288-
&transform.translation(),
289-
&transform.back(),
290-
projection.far(),
291-
);
284+
*frustum = projection.compute_frustum(transform);
292285
}
293286
}
294287

0 commit comments

Comments
 (0)