Skip to content

Commit 3cefe82

Browse files
authored
Projection Improvements (#18458)
# Objective - Remove a component impl footgun - Make projection code slightly nicer, and remove the need to import the projection trait when using the methods on `Projection`. ## Solution - Do the things.
1 parent 82d62e6 commit 3cefe82

File tree

4 files changed

+37
-44
lines changed

4 files changed

+37
-44
lines changed

crates/bevy_pbr/src/light/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use bevy_ecs::{
77
use bevy_math::{ops, Mat4, Vec3A, Vec4};
88
use bevy_reflect::prelude::*;
99
use bevy_render::{
10-
camera::{Camera, CameraProjection, Projection},
10+
camera::{Camera, Projection},
1111
extract_component::ExtractComponent,
1212
extract_resource::ExtractResource,
1313
mesh::Mesh3d,

crates/bevy_render/src/camera/camera.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use super::{ClearColorConfig, Projection};
66
use crate::{
77
batching::gpu_preprocessing::{GpuPreprocessingMode, GpuPreprocessingSupport},
8-
camera::{CameraProjection, ManualTextureViewHandle, ManualTextureViews},
8+
camera::{ManualTextureViewHandle, ManualTextureViews},
99
primitives::Frustum,
1010
render_asset::RenderAssets,
1111
render_graph::{InternedRenderSubGraph, RenderSubGraph},
@@ -311,8 +311,8 @@ pub enum ViewportConversionError {
311311
#[error("computed coordinate beyond `Camera`'s far plane")]
312312
PastFarPlane,
313313
/// The Normalized Device Coordinates could not be computed because the `camera_transform`, the
314-
/// `world_position`, or the projection matrix defined by [`CameraProjection`] contained `NAN`
315-
/// (see [`world_to_ndc`][Camera::world_to_ndc] and [`ndc_to_world`][Camera::ndc_to_world]).
314+
/// `world_position`, or the projection matrix defined by [`Projection`] contained `NAN` (see
315+
/// [`world_to_ndc`][Camera::world_to_ndc] and [`ndc_to_world`][Camera::ndc_to_world]).
316316
#[error("found NaN while computing NDC")]
317317
InvalidData,
318318
}
@@ -490,7 +490,7 @@ impl Camera {
490490
.map(|t: &RenderTargetInfo| t.scale_factor)
491491
}
492492

493-
/// The projection matrix computed using this camera's [`CameraProjection`].
493+
/// The projection matrix computed using this camera's [`Projection`].
494494
#[inline]
495495
pub fn clip_from_view(&self) -> Mat4 {
496496
self.computed.clip_from_view
@@ -655,7 +655,7 @@ impl Camera {
655655
/// To get the coordinates in the render target's viewport dimensions, you should use
656656
/// [`world_to_viewport`](Self::world_to_viewport).
657657
///
658-
/// Returns `None` if the `camera_transform`, the `world_position`, or the projection matrix defined by [`CameraProjection`] contain `NAN`.
658+
/// Returns `None` if the `camera_transform`, the `world_position`, or the projection matrix defined by [`Projection`] contain `NAN`.
659659
///
660660
/// # Panics
661661
///
@@ -681,7 +681,7 @@ impl Camera {
681681
/// To get the world space coordinates with the viewport position, you should use
682682
/// [`world_to_viewport`](Self::world_to_viewport).
683683
///
684-
/// Returns `None` if the `camera_transform`, the `world_position`, or the projection matrix defined by [`CameraProjection`] contain `NAN`.
684+
/// Returns `None` if the `camera_transform`, the `world_position`, or the projection matrix defined by [`Projection`] contain `NAN`.
685685
///
686686
/// # Panics
687687
///

crates/bevy_render/src/camera/projection.rs

Lines changed: 29 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use core::fmt::Debug;
2+
use core::ops::{Deref, DerefMut};
23

34
use crate::{primitives::Frustum, view::VisibilitySystems};
45
use bevy_app::{App, Plugin, PostStartup, PostUpdate};
56
use bevy_asset::AssetEventSystems;
6-
use bevy_derive::{Deref, DerefMut};
77
use bevy_ecs::prelude::*;
88
use bevy_math::{ops, AspectRatio, Mat4, Rect, Vec2, Vec3A, Vec4};
99
use bevy_reflect::{std_traits::ReflectDefault, Reflect, ReflectDeserialize, ReflectSerialize};
@@ -131,11 +131,10 @@ mod sealed {
131131
/// custom projection.
132132
///
133133
/// The contained dynamic object can be downcast into a static type using [`CustomProjection::get`].
134-
#[derive(Component, Debug, Reflect, Deref, DerefMut)]
134+
#[derive(Debug, Reflect)]
135135
#[reflect(Default, Clone)]
136136
pub struct CustomProjection {
137137
#[reflect(ignore)]
138-
#[deref]
139138
dyn_projection: Box<dyn sealed::DynCameraProjection>,
140139
}
141140

@@ -204,6 +203,20 @@ impl CustomProjection {
204203
}
205204
}
206205

206+
impl Deref for CustomProjection {
207+
type Target = dyn CameraProjection;
208+
209+
fn deref(&self) -> &Self::Target {
210+
self.dyn_projection.as_ref()
211+
}
212+
}
213+
214+
impl DerefMut for CustomProjection {
215+
fn deref_mut(&mut self) -> &mut Self::Target {
216+
self.dyn_projection.as_mut()
217+
}
218+
}
219+
207220
/// Component that defines how to compute a [`Camera`]'s projection matrix.
208221
///
209222
/// Common projections, like perspective and orthographic, are provided out of the box to handle the
@@ -240,7 +253,7 @@ impl Projection {
240253
// that, say, the `Debug` implementation is missing. Wrapping these traits behind a super
241254
// trait or some other indirection will make the errors harder to understand.
242255
//
243-
// For example, we don't use the `DynCameraProjection`` trait bound, because it is not the
256+
// For example, we don't use the `DynCameraProjection` trait bound, because it is not the
244257
// trait the user should be implementing - they only need to worry about implementing
245258
// `CameraProjection`.
246259
P: CameraProjection + Debug + Send + Sync + Clone + 'static,
@@ -251,44 +264,24 @@ impl Projection {
251264
}
252265
}
253266

254-
impl CameraProjection for Projection {
255-
fn get_clip_from_view(&self) -> Mat4 {
256-
match self {
257-
Projection::Perspective(projection) => projection.get_clip_from_view(),
258-
Projection::Orthographic(projection) => projection.get_clip_from_view(),
259-
Projection::Custom(projection) => projection.get_clip_from_view(),
260-
}
261-
}
262-
263-
fn get_clip_from_view_for_sub(&self, sub_view: &super::SubCameraView) -> Mat4 {
264-
match self {
265-
Projection::Perspective(projection) => projection.get_clip_from_view_for_sub(sub_view),
266-
Projection::Orthographic(projection) => projection.get_clip_from_view_for_sub(sub_view),
267-
Projection::Custom(projection) => projection.get_clip_from_view_for_sub(sub_view),
268-
}
269-
}
270-
271-
fn update(&mut self, width: f32, height: f32) {
272-
match self {
273-
Projection::Perspective(projection) => projection.update(width, height),
274-
Projection::Orthographic(projection) => projection.update(width, height),
275-
Projection::Custom(projection) => projection.update(width, height),
276-
}
277-
}
267+
impl Deref for Projection {
268+
type Target = dyn CameraProjection;
278269

279-
fn far(&self) -> f32 {
270+
fn deref(&self) -> &Self::Target {
280271
match self {
281-
Projection::Perspective(projection) => projection.far(),
282-
Projection::Orthographic(projection) => projection.far(),
283-
Projection::Custom(projection) => projection.far(),
272+
Projection::Perspective(projection) => projection,
273+
Projection::Orthographic(projection) => projection,
274+
Projection::Custom(projection) => projection.deref(),
284275
}
285276
}
277+
}
286278

287-
fn get_frustum_corners(&self, z_near: f32, z_far: f32) -> [Vec3A; 8] {
279+
impl DerefMut for Projection {
280+
fn deref_mut(&mut self) -> &mut Self::Target {
288281
match self {
289-
Projection::Perspective(projection) => projection.get_frustum_corners(z_near, z_far),
290-
Projection::Orthographic(projection) => projection.get_frustum_corners(z_near, z_far),
291-
Projection::Custom(projection) => projection.get_frustum_corners(z_near, z_far),
282+
Projection::Perspective(projection) => projection,
283+
Projection::Orthographic(projection) => projection,
284+
Projection::Custom(projection) => projection.deref_mut(),
292285
}
293286
}
294287
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use smallvec::SmallVec;
2020

2121
use super::NoCpuCulling;
2222
use crate::{
23-
camera::{Camera, CameraProjection, Projection},
23+
camera::{Camera, Projection},
2424
mesh::{Mesh, Mesh3d, MeshAabb},
2525
primitives::{Aabb, Frustum, Sphere},
2626
sync_world::MainEntity,

0 commit comments

Comments
 (0)