From 00655b2986226b16221e512497034b73f5a96a67 Mon Sep 17 00:00:00 2001 From: Nicola Papale Date: Sat, 9 Jul 2022 19:36:55 +0200 Subject: [PATCH] Make the ui cam extract system immutable Following #4402, it is now impossible to mutate the main world from the render world, so we split the update to the projection into a different system ran in the main world. --- crates/bevy_ui/src/lib.rs | 8 +++++++- crates/bevy_ui/src/render/mod.rs | 19 +++++-------------- crates/bevy_ui/src/update.rs | 17 ++++++++++++++++- 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/crates/bevy_ui/src/lib.rs b/crates/bevy_ui/src/lib.rs index d72c1b83495d16..301392896d514d 100644 --- a/crates/bevy_ui/src/lib.rs +++ b/crates/bevy_ui/src/lib.rs @@ -29,7 +29,7 @@ use bevy_ecs::schedule::{ParallelSystemDescriptorCoercion, SystemLabel}; use bevy_input::InputSystem; use bevy_transform::TransformSystem; use bevy_window::ModifiesWindows; -use update::{ui_z_system, update_clipping_system}; +use update::{ui_z_system, update_clipping_system, update_ui_camera_perspective}; /// The basic plugin for Bevy UI #[derive(Default)] @@ -42,6 +42,8 @@ pub enum UiSystem { Flex, /// After this label, input interactions with UI entities have been updated for this frame Focus, + /// Update Ui camera perspective to fit new viewport logical size. + UpdateUiCameraPerspective, } impl Plugin for UiPlugin { @@ -87,6 +89,10 @@ impl Plugin for UiPlugin { CoreStage::PostUpdate, widget::image_node_system.before(UiSystem::Flex), ) + .add_system_to_stage( + CoreStage::Last, + update_ui_camera_perspective.label(UiSystem::UpdateUiCameraPerspective), + ) .add_system_to_stage( CoreStage::PostUpdate, flex_node_system diff --git a/crates/bevy_ui/src/render/mod.rs b/crates/bevy_ui/src/render/mod.rs index d4e610071f09b8..fcd932e9f0072b 100644 --- a/crates/bevy_ui/src/render/mod.rs +++ b/crates/bevy_ui/src/render/mod.rs @@ -233,28 +233,19 @@ pub struct UiCamera { pub fn extract_default_ui_camera_view( mut commands: Commands, - mut query: Extract), With>>, + query: Extract), With>>, ) { - for (camera_entity, camera, opt_ui_config) in query.iter_mut() { - let ui_config = opt_ui_config.as_deref().cloned().unwrap_or_default(); + for (camera_entity, camera, opt_ui_config) in query.iter() { + let ui_config = opt_ui_config.cloned().unwrap_or_default(); // ignore cameras with disabled ui if !ui_config.show_ui { continue; } - if let (Some(logical_size), Some(physical_size)) = ( - camera.logical_viewport_size(), - camera.physical_viewport_size(), - ) { - let mut projection = ui_config.projection.clone(); - projection.update(logical_size.x, logical_size.y); - let projection_matrix = projection.get_projection_matrix(); - if let Some(mut config_to_update) = opt_ui_config { - config_to_update.projection = projection; - } + if let Some(physical_size) = camera.physical_viewport_size() { let ui_camera = commands .spawn() .insert(ExtractedView { - projection: projection_matrix, + projection: ui_config.projection.get_projection_matrix(), transform: GlobalTransform::from_xyz( ui_config.position.x, ui_config.position.y, diff --git a/crates/bevy_ui/src/update.rs b/crates/bevy_ui/src/update.rs index 05628555f1980b..04b1523412c61f 100644 --- a/crates/bevy_ui/src/update.rs +++ b/crates/bevy_ui/src/update.rs @@ -1,15 +1,17 @@ //! This module contains systems that update the UI when something changes -use crate::{CalculatedClip, Overflow, Style}; +use crate::{prelude::UiCameraConfig, CalculatedClip, Overflow, Style}; use super::Node; use bevy_ecs::{ entity::Entity, + prelude::{Changed, Or}, query::{With, Without}, system::{Commands, Query}, }; use bevy_hierarchy::{Children, Parent}; use bevy_math::Vec2; +use bevy_render::camera::{Camera, CameraProjection}; use bevy_sprite::Rect; use bevy_transform::components::{GlobalTransform, Transform}; @@ -82,6 +84,19 @@ pub fn update_clipping_system( } } +pub fn update_ui_camera_perspective( + mut query: Query< + (&Camera, &mut UiCameraConfig), + Or<(Changed, Changed)>, + >, +) { + for (camera, mut ui_config) in query.iter_mut() { + if let Some(logical_size) = camera.logical_viewport_size() { + ui_config.projection.update(logical_size.x, logical_size.y); + } + } +} + fn update_clipping( commands: &mut Commands, children_query: &Query<&Children>,