world coords to screen space (#1258)
Add Camera::world_to_screen to convert world coordinates to screen space
This commit is contained in:
		
							parent
							
								
									f15d62c0f1
								
							
						
					
					
						commit
						18e4fa8cdf
					
				| @ -1,8 +1,9 @@ | ||||
| use super::CameraProjection; | ||||
| use bevy_app::prelude::EventReader; | ||||
| use bevy_ecs::{Added, Component, Entity, Query, QuerySet, Res}; | ||||
| use bevy_math::Mat4; | ||||
| use bevy_math::{Mat4, Vec2, Vec3}; | ||||
| use bevy_reflect::{Reflect, ReflectComponent}; | ||||
| use bevy_transform::components::GlobalTransform; | ||||
| use bevy_window::{WindowCreated, WindowId, WindowResized, Windows}; | ||||
| 
 | ||||
| #[derive(Default, Debug, Reflect)] | ||||
| @ -28,6 +29,30 @@ impl Default for DepthCalculation { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Camera { | ||||
|     /// Given a position in world space, use the camera to compute the screen space coordinates.
 | ||||
|     pub fn world_to_screen( | ||||
|         &self, | ||||
|         windows: &Windows, | ||||
|         camera_transform: &GlobalTransform, | ||||
|         world_position: Vec3, | ||||
|     ) -> Option<Vec2> { | ||||
|         let window = windows.get(self.window)?; | ||||
|         let window_size = Vec2::new(window.width(), window.height()); | ||||
|         // 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.transform_point3(world_position); | ||||
|         // NDC z-values outside of 0 < z < 1 are behind the camera and are thus not in screen space
 | ||||
|         if ndc_space_coords.z < 0.0 || ndc_space_coords.z > 1.0 { | ||||
|             return None; | ||||
|         } | ||||
|         // 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(screen_space_coords) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub fn camera_system<T: CameraProjection + Component>( | ||||
|     mut window_resized_events: EventReader<WindowResized>, | ||||
|     mut window_created_events: EventReader<WindowCreated>, | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Aevyrie
						Aevyrie