2022-11-17 00:25:54 +00:00
|
|
|
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.
|
2022-11-17 00:25:54 +00:00
|
|
|
#[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-17 00:25:54 +00:00
|
|
|
}
|
|
|
|
|
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.
|
2022-11-17 00:25:54 +00:00
|
|
|
#[derive(Clone, Component, Default)]
|
2022-11-17 22:15:13 +00:00
|
|
|
pub struct InheritOutlineDepth;
|
2022-11-17 00:25:54 +00:00
|
|
|
|
|
|
|
#[allow(clippy::type_complexity)]
|
2022-11-17 22:15:13 +00:00
|
|
|
pub(crate) fn compute_outline_depth(
|
2022-11-17 00:25:54 +00:00
|
|
|
mut root_query: Query<
|
|
|
|
(
|
2022-11-17 22:15:13 +00:00
|
|
|
&mut ComputedOutlineDepth,
|
2022-11-17 00:25:54 +00:00
|
|
|
&GlobalTransform,
|
|
|
|
Changed<GlobalTransform>,
|
2022-11-21 23:46:36 +00:00
|
|
|
Option<(&SetOutlineDepth, Changed<SetOutlineDepth>)>,
|
2022-11-17 00:25:54 +00:00
|
|
|
Option<(&Children, Changed<Children>)>,
|
|
|
|
),
|
2022-11-17 22:15:13 +00:00
|
|
|
Without<InheritOutlineDepth>,
|
2022-11-17 00:25:54 +00:00
|
|
|
>,
|
2023-03-16 01:27:06 +00:00
|
|
|
mut computed_query: Query<
|
|
|
|
(&mut ComputedOutlineDepth, Changed<InheritOutlineDepth>),
|
|
|
|
With<InheritOutlineDepth>,
|
|
|
|
>,
|
2022-11-17 00:25:54 +00:00
|
|
|
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
|
|
|
};
|
2022-11-17 00:25:54 +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;
|
2022-11-17 00:25:54 +00:00
|
|
|
}
|
|
|
|
if let Some((cs, changed_children)) = children {
|
2022-11-21 23:46:36 +00:00
|
|
|
changed |= changed_children;
|
2022-11-17 00:25:54 +00:00
|
|
|
for child in cs.iter() {
|
2022-11-17 22:15:13 +00:00
|
|
|
propagate_outline_depth(
|
2022-11-17 00:25:54 +00:00
|
|
|
&computed,
|
2022-11-21 23:46:36 +00:00
|
|
|
changed,
|
2022-11-17 00:25:54 +00:00
|
|
|
*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,
|
2022-11-17 00:25:54 +00:00
|
|
|
entity: Entity,
|
2023-03-16 01:27:06 +00:00
|
|
|
computed_query: &mut Query<
|
|
|
|
(&mut ComputedOutlineDepth, Changed<InheritOutlineDepth>),
|
|
|
|
With<InheritOutlineDepth>,
|
|
|
|
>,
|
2022-11-17 00:25:54 +00:00
|
|
|
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 {
|
2022-11-17 00:25:54 +00:00
|
|
|
*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;
|
2022-11-17 00:25:54 +00:00
|
|
|
for child in cs.iter() {
|
2022-11-17 22:15:13 +00:00
|
|
|
propagate_outline_depth(
|
2022-11-17 00:25:54 +00:00
|
|
|
root_computed,
|
2022-11-21 23:46:36 +00:00
|
|
|
changed,
|
2022-11-17 00:25:54 +00:00
|
|
|
*child,
|
|
|
|
computed_query,
|
|
|
|
child_query,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|