Skip to content

Commit

Permalink
Update Node ComputedVisibility based on UI RenderLayers
Browse files Browse the repository at this point in the history
  • Loading branch information
nicopap committed Jul 21, 2022
1 parent d5ee6b4 commit 17153b6
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 3 deletions.
2 changes: 1 addition & 1 deletion crates/bevy_ui/src/entity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ pub struct ButtonBundle {
/// it will display the UI by default.
///
/// [`Camera`]: bevy_render::camera::Camera
#[derive(Component, Clone)]
#[derive(Component, Debug, Clone)]
pub struct UiCameraConfig {
/// Whether to output UI to this camera view.
///
Expand Down
14 changes: 13 additions & 1 deletion crates/bevy_ui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@ pub mod prelude {
use bevy_app::prelude::*;
use bevy_ecs::schedule::{ParallelSystemDescriptorCoercion, SystemLabel};
use bevy_input::InputSystem;
use bevy_render::view::VisibilitySystems;
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_layer_visibility};

/// The basic plugin for Bevy UI
#[derive(Default)]
Expand All @@ -42,6 +43,11 @@ pub enum UiSystem {
Flex,
/// After this label, input interactions with UI entities have been updated for this frame
Focus,
/// Update the [`ComputedVisibility`] component of [`Node`] entities to reflect
/// their visibility in accordance to UI cameras.
///
/// [`ComputedVisibility`]: bevy_render::view::ComputedVisibility
LayerVisibility,
}

impl Plugin for UiPlugin {
Expand Down Expand Up @@ -94,6 +100,12 @@ impl Plugin for UiPlugin {
.before(TransformSystem::TransformPropagate)
.after(ModifiesWindows),
)
.add_system_to_stage(
CoreStage::PostUpdate,
update_layer_visibility
.label(UiSystem::LayerVisibility)
.after(VisibilitySystems::CheckVisibility),
)
.add_system_to_stage(
CoreStage::PostUpdate,
ui_z_system
Expand Down
11 changes: 11 additions & 0 deletions crates/bevy_ui/src/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ fn get_ui_graph(render_app: &mut App) -> RenderGraph {
ui_graph
}

#[derive(Debug)]
pub struct ExtractedUiNode {
pub transform: Mat4,
pub color: Color,
Expand Down Expand Up @@ -224,9 +225,19 @@ const UI_CAMERA_FAR: f32 = 1000.0;
// TODO: Evaluate if we still need this.
const UI_CAMERA_TRANSFORM_OFFSET: f32 = -0.1;

/// The UI camera used by this Camera's viewport.
///
/// This component is inserted into the render world in the
/// [`extract_default_ui_camera_view`] system.
///
/// The component is attached to the "actual" viewport's camera.
/// The UI camera's `ExtractedView` is attached to the entity in the
/// `entity` field.
#[derive(Component, Debug)]
pub struct UiCamera {
/// The entity for the UI camera.
pub entity: Entity,
/// UI nodes layer this camera shows.
layers: RenderLayers,
}

Expand Down
27 changes: 26 additions & 1 deletion crates/bevy_ui/src/update.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! This module contains systems that update the UI when something changes

use crate::{CalculatedClip, Overflow, Style};
use crate::{entity::UiCameraConfig, CalculatedClip, Overflow, Style};

use super::Node;
use bevy_ecs::{
Expand All @@ -10,6 +10,7 @@ use bevy_ecs::{
};
use bevy_hierarchy::{Children, Parent};
use bevy_math::Vec2;
use bevy_render::view::{ComputedVisibility, RenderLayers};
use bevy_sprite::Rect;
use bevy_transform::components::{GlobalTransform, Transform};

Expand Down Expand Up @@ -64,6 +65,30 @@ fn update_hierarchy(
current_global_z
}

/// Correct the `ComputedVisibility` set by [`check_visibility`] for UI nodes.
///
/// Since [`check_visibility`] has no concept of UI cameras, we need a "post-pass"
/// where we re-enable UI nodes that are visible because they have a matching
/// UI camera in their layer.
///
/// [`check_visibility`]: bevy_render::view::visibility::check_visibility
pub fn update_layer_visibility(
ui_cams: Query<&UiCameraConfig>,
mut nodes: Query<(&mut ComputedVisibility, &RenderLayers), With<Node>>,
) {
for config in &ui_cams {
// Skip configs with default render layers, since `check_visibility` assumes it
if config.ui_render_layers == RenderLayers::default() {
continue;
}
for (mut visibility, node_layers) in &mut nodes {
if config.ui_render_layers.intersects(node_layers) {
visibility.set_visible_in_view();
}
}
}
}

/// Updates clipping for all nodes
pub fn update_clipping_system(
mut commands: Commands,
Expand Down

0 comments on commit 17153b6

Please sign in to comment.