diff --git a/crates/bevy_core_pipeline/src/core_2d/camera_2d.rs b/crates/bevy_core_pipeline/src/core_2d/camera_2d.rs index be3c23b57d..471512d0bb 100644 --- a/crates/bevy_core_pipeline/src/core_2d/camera_2d.rs +++ b/crates/bevy_core_pipeline/src/core_2d/camera_2d.rs @@ -45,14 +45,7 @@ impl Default for Camera2dBundle { ..Default::default() }; let transform = Transform::default(); - let view_projection = - projection.get_projection_matrix() * transform.compute_matrix().inverse(); - let frustum = Frustum::from_view_projection_custom_far( - &view_projection, - &transform.translation, - &transform.back(), - projection.far(), - ); + let frustum = projection.compute_frustum(&GlobalTransform::from(transform)); Self { camera_render_graph: CameraRenderGraph::new(SubGraph2d), projection, @@ -84,14 +77,7 @@ impl Camera2dBundle { ..Default::default() }; let transform = Transform::from_xyz(0.0, 0.0, far - 0.1); - let view_projection = - projection.get_projection_matrix() * transform.compute_matrix().inverse(); - let frustum = Frustum::from_view_projection_custom_far( - &view_projection, - &transform.translation, - &transform.back(), - projection.far(), - ); + let frustum = projection.compute_frustum(&GlobalTransform::from(transform)); Self { camera_render_graph: CameraRenderGraph::new(SubGraph3d), projection, diff --git a/crates/bevy_render/src/camera/projection.rs b/crates/bevy_render/src/camera/projection.rs index 27f90559d6..449702e6ec 100644 --- a/crates/bevy_render/src/camera/projection.rs +++ b/crates/bevy_render/src/camera/projection.rs @@ -1,12 +1,14 @@ use std::marker::PhantomData; use std::ops::{Div, DivAssign, Mul, MulAssign}; +use crate::primitives::Frustum; use bevy_app::{App, Plugin, PostStartup, PostUpdate}; use bevy_ecs::{prelude::*, reflect::ReflectComponent}; use bevy_math::{AspectRatio, Mat4, Rect, Vec2, Vec3A}; use bevy_reflect::{ std_traits::ReflectDefault, GetTypeRegistration, Reflect, ReflectDeserialize, ReflectSerialize, }; +use bevy_transform::components::GlobalTransform; use serde::{Deserialize, Serialize}; /// Adds [`Camera`](crate::camera::Camera) driver systems for a given projection type. @@ -60,6 +62,21 @@ pub trait CameraProjection { fn update(&mut self, width: f32, height: f32); fn far(&self) -> f32; fn get_frustum_corners(&self, z_near: f32, z_far: f32) -> [Vec3A; 8]; + + /// Compute camera frustum for camera with given projection and transform. + /// + /// This code is called by [`update_frusta`](crate::view::visibility::update_frusta) system + /// for each camera to update its frustum. + fn compute_frustum(&self, camera_transform: &GlobalTransform) -> Frustum { + let view_projection = + self.get_projection_matrix() * camera_transform.compute_matrix().inverse(); + Frustum::from_view_projection_custom_far( + &view_projection, + &camera_transform.translation(), + &camera_transform.back(), + self.far(), + ) + } } /// A configurable [`CameraProjection`] that can select its projection type at runtime. diff --git a/crates/bevy_render/src/view/visibility/mod.rs b/crates/bevy_render/src/view/visibility/mod.rs index 4427b408e1..e060864617 100644 --- a/crates/bevy_render/src/view/visibility/mod.rs +++ b/crates/bevy_render/src/view/visibility/mod.rs @@ -281,14 +281,7 @@ pub fn update_frusta( >, ) { for (transform, projection, mut frustum) in &mut views { - let view_projection = - projection.get_projection_matrix() * transform.compute_matrix().inverse(); - *frustum = Frustum::from_view_projection_custom_far( - &view_projection, - &transform.translation(), - &transform.back(), - projection.far(), - ); + *frustum = projection.compute_frustum(transform); } }