From 9abf5b4fbbb5eee8fb385c308a9c2cf29caa0d55 Mon Sep 17 00:00:00 2001 From: Roman Salnikov Date: Wed, 8 Nov 2023 23:39:33 +0100 Subject: [PATCH 01/36] Update split_screen example; replace `window_roots` with `camera_roots` --- crates/bevy_render/src/camera/camera.rs | 5 ++ crates/bevy_ui/src/layout/debug.rs | 4 +- crates/bevy_ui/src/layout/mod.rs | 63 ++++++++++++------ crates/bevy_ui/src/ui_node.rs | 5 +- examples/3d/split_screen.rs | 88 +++++++++++++++++++------ 5 files changed, 121 insertions(+), 44 deletions(-) diff --git a/crates/bevy_render/src/camera/camera.rs b/crates/bevy_render/src/camera/camera.rs index be6349689b7cb..9994e9f15ab5c 100644 --- a/crates/bevy_render/src/camera/camera.rs +++ b/crates/bevy_render/src/camera/camera.rs @@ -219,6 +219,11 @@ impl Camera { self.computed.target_info.as_ref().map(|t| t.physical_size) } + #[inline] + pub fn target_scaling_factor(&self) -> Option { + self.computed.target_info.as_ref().map(|t| t.scale_factor) + } + /// The projection matrix computed using this camera's [`CameraProjection`]. #[inline] pub fn projection_matrix(&self) -> Mat4 { diff --git a/crates/bevy_ui/src/layout/debug.rs b/crates/bevy_ui/src/layout/debug.rs index c47b2ca8e802b..37fb5c2b88845 100644 --- a/crates/bevy_ui/src/layout/debug.rs +++ b/crates/bevy_ui/src/layout/debug.rs @@ -12,7 +12,7 @@ pub fn print_ui_layout_tree(ui_surface: &UiSurface) { .iter() .map(|(entity, node)| (*node, *entity)) .collect(); - for (&entity, roots) in &ui_surface.window_roots { + for (&entity, roots) in &ui_surface.camera_roots { let mut out = String::new(); for root in roots { print_node( @@ -25,7 +25,7 @@ pub fn print_ui_layout_tree(ui_surface: &UiSurface) { &mut out, ); } - bevy_log::info!("Layout tree for window entity: {entity:?}\n{out}"); + bevy_log::info!("Layout tree for camera entity: {entity:?}\n{out}"); } } diff --git a/crates/bevy_ui/src/layout/mod.rs b/crates/bevy_ui/src/layout/mod.rs index d404431b1bf26..2fe305ded5b8e 100644 --- a/crates/bevy_ui/src/layout/mod.rs +++ b/crates/bevy_ui/src/layout/mod.rs @@ -1,7 +1,7 @@ mod convert; pub mod debug; -use crate::{ContentSize, Node, Outline, Style, UiScale}; +use crate::{ContentSize, Node, Outline, Style, UiCamera, UiScale}; use bevy_ecs::{ change_detection::{DetectChanges, DetectChangesMut}, entity::Entity, @@ -13,7 +13,8 @@ use bevy_ecs::{ }; use bevy_hierarchy::{Children, Parent}; use bevy_log::warn; -use bevy_math::Vec2; +use bevy_math::{UVec2, Vec2}; +use bevy_render::camera::Camera; use bevy_transform::components::Transform; use bevy_utils::{default, HashMap}; use bevy_window::{PrimaryWindow, Window, WindowResolution, WindowScaleFactorChanged}; @@ -51,7 +52,7 @@ struct RootNodePair { #[derive(Resource)] pub struct UiSurface { entity_to_taffy: HashMap, - window_roots: HashMap>, + camera_roots: HashMap>, taffy: Taffy, } @@ -66,7 +67,7 @@ impl fmt::Debug for UiSurface { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("UiSurface") .field("entity_to_taffy", &self.entity_to_taffy) - .field("window_nodes", &self.window_roots) + .field("camera_roots", &self.camera_roots) .finish() } } @@ -77,7 +78,7 @@ impl Default for UiSurface { taffy.disable_rounding(); Self { entity_to_taffy: Default::default(), - window_roots: Default::default(), + camera_roots: Default::default(), taffy, } } @@ -142,9 +143,9 @@ without UI components as a child of an entity with UI components, results may be } /// Set the ui node entities without a [`Parent`] as children to the root node in the taffy layout. - pub fn set_window_children( + pub fn set_camera_children( &mut self, - window_id: Entity, + camera_id: Entity, children: impl Iterator, ) { let viewport_style = taffy::style::Style { @@ -160,7 +161,7 @@ without UI components as a child of an entity with UI components, results may be ..default() }; - let existing_roots = self.window_roots.entry(window_id).or_default(); + let existing_roots = self.camera_roots.entry(camera_id).or_default(); let mut new_roots = Vec::new(); for entity in children { let node = *self.entity_to_taffy.get(&entity).unwrap(); @@ -185,18 +186,20 @@ without UI components as a child of an entity with UI components, results may be } } - self.window_roots.insert(window_id, new_roots); + self.camera_roots.insert(camera_id, new_roots); } /// Compute the layout for each window entity's corresponding root node in the layout. - pub fn compute_window_layout(&mut self, window: Entity, window_resolution: &WindowResolution) { + pub fn compute_camera_layout(&mut self, camera: Entity, render_target_resolution: UVec2) { + let Some(camera_root_nodes) = self.camera_roots.get(&camera) else { + return; + }; + let available_space = taffy::geometry::Size { - width: taffy::style::AvailableSpace::Definite(window_resolution.physical_width() as f32), - height: taffy::style::AvailableSpace::Definite( - window_resolution.physical_height() as f32 - ), + width: taffy::style::AvailableSpace::Definite(render_target_resolution.x as f32), + height: taffy::style::AvailableSpace::Definite(render_target_resolution.y as f32), }; - for root_nodes in self.window_roots.entry(window).or_default() { + for root_nodes in camera_root_nodes { self.taffy .compute_layout(root_nodes.implicit_viewport_node, available_space) .unwrap(); @@ -242,11 +245,12 @@ pub enum LayoutError { pub fn ui_layout_system( primary_window: Query<(Entity, &Window), With>, windows: Query<(Entity, &Window)>, + cameras: Query<(Entity, &Camera)>, ui_scale: Res, mut scale_factor_events: EventReader, mut resize_events: EventReader, mut ui_surface: ResMut, - root_node_query: Query, Without)>, + root_node_query: Query<(Entity, Option<&UiCamera>), (With, Without)>, style_query: Query<(Entity, Ref