Skip to content

Commit c2bed72

Browse files
barsoosayqueVrixyz
andauthored
Per entity/collider debug rendering (#278)
Co-authored-by: Thierry Berger <[email protected]>
1 parent c556052 commit c2bed72

File tree

6 files changed

+334
-2
lines changed

6 files changed

+334
-2
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ during a frame which would not run a simulation step.
1717
- Added a `TriMeshFlags` parameter for `ComputedColliderShape`,
1818
its default value is `TriMeshFlags::MERGE_DUPLICATE_VERTICES`,
1919
which was its hardcoded behaviour.
20+
- Added a way to configure which colliders should be debug rendered: `global` parameter for both
21+
`RapierDebugColliderPlugin` and `DebugRenderContext`, as well as individual collider setup via
22+
a `ColliderDebug` component.
2023

2124
## v0.27.0 (07 July 2024)
2225

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
use std::time::Duration;
2+
3+
pub use bevy::input::common_conditions::input_just_pressed;
4+
use bevy::prelude::*;
5+
use bevy_rapier2d::prelude::*;
6+
7+
fn main() {
8+
App::new()
9+
.insert_resource(ClearColor(Color::srgb(
10+
0xF9 as f32 / 255.0,
11+
0xF9 as f32 / 255.0,
12+
0xFF as f32 / 255.0,
13+
)))
14+
.add_plugins((
15+
DefaultPlugins,
16+
RapierPhysicsPlugin::<NoUserData>::default(),
17+
RapierDebugRenderPlugin::default(),
18+
))
19+
.add_systems(Startup, (setup_graphics, setup_physics))
20+
.add_systems(
21+
Update,
22+
(
23+
toggle_debug,
24+
(|mut debug_render_context: ResMut<DebugRenderContext>| {
25+
debug_render_context.enabled = !debug_render_context.enabled;
26+
})
27+
.run_if(input_just_pressed(KeyCode::KeyV)),
28+
),
29+
)
30+
.run();
31+
}
32+
33+
pub fn setup_graphics(mut commands: Commands) {
34+
commands.spawn(Camera3dBundle {
35+
transform: Transform::from_xyz(-30.0, 30.0, 100.0)
36+
.looking_at(Vec3::new(0.0, 10.0, 0.0), Vec3::Y),
37+
..Default::default()
38+
});
39+
}
40+
41+
#[derive(Component)]
42+
pub struct DebugCooldown(pub Timer);
43+
44+
pub fn setup_physics(mut commands: Commands) {
45+
/*
46+
* Ground
47+
*/
48+
let ground_size = 200.1;
49+
let ground_height = 0.1;
50+
51+
commands.spawn((
52+
TransformBundle::from(Transform::from_xyz(0.0, -ground_height, 0.0)),
53+
Collider::cuboid(ground_size, ground_height),
54+
));
55+
56+
/*
57+
* Create the cubes
58+
*/
59+
let num = 8;
60+
let rad = 1.0;
61+
62+
let shift = rad * 2.0 + rad;
63+
let centerx = shift * (num / 2) as f32;
64+
let centery = shift / 2.0;
65+
let centerz = shift * (num / 2) as f32;
66+
67+
let mut offset = -(num as f32) * (rad * 2.0 + rad) * 0.5;
68+
let mut color = 0;
69+
let colors = [
70+
Hsla::hsl(220.0, 1.0, 0.3),
71+
Hsla::hsl(180.0, 1.0, 0.3),
72+
Hsla::hsl(260.0, 1.0, 0.7),
73+
];
74+
75+
for j in 0usize..20 {
76+
for i in 0..num {
77+
for k in 0usize..num {
78+
let x = i as f32 * shift - centerx + offset;
79+
let y = j as f32 * shift + centery + 3.0;
80+
let z = k as f32 * shift - centerz + offset;
81+
color += 1;
82+
83+
commands
84+
.spawn(TransformBundle::from(Transform::from_rotation(
85+
Quat::from_rotation_x(0.2),
86+
)))
87+
.with_children(|child| {
88+
child.spawn((
89+
TransformBundle::from(Transform::from_xyz(x, y, z)),
90+
RigidBody::Dynamic,
91+
Collider::cuboid(rad, rad),
92+
ColliderDebugColor(colors[color % 3]),
93+
ColliderDebug::AlwaysRender,
94+
DebugCooldown(Timer::new(
95+
Duration::from_secs_f32(0.4f32 + (i % 3 + (j + 1) % 3) as f32),
96+
TimerMode::Repeating,
97+
)),
98+
));
99+
});
100+
}
101+
}
102+
103+
offset -= 0.05 * rad * (num as f32 - 1.0);
104+
}
105+
}
106+
107+
pub fn toggle_debug(time: Res<Time>, mut query: Query<(&mut ColliderDebug, &mut DebugCooldown)>) {
108+
for (mut debug, mut cooldown) in query.iter_mut() {
109+
cooldown.0.tick(time.delta());
110+
if cooldown.0.just_finished() {
111+
*debug = match *debug {
112+
ColliderDebug::AlwaysRender => ColliderDebug::NeverRender,
113+
ColliderDebug::NeverRender => ColliderDebug::AlwaysRender,
114+
}
115+
}
116+
}
117+
}

bevy_rapier2d/examples/testbed2.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
mod boxes2;
44
mod debug_despawn2;
5+
mod debug_toggle2;
56
mod despawn2;
67
mod events2;
78
mod joints2;
@@ -21,6 +22,7 @@ pub enum Examples {
2122
#[default]
2223
None,
2324
Boxes2,
25+
DebugToggle2,
2426
RopeJoint2,
2527
DebugDespawn2,
2628
Despawn2,
@@ -90,6 +92,23 @@ fn main() {
9092
)
9193
.add_systems(OnExit(Examples::Boxes2), cleanup)
9294
//
95+
// Debug toggle
96+
.add_systems(
97+
OnEnter(Examples::DebugToggle2),
98+
(debug_toggle2::setup_graphics, debug_toggle2::setup_physics),
99+
)
100+
.add_systems(
101+
Update,
102+
(
103+
debug_toggle2::toggle_debug,
104+
(|mut debug_render_context: ResMut<DebugRenderContext>| {
105+
debug_render_context.enabled = !debug_render_context.enabled;
106+
})
107+
.run_if(debug_toggle2::input_just_pressed(KeyCode::KeyV)),
108+
)
109+
.run_if(in_state(Examples::DebugToggle2)),
110+
)
111+
//
93112
// rope joint
94113
.add_systems(
95114
OnEnter(Examples::RopeJoint2),
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
use std::time::Duration;
2+
3+
pub use bevy::input::common_conditions::input_just_pressed;
4+
use bevy::prelude::*;
5+
use bevy_rapier3d::prelude::*;
6+
7+
fn main() {
8+
App::new()
9+
.insert_resource(ClearColor(Color::srgb(
10+
0xF9 as f32 / 255.0,
11+
0xF9 as f32 / 255.0,
12+
0xFF as f32 / 255.0,
13+
)))
14+
.add_plugins((
15+
DefaultPlugins,
16+
RapierPhysicsPlugin::<NoUserData>::default(),
17+
RapierDebugRenderPlugin::default(),
18+
))
19+
.add_systems(Startup, (setup_graphics, setup_physics))
20+
.add_systems(
21+
Update,
22+
(
23+
toggle_debug,
24+
(|mut debug_render_context: ResMut<DebugRenderContext>| {
25+
debug_render_context.enabled = !debug_render_context.enabled;
26+
})
27+
.run_if(input_just_pressed(KeyCode::KeyV)),
28+
),
29+
)
30+
.run();
31+
}
32+
33+
pub fn setup_graphics(mut commands: Commands) {
34+
commands.spawn(Camera3dBundle {
35+
transform: Transform::from_xyz(-30.0, 30.0, 100.0)
36+
.looking_at(Vec3::new(0.0, 10.0, 0.0), Vec3::Y),
37+
..Default::default()
38+
});
39+
}
40+
41+
#[derive(Component)]
42+
pub struct DebugCooldown(pub Timer);
43+
44+
pub fn setup_physics(mut commands: Commands) {
45+
/*
46+
* Ground
47+
*/
48+
let ground_size = 200.1;
49+
let ground_height = 0.1;
50+
51+
commands.spawn((
52+
TransformBundle::from(Transform::from_xyz(0.0, -ground_height, 0.0)),
53+
Collider::cuboid(ground_size, ground_height, ground_size),
54+
));
55+
56+
/*
57+
* Create the cubes
58+
*/
59+
let num = 8;
60+
let rad = 1.0;
61+
62+
let shift = rad * 2.0 + rad;
63+
let centerx = shift * (num / 2) as f32;
64+
let centery = shift / 2.0;
65+
let centerz = shift * (num / 2) as f32;
66+
67+
let mut offset = -(num as f32) * (rad * 2.0 + rad) * 0.5;
68+
let mut color = 0;
69+
let colors = [
70+
Hsla::hsl(220.0, 1.0, 0.3),
71+
Hsla::hsl(180.0, 1.0, 0.3),
72+
Hsla::hsl(260.0, 1.0, 0.7),
73+
];
74+
75+
for j in 0usize..20 {
76+
for i in 0..num {
77+
for k in 0usize..num {
78+
let x = i as f32 * shift - centerx + offset;
79+
let y = j as f32 * shift + centery + 3.0;
80+
let z = k as f32 * shift - centerz + offset;
81+
color += 1;
82+
83+
commands
84+
.spawn(TransformBundle::from(Transform::from_rotation(
85+
Quat::from_rotation_x(0.2),
86+
)))
87+
.with_children(|child| {
88+
child.spawn((
89+
TransformBundle::from(Transform::from_xyz(x, y, z)),
90+
RigidBody::Dynamic,
91+
Collider::cuboid(rad, rad, rad),
92+
ColliderDebugColor(colors[color % 3]),
93+
ColliderDebug::AlwaysRender,
94+
DebugCooldown(Timer::new(
95+
Duration::from_secs_f32(0.4f32 + (i % 3 + (j + 1) % 3) as f32),
96+
TimerMode::Repeating,
97+
)),
98+
));
99+
});
100+
}
101+
}
102+
103+
offset -= 0.05 * rad * (num as f32 - 1.0);
104+
}
105+
}
106+
107+
pub fn toggle_debug(time: Res<Time>, mut query: Query<(&mut ColliderDebug, &mut DebugCooldown)>) {
108+
for (mut debug, mut cooldown) in query.iter_mut() {
109+
cooldown.0.tick(time.delta());
110+
if cooldown.0.just_finished() {
111+
*debug = match *debug {
112+
ColliderDebug::AlwaysRender => ColliderDebug::NeverRender,
113+
ColliderDebug::NeverRender => ColliderDebug::AlwaysRender,
114+
}
115+
}
116+
}
117+
}

bevy_rapier3d/examples/testbed3.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#![allow(dead_code)]
22

33
mod boxes3;
4+
mod debug_toggle3;
45
mod despawn3;
56
mod events3;
67
mod joints3;
@@ -20,6 +21,7 @@ pub enum Examples {
2021
#[default]
2122
None,
2223
Boxes3,
24+
DebugToggle3,
2325
Despawn3,
2426
Events3,
2527
Joints3,
@@ -69,6 +71,7 @@ fn main() {
6971
.init_state::<Examples>()
7072
.insert_resource(ExampleSet(vec![
7173
(Examples::Boxes3, "Boxes3").into(),
74+
(Examples::DebugToggle3, "DebugToggle3").into(),
7275
(Examples::Despawn3, "Despawn3").into(),
7376
(Examples::Events3, "Events3").into(),
7477
(Examples::Joints3, "Joints3").into(),
@@ -87,6 +90,23 @@ fn main() {
8790
)
8891
.add_systems(OnExit(Examples::Boxes3), cleanup)
8992
//
93+
// Debug toggle
94+
.add_systems(
95+
OnEnter(Examples::DebugToggle3),
96+
(debug_toggle3::setup_graphics, debug_toggle3::setup_physics),
97+
)
98+
.add_systems(
99+
Update,
100+
(
101+
debug_toggle3::toggle_debug,
102+
(|mut debug_render_context: ResMut<DebugRenderContext>| {
103+
debug_render_context.enabled = !debug_render_context.enabled;
104+
})
105+
.run_if(debug_toggle3::input_just_pressed(KeyCode::KeyV)),
106+
)
107+
.run_if(in_state(Examples::DebugToggle3)),
108+
)
109+
//
90110
// despawn
91111
.init_resource::<despawn3::DespawnResource>()
92112
.add_systems(

0 commit comments

Comments
 (0)