simplified API to get NDC from camera and world position (#4041)
# Objective
- After #3412, `Camera::world_to_screen` got a little bit uglier to use by needing to provide both `Windows` and `Assets<Image>`, even though only one would be needed b697e73c3d/crates/bevy_render/src/camera/camera.rs (L117-L123)
- Some time, exact coordinates are not needed but normalized device coordinates is enough
## Solution
- Add a function to just get NDC
			
			
This commit is contained in:
		
							parent
							
								
									2b6e67f4cb
								
							
						
					
					
						commit
						4a9932fa8e
					
				| @ -122,6 +122,9 @@ impl Default for DepthCalculation { | |||||||
| 
 | 
 | ||||||
| impl Camera { | impl Camera { | ||||||
|     /// Given a position in world space, use the camera to compute the screen space coordinates.
 |     /// Given a position in world space, use the camera to compute the screen space coordinates.
 | ||||||
|  |     ///
 | ||||||
|  |     /// To get the coordinates in Normalized Device Coordinates, you should use
 | ||||||
|  |     /// [`world_to_ndc`](Self::world_to_ndc).
 | ||||||
|     pub fn world_to_screen( |     pub fn world_to_screen( | ||||||
|         &self, |         &self, | ||||||
|         windows: &Windows, |         windows: &Windows, | ||||||
| @ -130,18 +133,33 @@ impl Camera { | |||||||
|         world_position: Vec3, |         world_position: Vec3, | ||||||
|     ) -> Option<Vec2> { |     ) -> Option<Vec2> { | ||||||
|         let window_size = self.target.get_logical_size(windows, images)?; |         let window_size = self.target.get_logical_size(windows, images)?; | ||||||
|         // Build a transform to convert from world to NDC using camera data
 |         let ndc_space_coords = self.world_to_ndc(camera_transform, world_position)?; | ||||||
|         let world_to_ndc: Mat4 = |  | ||||||
|             self.projection_matrix * camera_transform.compute_matrix().inverse(); |  | ||||||
|         let ndc_space_coords: Vec3 = world_to_ndc.project_point3(world_position); |  | ||||||
|         // NDC z-values outside of 0 < z < 1 are outside the camera frustum and are thus not in screen space
 |         // NDC z-values outside of 0 < z < 1 are outside the camera frustum and are thus not in screen space
 | ||||||
|         if ndc_space_coords.z < 0.0 || ndc_space_coords.z > 1.0 { |         if ndc_space_coords.z < 0.0 || ndc_space_coords.z > 1.0 { | ||||||
|             return None; |             return None; | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|         // Once in NDC space, we can discard the z element and rescale x/y to fit the screen
 |         // Once in NDC space, we can discard the z element and rescale x/y to fit the screen
 | ||||||
|         let screen_space_coords = (ndc_space_coords.truncate() + Vec2::ONE) / 2.0 * window_size; |         Some((ndc_space_coords.truncate() + Vec2::ONE) / 2.0 * window_size) | ||||||
|         if !screen_space_coords.is_nan() { |     } | ||||||
|             Some(screen_space_coords) | 
 | ||||||
|  |     /// Given a position in world space, use the camera to compute the Normalized Device Coordinates.
 | ||||||
|  |     ///
 | ||||||
|  |     /// Values returned will be between -1.0 and 1.0 when the position is in screen space.
 | ||||||
|  |     /// To get the coordinates in the render target dimensions, you should use
 | ||||||
|  |     /// [`world_to_screen`](Self::world_to_screen).
 | ||||||
|  |     pub fn world_to_ndc( | ||||||
|  |         &self, | ||||||
|  |         camera_transform: &GlobalTransform, | ||||||
|  |         world_position: Vec3, | ||||||
|  |     ) -> Option<Vec3> { | ||||||
|  |         // Build a transform to convert from world to NDC using camera data
 | ||||||
|  |         let world_to_ndc: Mat4 = | ||||||
|  |             self.projection_matrix * camera_transform.compute_matrix().inverse(); | ||||||
|  |         let ndc_space_coords: Vec3 = world_to_ndc.project_point3(world_position); | ||||||
|  | 
 | ||||||
|  |         if !ndc_space_coords.is_nan() { | ||||||
|  |             Some(ndc_space_coords) | ||||||
|         } else { |         } else { | ||||||
|             None |             None | ||||||
|         } |         } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 François
						François