update camera projection if viewport changed (#5945)
fixes https://github.com/bevyengine/bevy/issues/5944 Uses the second solution: > 2. keep track of the old viewport in the computed_state, and if camera.viewport != camera.computed_state.old_viewport, then update the projection. This is more reliable, but needs to store two UVec2s more in the camera (probably not a big deal).
This commit is contained in:
		
							parent
							
								
									fe7ebd4326
								
							
						
					
					
						commit
						0401f04ba9
					
				| @ -13,9 +13,8 @@ use bevy_ecs::{ | ||||
|     component::Component, | ||||
|     entity::Entity, | ||||
|     event::EventReader, | ||||
|     query::Added, | ||||
|     reflect::ReflectComponent, | ||||
|     system::{Commands, ParamSet, Query, Res}, | ||||
|     system::{Commands, Query, Res}, | ||||
| }; | ||||
| use bevy_math::{Mat4, Ray, UVec2, UVec4, Vec2, Vec3}; | ||||
| use bevy_reflect::prelude::*; | ||||
| @ -68,6 +67,8 @@ pub struct RenderTargetInfo { | ||||
| pub struct ComputedCameraValues { | ||||
|     projection_matrix: Mat4, | ||||
|     target_info: Option<RenderTargetInfo>, | ||||
|     // position and size of the `Viewport`
 | ||||
|     old_viewport_size: Option<UVec2>, | ||||
| } | ||||
| 
 | ||||
| /// The defining component for camera entities, storing information about how and what to render
 | ||||
| @ -404,10 +405,7 @@ pub fn camera_system<T: CameraProjection + Component>( | ||||
|     mut image_asset_events: EventReader<AssetEvent<Image>>, | ||||
|     windows: Res<Windows>, | ||||
|     images: Res<Assets<Image>>, | ||||
|     mut queries: ParamSet<( | ||||
|         Query<(Entity, &mut Camera, &mut T)>, | ||||
|         Query<Entity, Added<Camera>>, | ||||
|     )>, | ||||
|     mut cameras: Query<(&mut Camera, &mut T)>, | ||||
| ) { | ||||
|     let mut changed_window_ids = Vec::new(); | ||||
| 
 | ||||
| @ -440,18 +438,21 @@ pub fn camera_system<T: CameraProjection + Component>( | ||||
|         }) | ||||
|         .collect(); | ||||
| 
 | ||||
|     let mut added_cameras = vec![]; | ||||
|     for entity in &queries.p1() { | ||||
|         added_cameras.push(entity); | ||||
|     } | ||||
|     for (entity, mut camera, mut camera_projection) in &mut queries.p0() { | ||||
|     for (mut camera, mut camera_projection) in &mut cameras { | ||||
|         let viewport_size = camera | ||||
|             .viewport | ||||
|             .as_ref() | ||||
|             .map(|viewport| viewport.physical_size); | ||||
| 
 | ||||
|         if camera | ||||
|             .target | ||||
|             .is_changed(&changed_window_ids, &changed_image_handles) | ||||
|             || added_cameras.contains(&entity) | ||||
|             || camera.is_added() | ||||
|             || camera_projection.is_changed() | ||||
|             || camera.computed.old_viewport_size != viewport_size | ||||
|         { | ||||
|             camera.computed.target_info = camera.target.get_render_target_info(&windows, &images); | ||||
|             camera.computed.old_viewport_size = viewport_size; | ||||
|             if let Some(size) = camera.logical_viewport_size() { | ||||
|                 camera_projection.update(size.x, size.y); | ||||
|                 camera.computed.projection_matrix = camera_projection.get_projection_matrix(); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Jakob Hellermann
						Jakob Hellermann