diff --git a/crates/bevy_pbr/src/light/mod.rs b/crates/bevy_pbr/src/light/mod.rs index 4bcaaa9458633..9874a1edd9438 100644 --- a/crates/bevy_pbr/src/light/mod.rs +++ b/crates/bevy_pbr/src/light/mod.rs @@ -7,7 +7,7 @@ use bevy_ecs::{ use bevy_math::{ops, Mat4, Vec3A, Vec4}; use bevy_reflect::prelude::*; use bevy_render::{ - camera::{Camera, CameraProjection, Projection}, + camera::{Camera, Projection}, extract_component::ExtractComponent, extract_resource::ExtractResource, mesh::Mesh3d, diff --git a/crates/bevy_render/src/camera/camera.rs b/crates/bevy_render/src/camera/camera.rs index d38cb3fbcac67..f6d90970628c2 100644 --- a/crates/bevy_render/src/camera/camera.rs +++ b/crates/bevy_render/src/camera/camera.rs @@ -5,7 +5,7 @@ use super::{ClearColorConfig, Projection}; use crate::{ batching::gpu_preprocessing::{GpuPreprocessingMode, GpuPreprocessingSupport}, - camera::{CameraProjection, ManualTextureViewHandle, ManualTextureViews}, + camera::{ManualTextureViewHandle, ManualTextureViews}, primitives::Frustum, render_asset::RenderAssets, render_graph::{InternedRenderSubGraph, RenderSubGraph}, @@ -659,7 +659,7 @@ impl Camera { /// To get the coordinates in the render target's viewport dimensions, you should use /// [`world_to_viewport`](Self::world_to_viewport). /// - /// Returns `None` if the `camera_transform`, the `world_position`, or the projection matrix defined by [`CameraProjection`] contain `NAN`. + /// Returns `None` if the `camera_transform`, the `world_position`, or the projection matrix defined by [`Projection`] contain `NAN`. /// /// # Panics /// diff --git a/crates/bevy_render/src/camera/projection.rs b/crates/bevy_render/src/camera/projection.rs index e3f95cb0361e5..b7de26c6fb2e6 100644 --- a/crates/bevy_render/src/camera/projection.rs +++ b/crates/bevy_render/src/camera/projection.rs @@ -128,7 +128,7 @@ mod sealed { /// custom projection. /// /// The contained dynamic object can be downcast into a static type using [`CustomProjection::get`]. -#[derive(Component, Debug, Reflect, Deref, DerefMut)] +#[derive(Debug, Reflect, Deref, DerefMut)] #[reflect(Default, Clone)] pub struct CustomProjection { #[reflect(ignore)] @@ -201,6 +201,36 @@ impl CustomProjection { } } +// TODO: remove when trait upcasting is stabilized. +// The deref impl can return `dyn DynCameraProjection`, which can be coerced into +// `dyn CameraProjection` using trait upcasting. +impl CameraProjection for CustomProjection { + #[inline(always)] + fn get_clip_from_view(&self) -> Mat4 { + self.dyn_projection.get_clip_from_view() + } + + #[inline(always)] + fn get_clip_from_view_for_sub(&self, sub_view: &super::SubCameraView) -> Mat4 { + self.dyn_projection.get_clip_from_view_for_sub(sub_view) + } + + #[inline(always)] + fn update(&mut self, width: f32, height: f32) { + self.dyn_projection.update(width, height); + } + + #[inline(always)] + fn far(&self) -> f32 { + self.dyn_projection.far() + } + + #[inline(always)] + fn get_frustum_corners(&self, z_near: f32, z_far: f32) -> [Vec3A; 8] { + self.dyn_projection.get_frustum_corners(z_near, z_far) + } +} + /// Component that defines how to compute a [`Camera`]'s projection matrix. /// /// Common projections, like perspective and orthographic, are provided out of the box to handle the @@ -237,7 +267,7 @@ impl Projection { // that, say, the `Debug` implementation is missing. Wrapping these traits behind a super // trait or some other indirection will make the errors harder to understand. // - // For example, we don't use the `DynCameraProjection`` trait bound, because it is not the + // For example, we don't use the `DynCameraProjection` trait bound, because it is not the // trait the user should be implementing - they only need to worry about implementing // `CameraProjection`. P: CameraProjection + Debug + Send + Sync + Clone + 'static, @@ -248,44 +278,24 @@ impl Projection { } } -impl CameraProjection for Projection { - fn get_clip_from_view(&self) -> Mat4 { - match self { - Projection::Perspective(projection) => projection.get_clip_from_view(), - Projection::Orthographic(projection) => projection.get_clip_from_view(), - Projection::Custom(projection) => projection.get_clip_from_view(), - } - } - - fn get_clip_from_view_for_sub(&self, sub_view: &super::SubCameraView) -> Mat4 { - match self { - Projection::Perspective(projection) => projection.get_clip_from_view_for_sub(sub_view), - Projection::Orthographic(projection) => projection.get_clip_from_view_for_sub(sub_view), - Projection::Custom(projection) => projection.get_clip_from_view_for_sub(sub_view), - } - } +impl core::ops::Deref for Projection { + type Target = dyn CameraProjection; - fn update(&mut self, width: f32, height: f32) { - match self { - Projection::Perspective(projection) => projection.update(width, height), - Projection::Orthographic(projection) => projection.update(width, height), - Projection::Custom(projection) => projection.update(width, height), - } - } - - fn far(&self) -> f32 { + fn deref(&self) -> &Self::Target { match self { - Projection::Perspective(projection) => projection.far(), - Projection::Orthographic(projection) => projection.far(), - Projection::Custom(projection) => projection.far(), + Projection::Perspective(projection) => projection, + Projection::Orthographic(projection) => projection, + Projection::Custom(projection) => projection, } } +} - fn get_frustum_corners(&self, z_near: f32, z_far: f32) -> [Vec3A; 8] { +impl core::ops::DerefMut for Projection { + fn deref_mut(&mut self) -> &mut Self::Target { match self { - Projection::Perspective(projection) => projection.get_frustum_corners(z_near, z_far), - Projection::Orthographic(projection) => projection.get_frustum_corners(z_near, z_far), - Projection::Custom(projection) => projection.get_frustum_corners(z_near, z_far), + Projection::Perspective(projection) => projection, + Projection::Orthographic(projection) => projection, + Projection::Custom(projection) => projection, } } } diff --git a/crates/bevy_render/src/view/visibility/mod.rs b/crates/bevy_render/src/view/visibility/mod.rs index d72c52abf7b97..1e880dba207bc 100644 --- a/crates/bevy_render/src/view/visibility/mod.rs +++ b/crates/bevy_render/src/view/visibility/mod.rs @@ -20,7 +20,7 @@ use smallvec::SmallVec; use super::NoCpuCulling; use crate::{ - camera::{Camera, CameraProjection, Projection}, + camera::{Camera, Projection}, mesh::{Mesh, Mesh3d, MeshAabb}, primitives::{Aabb, Frustum, Sphere}, sync_world::MainEntity,