Skip to content

Commit 92dfd0c

Browse files
fleshed out the example some
1 parent d251dfb commit 92dfd0c

File tree

2 files changed

+125
-22
lines changed

2 files changed

+125
-22
lines changed

crates/bevy_gizmos_render/src/retained.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,25 +101,22 @@ pub(crate) fn extract_linegizmos(
101101
pub(crate) fn calculate_bounds(
102102
mut commands: Commands,
103103
gizmo_assets: Res<Assets<GizmoAsset>>,
104-
without_aabb: Query<
104+
needs_aabb: Query<
105105
(Entity, &Gizmo),
106106
(
107107
Or<(Changed<Gizmo>, Without<Aabb>)>,
108108
Without<NoFrustumCulling>,
109109
),
110110
>,
111111
) {
112-
for (entity, gizmo) in &without_aabb {
112+
for (entity, gizmo) in &needs_aabb {
113113
if let Some(gizmo_asset) = gizmo_assets.get(&gizmo.handle) {
114-
println!("Calculating AABB for gizmo entity {:?}", entity);
115114
let aabb_3d = Aabb3d::from_point_cloud(
116115
Isometry3d::IDENTITY,
117116
gizmo_asset
118117
.list_positions
119118
.iter()
120119
.chain(gizmo_asset.strip_positions.iter())
121-
// infinite points show up in here for some reason
122-
// i am brutally filtering them for now
123120
.filter(|p| p.is_finite())
124121
.map(|&p| Vec3A::from(p)),
125122
);

examples/gizmos/retained_gizmos.rs

Lines changed: 123 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,121 @@
1-
//! This example demonstrates Bevy's visual debugging using retained gizmos.
1+
//! This example demonstrates retained gizmos.
22
33
use bevy::{
44
camera_controller::free_camera::{FreeCamera, FreeCameraPlugin},
55
color::palettes::css::*,
66
prelude::*,
77
};
8+
use rand::Rng;
89

910
fn main() {
1011
App::new()
1112
.add_plugins((DefaultPlugins, FreeCameraPlugin))
12-
//.init_gizmo_group::<MyRoundGizmos>()
1313
.add_systems(Startup, setup)
14-
// .add_systems(
15-
// Update,
16-
// (
17-
// draw_example_collection,
18-
// update_config,
19-
// update_retained_gizmo_visibility,
20-
// ),
21-
// )
14+
.add_systems(Update, (spawn_gizmo, spin, twinkle))
15+
.add_observer(on_spawn_gizmo)
2216
.run();
2317
}
2418

25-
fn setup(mut commands: Commands, mut gizmo_assets: ResMut<Assets<GizmoAsset>>) {
19+
fn setup(mut commands: Commands) {
2620
commands.spawn((
21+
Camera {
22+
clear_color: ClearColorConfig::Custom(BLACK.into()),
23+
..default()
24+
},
2725
Camera3d::default(),
28-
Transform::from_xyz(0., 1.5, 6.).looking_at(Vec3::NEG_Z, Vec3::Y),
26+
Transform::from_xyz(0., 0., 6.).looking_at(Vec3::NEG_Z, Vec3::Y),
2927
FreeCamera::default(),
3028
));
29+
}
30+
31+
const COLORS: [Srgba; 7] = [
32+
CORNSILK,
33+
DARK_ORANGE,
34+
MEDIUM_AQUAMARINE,
35+
CORAL,
36+
BISQUE,
37+
ANTIQUE_WHITE,
38+
BLUE_VIOLET,
39+
];
40+
41+
#[derive(Component)]
42+
struct Spin(f32);
43+
44+
#[derive(Component)]
45+
struct Twinkler {
46+
timer: Timer,
47+
not_before: f32,
48+
}
49+
50+
#[derive(Deref, DerefMut)]
51+
struct SpawnTimer(Timer);
52+
53+
impl Default for SpawnTimer {
54+
fn default() -> Self {
55+
SpawnTimer(Timer::from_seconds(0.1, TimerMode::Once))
56+
}
57+
}
58+
59+
fn spawn_gizmo(
60+
mut commands: Commands,
61+
mut timer: Local<SpawnTimer>,
62+
gizmos: Query<Entity, With<Gizmo>>,
63+
time: Res<Time>,
64+
) {
65+
timer.tick(time.delta());
66+
if !timer.just_finished() {
67+
return;
68+
}
69+
let mut rng = rand::rng();
70+
**timer = Timer::from_seconds(rng.random_range(1.2..3.8), TimerMode::Once);
71+
72+
let total = gizmos.iter().count();
3173

74+
if total > 25 && rng.random_bool((total as f64 / 150.0).min(1.0)) {
75+
if let Some(entity) = gizmos.iter().nth(rng.random_range(0..total)) {
76+
commands.entity(entity).despawn();
77+
}
78+
return;
79+
}
80+
81+
commands.trigger(SpawnGizmo);
82+
}
83+
84+
#[derive(Event)]
85+
struct SpawnGizmo;
86+
87+
fn on_spawn_gizmo(
88+
_: On<SpawnGizmo>,
89+
mut commands: Commands,
90+
mut gizmo_assets: ResMut<Assets<GizmoAsset>>,
91+
) {
3292
let mut gizmo = GizmoAsset::new();
3393

94+
let mut rng = rand::rng();
95+
let radius = rng.random_range(0.5..2.0);
96+
let x = rng.random_range(-31.0..31.0);
97+
let y = rng.random_range(-17.0..17.0);
98+
let z = rng.random_range(-50.0..-30.0);
99+
let axis = Vec3::new(
100+
rng.random_range(-1.0..1.0),
101+
rng.random_range(-1.0..1.0),
102+
rng.random_range(-1.0..1.0),
103+
)
104+
.normalize_or(Vec3::Y);
105+
let up = axis.any_orthonormal_vector();
106+
let spin_rate = rng.random_range(-0.5..0.5);
107+
34108
// When drawing a lot of static lines a Gizmo component can have
35109
// far better performance than the Gizmos system parameter,
36110
// but the system parameter will perform better for smaller lines that update often.
37-
38-
// we'll sprinkle spheres made of 3,000 lines throughout the scene
39-
// and make the blink
111+
let color = COLORS[rng.random_range(0..COLORS.len())];
40112
gizmo
41-
.sphere(Isometry3d::IDENTITY, 0.5, LIGHT_GOLDENROD_YELLOW)
113+
.sphere(Isometry3d::IDENTITY, radius, color)
42114
.resolution(3_000 / 3);
43115

116+
let color = COLORS[rng.random_range(0..COLORS.len())];
117+
gizmo.cross(Isometry3d::IDENTITY, radius, color);
118+
44119
commands.spawn((
45120
Gizmo {
46121
handle: gizmo_assets.add(gizmo),
@@ -50,6 +125,37 @@ fn setup(mut commands: Commands, mut gizmo_assets: ResMut<Assets<GizmoAsset>>) {
50125
},
51126
..default()
52127
},
53-
Transform::IDENTITY,
128+
Transform::from_translation(vec3(x, y, z)).looking_to(axis, up),
129+
Spin(spin_rate),
54130
));
55131
}
132+
133+
fn spin(mut spinners: Query<(&mut Transform, &Spin)>, time: Res<Time>) {
134+
for (mut transform, spin) in &mut spinners {
135+
transform.rotate_local_y(time.delta_secs() * spin.0);
136+
}
137+
}
138+
139+
fn twinkle(
140+
mut commands: Commands,
141+
mut gizmos: Query<(Entity, &mut Visibility, Option<&mut Twinkler>), With<Gizmo>>,
142+
time: Res<Time>,
143+
) {
144+
for (entity, mut visibility, twinkler) in &mut gizmos {
145+
if let Some(mut twinkler) = twinkler {
146+
twinkler.timer.tick(time.delta());
147+
if twinkler.timer.just_finished() {
148+
*visibility = Visibility::Visible;
149+
}
150+
if twinkler.not_before < time.elapsed_secs() {
151+
commands.entity(entity).remove::<Twinkler>();
152+
}
153+
} else if rand::rng().random_bool(0.001) {
154+
*visibility = Visibility::Hidden;
155+
commands.entity(entity).insert(Twinkler {
156+
timer: Timer::from_seconds(rand::rng().random_range(0.3..0.8), TimerMode::Once),
157+
not_before: time.elapsed_secs() + rand::rng().random_range(5.0..15.0),
158+
});
159+
}
160+
}
161+
}

0 commit comments

Comments
 (0)