Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_gizmos/src/aabb.rs
6595 views
1
//! A module adding debug visualization of [`Aabb`]s.
2
3
use bevy_app::{Plugin, PostUpdate};
4
use bevy_camera::primitives::Aabb;
5
use bevy_color::{Color, Oklcha};
6
use bevy_ecs::{
7
component::Component,
8
entity::Entity,
9
query::Without,
10
reflect::ReflectComponent,
11
schedule::IntoScheduleConfigs,
12
system::{Query, Res},
13
};
14
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
15
use bevy_transform::{
16
components::{GlobalTransform, Transform},
17
TransformSystems,
18
};
19
20
use crate::{
21
config::{GizmoConfigGroup, GizmoConfigStore},
22
gizmos::Gizmos,
23
AppGizmoBuilder,
24
};
25
26
/// A [`Plugin`] that provides visualization of [`Aabb`]s for debugging.
27
pub struct AabbGizmoPlugin;
28
29
impl Plugin for AabbGizmoPlugin {
30
fn build(&self, app: &mut bevy_app::App) {
31
app.init_gizmo_group::<AabbGizmoConfigGroup>().add_systems(
32
PostUpdate,
33
(
34
draw_aabbs,
35
draw_all_aabbs.run_if(|config: Res<GizmoConfigStore>| {
36
config.config::<AabbGizmoConfigGroup>().1.draw_all
37
}),
38
)
39
.after(bevy_camera::visibility::VisibilitySystems::CalculateBounds)
40
.after(TransformSystems::Propagate),
41
);
42
}
43
}
44
/// The [`GizmoConfigGroup`] used for debug visualizations of [`Aabb`] components on entities
45
#[derive(Clone, Default, Reflect, GizmoConfigGroup)]
46
#[reflect(Clone, Default)]
47
pub struct AabbGizmoConfigGroup {
48
/// Draws all bounding boxes in the scene when set to `true`.
49
///
50
/// To draw a specific entity's bounding box, you can add the [`ShowAabbGizmo`] component.
51
///
52
/// Defaults to `false`.
53
pub draw_all: bool,
54
/// The default color for bounding box gizmos.
55
///
56
/// A random color is chosen per box if `None`.
57
///
58
/// Defaults to `None`.
59
pub default_color: Option<Color>,
60
}
61
62
/// Add this [`Component`] to an entity to draw its [`Aabb`] component.
63
#[derive(Component, Reflect, Default, Debug)]
64
#[reflect(Component, Default, Debug)]
65
pub struct ShowAabbGizmo {
66
/// The color of the box.
67
///
68
/// The default color from the [`AabbGizmoConfigGroup`] config is used if `None`,
69
pub color: Option<Color>,
70
}
71
72
fn draw_aabbs(
73
query: Query<(Entity, &Aabb, &GlobalTransform, &ShowAabbGizmo)>,
74
mut gizmos: Gizmos<AabbGizmoConfigGroup>,
75
) {
76
for (entity, &aabb, &transform, gizmo) in &query {
77
let color = gizmo
78
.color
79
.or(gizmos.config_ext.default_color)
80
.unwrap_or_else(|| color_from_entity(entity));
81
gizmos.cuboid(aabb_transform(aabb, transform), color);
82
}
83
}
84
85
fn draw_all_aabbs(
86
query: Query<(Entity, &Aabb, &GlobalTransform), Without<ShowAabbGizmo>>,
87
mut gizmos: Gizmos<AabbGizmoConfigGroup>,
88
) {
89
for (entity, &aabb, &transform) in &query {
90
let color = gizmos
91
.config_ext
92
.default_color
93
.unwrap_or_else(|| color_from_entity(entity));
94
gizmos.cuboid(aabb_transform(aabb, transform), color);
95
}
96
}
97
98
fn color_from_entity(entity: Entity) -> Color {
99
Oklcha::sequential_dispersed(entity.index()).into()
100
}
101
102
fn aabb_transform(aabb: Aabb, transform: GlobalTransform) -> GlobalTransform {
103
transform
104
* GlobalTransform::from(
105
Transform::from_translation(aabb.center.into())
106
.with_scale((aabb.half_extents * 2.).into()),
107
)
108
}
109
110