bevy_mod_outline/src/computed.rs

106 lines
3.4 KiB
Rust
Raw Normal View History

use bevy::prelude::*;
2023-02-21 21:12:44 +00:00
use crate::uniforms::DepthMode;
2022-11-17 22:15:13 +00:00
/// A component for storing the computed depth at which the outline lies.
#[derive(Clone, Component, Default)]
2022-11-17 22:15:13 +00:00
pub struct ComputedOutlineDepth {
2023-02-21 21:12:44 +00:00
pub(crate) world_origin: Vec3,
pub(crate) depth_mode: DepthMode,
}
2022-11-21 23:46:36 +00:00
/// A component which specifies how the outline depth should be computed.
#[derive(Clone, Component)]
#[non_exhaustive]
pub enum SetOutlineDepth {
/// A flat plane facing the camera and intersecting the specified point in model-space.
Flat { model_origin: Vec3 },
2023-01-03 02:06:45 +00:00
/// Real model-space.
Real,
2022-11-21 23:46:36 +00:00
}
/// A component which specifies that this outline lies at the same depth as its parent.
#[derive(Clone, Component, Default)]
2022-11-17 22:15:13 +00:00
pub struct InheritOutlineDepth;
#[allow(clippy::type_complexity)]
2022-11-17 22:15:13 +00:00
pub(crate) fn compute_outline_depth(
mut root_query: Query<
(
2022-11-17 22:15:13 +00:00
&mut ComputedOutlineDepth,
&GlobalTransform,
Changed<GlobalTransform>,
2022-11-21 23:46:36 +00:00
Option<(&SetOutlineDepth, Changed<SetOutlineDepth>)>,
Option<(&Children, Changed<Children>)>,
),
2022-11-17 22:15:13 +00:00
Without<InheritOutlineDepth>,
>,
mut computed_query: Query<
(&mut ComputedOutlineDepth, Changed<InheritOutlineDepth>),
With<InheritOutlineDepth>,
>,
child_query: Query<(&Children, Changed<Children>)>,
) {
2022-11-21 23:46:36 +00:00
for (mut computed, transform, changed_transform, set_depth, children) in root_query.iter_mut() {
2023-02-21 21:12:44 +00:00
let mut changed =
computed.is_added() || changed_transform || set_depth.filter(|(_, c)| *c).is_some();
2022-11-21 23:46:36 +00:00
if changed {
2023-02-21 21:12:44 +00:00
let (origin, depth_mode) = if let Some((sd, _)) = set_depth {
2022-11-21 23:46:36 +00:00
match sd {
SetOutlineDepth::Flat {
model_origin: origin,
2023-02-21 21:12:44 +00:00
} => (*origin, DepthMode::Flat),
SetOutlineDepth::Real => (Vec3::NAN, DepthMode::Real),
2022-11-21 23:46:36 +00:00
}
} else {
2023-02-21 21:12:44 +00:00
(Vec3::ZERO, DepthMode::Flat)
2022-11-21 23:46:36 +00:00
};
let matrix = transform.compute_matrix();
2023-02-21 21:12:44 +00:00
computed.world_origin = matrix.project_point3(origin);
computed.depth_mode = depth_mode;
}
if let Some((cs, changed_children)) = children {
2022-11-21 23:46:36 +00:00
changed |= changed_children;
for child in cs.iter() {
2022-11-17 22:15:13 +00:00
propagate_outline_depth(
&computed,
2022-11-21 23:46:36 +00:00
changed,
*child,
&mut computed_query,
&child_query,
);
}
}
}
}
2022-11-17 22:15:13 +00:00
fn propagate_outline_depth(
root_computed: &ComputedOutlineDepth,
2022-11-21 23:46:36 +00:00
mut changed: bool,
entity: Entity,
computed_query: &mut Query<
(&mut ComputedOutlineDepth, Changed<InheritOutlineDepth>),
With<InheritOutlineDepth>,
>,
child_query: &Query<(&Children, Changed<Children>)>,
) {
if let Ok((mut computed, changed_inherit)) = computed_query.get_mut(entity) {
2022-11-21 23:46:36 +00:00
changed |= changed_inherit;
if changed {
*computed = root_computed.clone();
}
if let Ok((cs, changed_children)) = child_query.get(entity) {
2022-11-21 23:46:36 +00:00
changed |= changed_children;
for child in cs.iter() {
2022-11-17 22:15:13 +00:00
propagate_outline_depth(
root_computed,
2022-11-21 23:46:36 +00:00
changed,
*child,
computed_query,
child_query,
);
}
}
}
}