mod convex_hull;
mod labels;
mod screen_space;
mod systems;
mod types;
use bevy::camera::visibility::RenderLayers;
use bevy::prelude::*;
use labels::BoundsLabel;
use labels::MarginLabel;
pub use types::FitTargetGizmo;
pub use types::FitTargetOverlayConfig;
use types::FitTargetViewportMargins;
use super::components::FitOverlay;
pub struct ZoomOverlayPlugin;
impl Plugin for ZoomOverlayPlugin {
fn build(&self, app: &mut App) {
if app.is_plugin_added::<bevy::gizmos::GizmoPlugin>() {
app.init_gizmo_group::<FitTargetGizmo>();
}
app.init_resource::<FitTargetOverlayConfig>()
.add_observer(on_remove_fit_visualization)
.add_systems(
Update,
(sync_gizmo_render_layers, systems::draw_fit_target_bounds)
.chain()
.run_if(any_with_component::<FitOverlay>),
);
}
}
fn on_remove_fit_visualization(
trigger: On<Remove, FitOverlay>,
mut commands: Commands,
label_query: Query<(Entity, &MarginLabel)>,
bounds_label_query: Query<(Entity, &BoundsLabel)>,
) {
let camera = trigger.entity;
commands
.entity(camera)
.try_remove::<FitTargetViewportMargins>();
for (entity, label) in &label_query {
if label.camera == camera {
commands.entity(entity).despawn();
}
}
for (entity, label) in &bounds_label_query {
if label.camera == camera {
commands.entity(entity).despawn();
}
}
}
fn sync_gizmo_render_layers(
mut config_store: ResMut<GizmoConfigStore>,
viz_config: Res<FitTargetOverlayConfig>,
camera_query: Query<Option<&RenderLayers>, With<FitOverlay>>,
) {
let (gizmo_config, _) = config_store.config_mut::<FitTargetGizmo>();
gizmo_config.line.width = viz_config.line_width;
gizmo_config.depth_bias = -1.0;
if let Some(Some(layers)) = camera_query.iter().next() {
gizmo_config.render_layers = layers.clone();
}
}