From 7ceb4dfd799828ed6e6b04abad13846f3ae233c4 Mon Sep 17 00:00:00 2001 From: Tormod Gjeitnes Hellen Date: Thu, 3 Aug 2023 02:12:44 +0200 Subject: [PATCH] Document when Camera::viewport_to_world and related methods return None (#8841) # Objective Fixes #7171 ## Solution - Add documentation for when Camera::viewport_to_world and related methods return None --- crates/bevy_render/src/camera/camera.rs | 32 ++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/crates/bevy_render/src/camera/camera.rs b/crates/bevy_render/src/camera/camera.rs index 7651401970..c85e8d68cf 100644 --- a/crates/bevy_render/src/camera/camera.rs +++ b/crates/bevy_render/src/camera/camera.rs @@ -169,6 +169,14 @@ impl Camera { /// of the current [`RenderTarget`]. /// For logic that requires the full logical size of the /// [`RenderTarget`], prefer [`Camera::logical_target_size`]. + /// + /// Returns `None` if either: + /// - the function is called just after the `Camera` is created, before `camera_system` is executed, + /// - the [`RenderTarget`] isn't correctly set: + /// - it references the [`PrimaryWindow`](RenderTarget::Window) when there is none, + /// - it references a [`Window`](RenderTarget::Window) entity that doesn't exist or doesn't actually have a `Window` component, + /// - it references an [`Image`](RenderTarget::Image) that doesn't exist (invalid handle), + /// - it references a [`TextureView`](RenderTarget::TextureView) that doesn't exist (invalid handle). #[inline] pub fn logical_viewport_size(&self) -> Option { self.viewport @@ -218,6 +226,12 @@ impl Camera { /// /// To get the coordinates in Normalized Device Coordinates, you should use /// [`world_to_ndc`](Self::world_to_ndc). + /// + /// Returns `None` if any of these conditions occur: + /// - The computed coordinates are beyond the near or far plane + /// - The logical viewport size cannot be computed. See [`logical_viewport_size`](Camera::logical_viewport_size) + /// - The world coordinates cannot be mapped to the Normalized Device Coordinates. See [`world_to_ndc`](Camera::world_to_ndc) + /// May also panic if `glam_assert` is enabled. See [`world_to_ndc`](Camera::world_to_ndc). #[doc(alias = "world_to_screen")] pub fn world_to_viewport( &self, @@ -226,7 +240,7 @@ impl Camera { ) -> Option { let target_size = self.logical_viewport_size()?; let ndc_space_coords = self.world_to_ndc(camera_transform, world_position)?; - // NDC z-values outside of 0 < z < 1 are outside the camera frustum and are thus not in viewport-space + // NDC z-values outside of 0 < z < 1 are outside the (implicit) camera frustum and are thus not in viewport-space if ndc_space_coords.z < 0.0 || ndc_space_coords.z > 1.0 { return None; } @@ -246,6 +260,11 @@ impl Camera { /// /// To get the world space coordinates with Normalized Device Coordinates, you should use /// [`ndc_to_world`](Self::ndc_to_world). + /// + /// Returns `None` if any of these conditions occur: + /// - The logical viewport size cannot be computed. See [`logical_viewport_size`](Camera::logical_viewport_size) + /// - The near or far plane cannot be computed. This can happen if the `camera_transform`, the `world_position`, or the projection matrix defined by [`CameraProjection`] contain `NAN`. + /// Panics if the projection matrix is null and `glam_assert` is enabled. pub fn viewport_to_world( &self, camera_transform: &GlobalTransform, @@ -274,6 +293,11 @@ impl Camera { /// /// To get the world space coordinates with Normalized Device Coordinates, you should use /// [`ndc_to_world`](Self::ndc_to_world). + /// + /// Returns `None` if any of these conditions occur: + /// - The logical viewport size cannot be computed. See [`logical_viewport_size`](Camera::logical_viewport_size) + /// - The viewport position cannot be mapped to the world. See [`ndc_to_world`](Camera::ndc_to_world) + /// May panic. See [`ndc_to_world`](Camera::ndc_to_world). pub fn viewport_to_world_2d( &self, camera_transform: &GlobalTransform, @@ -295,6 +319,9 @@ impl Camera { /// and between 0.0 and 1.0 on the Z axis. /// 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`. + /// Panics if the `camera_transform` contains `NAN` and the `glam_assert` feature is enabled. pub fn world_to_ndc( &self, camera_transform: &GlobalTransform, @@ -315,6 +342,9 @@ impl Camera { /// and between 0.0 and 1.0 on the Z axis. /// To get the world space coordinates with the viewport position, 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`. + /// Panics if the projection matrix is null and `glam_assert` is enabled. pub fn ndc_to_world(&self, camera_transform: &GlobalTransform, ndc: Vec3) -> Option { // Build a transformation matrix to convert from NDC to world space using camera data let ndc_to_world =