avian3d/debug_render/
configuration.rs

1use crate::prelude::*;
2use bevy::{color::palettes::css::*, prelude::*};
3
4/// Gizmos used for debug rendering physics. See [`PhysicsDebugPlugin`]
5///
6/// You can configure what is rendered by inserting the [`PhysicsGizmos`] configuration group
7/// or by getting it from the `GizmoConfigStore` resource and mutating the returned configuration.
8///
9/// To configure the debug rendering of specific entities, use the [`DebugRender`] component.
10///
11/// # Example
12///
13/// ```no_run
14#[cfg_attr(feature = "2d", doc = "use avian2d::prelude::*;")]
15#[cfg_attr(feature = "3d", doc = "use avian3d::prelude::*;")]
16/// use bevy::prelude::*;
17///
18/// fn main() {
19///     App::new()
20///         .add_plugins((
21///             DefaultPlugins,
22///             PhysicsPlugins::default(),
23///             // Enables debug rendering
24///             PhysicsDebugPlugin,
25///         ))
26///         // Overwrite default debug rendering configuration (optional)
27///         .insert_gizmo_config(
28///             PhysicsGizmos {
29///                 aabb_color: Some(Color::WHITE),
30///                 ..default()
31///             },
32///             GizmoConfig::default(),
33///         )
34///         .run();
35/// }
36///
37/// fn setup(mut commands: Commands) {
38///     // This rigid body and its collider and AABB will get rendered
39#[cfg_attr(
40    feature = "2d",
41    doc = "    commands.spawn((RigidBody::Dynamic, Collider::circle(0.5)));"
42)]
43#[cfg_attr(
44    feature = "3d",
45    doc = "    commands.spawn((RigidBody::Dynamic, Collider::sphere(0.5)));"
46)]
47/// }
48/// ```
49#[derive(Reflect, GizmoConfigGroup)]
50#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
51#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
52pub struct PhysicsGizmos {
53    /// The lengths of the axes drawn for an entity at the center of mass.
54    pub axis_lengths: Option<Vector>,
55    /// The color of the [AABBs](ColliderAabb). If `None`, the AABBs will not be rendered.
56    pub aabb_color: Option<Color>,
57    /// The color of the [collider](Collider) wireframes. If `None`, the colliders will not be rendered.
58    pub collider_color: Option<Color>,
59    /// The colors (in HSLA) for [sleeping](Sleeping) bodies will be multiplied by this array.
60    /// If `None`, sleeping will have no effect on the colors.
61    pub sleeping_color_multiplier: Option<[f32; 4]>,
62    /// The color of the contact points. If `None`, the contact points will not be rendered.
63    pub contact_point_color: Option<Color>,
64    /// The color of the contact normals. If `None`, the contact normals will not be rendered.
65    pub contact_normal_color: Option<Color>,
66    /// The scale used for contact normals.
67    pub contact_normal_scale: ContactGizmoScale,
68    /// The color of the lines drawn from the centers of bodies to their joint anchors.
69    pub joint_anchor_color: Option<Color>,
70    /// The color of the lines drawn between joint anchors, indicating the separation.
71    pub joint_separation_color: Option<Color>,
72    /// The color used for the rays in [raycasts](spatial_query#raycasting).
73    pub raycast_color: Option<Color>,
74    /// The color used for the hit points in [raycasts](spatial_query#raycasting).
75    pub raycast_point_color: Option<Color>,
76    /// The color used for the hit normals in [raycasts](spatial_query#raycasting).
77    pub raycast_normal_color: Option<Color>,
78    /// The color used for the ray in [shapecasts](spatial_query#shapecasting).
79    pub shapecast_color: Option<Color>,
80    /// The color used for the shape in [shapecasts](spatial_query#shapecasting).
81    pub shapecast_shape_color: Option<Color>,
82    /// The color used for the hit points in [shapecasts](spatial_query#shapecasting).
83    pub shapecast_point_color: Option<Color>,
84    /// The color used for the hit normals in [shapecasts](spatial_query#shapecasting).
85    pub shapecast_normal_color: Option<Color>,
86    /// The color used for the bounds of [`PhysicsIsland`](dynamics::solver::islands::PhysicsIsland)s.
87    pub island_color: Option<Color>,
88    /// The color used for [`ColliderTree`](crate::collider_tree) nodes.
89    pub collider_tree_color: Option<Color>,
90    /// Determines if the visibility of entities with [colliders](Collider) should be set to `Visibility::Hidden`,
91    /// which will only show the debug renders.
92    pub hide_meshes: bool,
93}
94
95impl Default for PhysicsGizmos {
96    fn default() -> Self {
97        Self {
98            axis_lengths: Some(Vector::splat(0.5)),
99            aabb_color: None,
100            collider_color: Some(ORANGE.into()),
101            sleeping_color_multiplier: Some([1.0, 1.0, 0.4, 1.0]),
102            contact_point_color: None,
103            contact_normal_color: None,
104            contact_normal_scale: ContactGizmoScale::default(),
105            joint_anchor_color: Some(PINK.into()),
106            joint_separation_color: Some(RED.into()),
107            raycast_color: Some(RED.into()),
108            raycast_point_color: Some(YELLOW.into()),
109            raycast_normal_color: Some(PINK.into()),
110            shapecast_color: Some(RED.into()),
111            shapecast_shape_color: Some(Color::srgb(0.4, 0.6, 1.0)),
112            shapecast_point_color: Some(YELLOW.into()),
113            shapecast_normal_color: Some(PINK.into()),
114            island_color: None,
115            collider_tree_color: None,
116            hide_meshes: false,
117        }
118    }
119}
120
121/// The scale used for contact normals rendered using gizmos.
122#[derive(Reflect, Clone, Copy, PartialEq)]
123#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
124#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
125#[reflect(PartialEq)]
126pub enum ContactGizmoScale {
127    /// The length of the rendered contact normal is constant.
128    Constant(Scalar),
129    /// The length of the rendered contact normal is scaled by the contact force and the given scaling factor.
130    Scaled(Scalar),
131}
132
133impl Default for ContactGizmoScale {
134    fn default() -> Self {
135        Self::Scaled(0.025)
136    }
137}
138
139impl PhysicsGizmos {
140    /// Creates a [`PhysicsGizmos`] configuration with all rendering options enabled.
141    pub fn all() -> Self {
142        Self {
143            axis_lengths: Some(Vector::splat(0.5)),
144            aabb_color: Some(Color::srgb(0.8, 0.8, 0.8)),
145            collider_color: Some(ORANGE.into()),
146            sleeping_color_multiplier: Some([1.0, 1.0, 0.4, 1.0]),
147            contact_point_color: Some(LIGHT_CYAN.into()),
148            contact_normal_color: Some(RED.into()),
149            contact_normal_scale: ContactGizmoScale::default(),
150            joint_anchor_color: Some(PINK.into()),
151            joint_separation_color: Some(RED.into()),
152            raycast_color: Some(RED.into()),
153            raycast_point_color: Some(YELLOW.into()),
154            raycast_normal_color: Some(PINK.into()),
155            shapecast_color: Some(RED.into()),
156            shapecast_shape_color: Some(Color::srgb(0.4, 0.6, 1.0)),
157            shapecast_point_color: Some(YELLOW.into()),
158            shapecast_normal_color: Some(PINK.into()),
159            island_color: Some(RED.into()),
160            collider_tree_color: Some(Color::WHITE),
161            hide_meshes: true,
162        }
163    }
164
165    /// Creates a [`PhysicsGizmos`] configuration with debug rendering enabled but all options turned off.
166    ///
167    /// Note: this doesn't affect entities with [`DebugRender`] component; their debug gizmos will be visible.
168    pub fn none() -> Self {
169        Self {
170            axis_lengths: None,
171            aabb_color: None,
172            collider_color: None,
173            sleeping_color_multiplier: None,
174            contact_point_color: None,
175            contact_normal_color: None,
176            contact_normal_scale: ContactGizmoScale::default(),
177            joint_anchor_color: None,
178            joint_separation_color: None,
179            raycast_color: None,
180            raycast_point_color: None,
181            raycast_normal_color: None,
182            shapecast_color: None,
183            shapecast_shape_color: None,
184            shapecast_point_color: None,
185            shapecast_normal_color: None,
186            island_color: None,
187            collider_tree_color: None,
188            hide_meshes: false,
189        }
190    }
191
192    /// Creates a [`PhysicsGizmos`] configuration with the given lengths for the axes
193    /// that are drawn for the entity at the center of mass. Other debug rendering options will be disabled.
194    pub fn axes(axis_lengths: Vector) -> Self {
195        Self {
196            axis_lengths: Some(axis_lengths),
197            ..Self::none()
198        }
199    }
200
201    /// Creates a [`PhysicsGizmos`] configuration with a given AABB color.
202    /// Other debug rendering options will be disabled.
203    pub fn aabbs(color: Color) -> Self {
204        Self {
205            aabb_color: Some(color),
206            ..Self::none()
207        }
208    }
209
210    /// Creates a [`PhysicsGizmos`] configuration with a given collider color.
211    /// Other debug rendering options will be disabled.
212    pub fn colliders(color: Color) -> Self {
213        Self {
214            collider_color: Some(color),
215            ..Self::none()
216        }
217    }
218
219    /// Creates a [`PhysicsGizmos`] configuration with a given contact point color.
220    /// Other debug rendering options will be disabled.
221    pub fn contact_points(color: Color) -> Self {
222        Self {
223            contact_point_color: Some(color),
224            ..Self::none()
225        }
226    }
227
228    /// Creates a [`PhysicsGizmos`] configuration with a given contact normal color.
229    /// Other debug rendering options will be disabled.
230    pub fn contact_normals(color: Color) -> Self {
231        Self {
232            contact_normal_color: Some(color),
233            ..Self::none()
234        }
235    }
236
237    /// Creates a [`PhysicsGizmos`] configuration with given colors for
238    /// joint anchors and separation distances. Other debug rendering options will be disabled.
239    pub fn joints(anchor_color: Option<Color>, separation_color: Option<Color>) -> Self {
240        Self {
241            joint_anchor_color: anchor_color,
242            joint_separation_color: separation_color,
243            ..Self::none()
244        }
245    }
246
247    /// Sets the lengths of the axes drawn for the entity.
248    pub fn with_axes(mut self, axis_lengths: Vector) -> Self {
249        self.axis_lengths = Some(axis_lengths);
250        self
251    }
252
253    /// Sets the AABB color.
254    pub fn with_aabb_color(mut self, color: Color) -> Self {
255        self.aabb_color = Some(color);
256        self
257    }
258
259    /// Sets the collider color.
260    pub fn with_collider_color(mut self, color: Color) -> Self {
261        self.collider_color = Some(color);
262        self
263    }
264
265    /// Sets the multiplier used for the colors (in HSLA) of [sleeping](Sleeping) bodies.
266    pub fn with_sleeping_color_multiplier(mut self, color_multiplier: [f32; 4]) -> Self {
267        self.sleeping_color_multiplier = Some(color_multiplier);
268        self
269    }
270
271    /// Sets the contact point color.
272    pub fn with_contact_point_color(mut self, color: Color) -> Self {
273        self.contact_point_color = Some(color);
274        self
275    }
276
277    /// Sets the contact normal color.
278    pub fn with_contact_normal_color(mut self, color: Color) -> Self {
279        self.contact_normal_color = Some(color);
280        self
281    }
282
283    /// Sets the contact normal scale.
284    pub fn with_contact_normal_scale(mut self, scale: ContactGizmoScale) -> Self {
285        self.contact_normal_scale = scale;
286        self
287    }
288
289    /// Sets the colors used for debug rendering joints.
290    pub fn with_joint_colors(anchor_color: Option<Color>, separation_color: Option<Color>) -> Self {
291        Self {
292            joint_anchor_color: anchor_color,
293            joint_separation_color: separation_color,
294            ..Self::none()
295        }
296    }
297
298    /// Sets the colors used for debug rendering raycasts.
299    pub fn with_raycast_colors(
300        mut self,
301        ray: Option<Color>,
302        hit_point: Option<Color>,
303        hit_normal: Option<Color>,
304    ) -> Self {
305        self.raycast_color = ray;
306        self.raycast_point_color = hit_point;
307        self.raycast_normal_color = hit_normal;
308        self
309    }
310
311    /// Sets the colors used for debug rendering shapecasts.
312    pub fn with_shapecast_colors(
313        mut self,
314        ray: Option<Color>,
315        shape: Option<Color>,
316        hit_point: Option<Color>,
317        hit_normal: Option<Color>,
318    ) -> Self {
319        self.shapecast_color = ray;
320        self.shapecast_shape_color = shape;
321        self.shapecast_point_color = hit_point;
322        self.shapecast_normal_color = hit_normal;
323        self
324    }
325
326    /// Sets the visibility of the entity's visual mesh.
327    pub fn with_mesh_visibility(mut self, is_visible: bool) -> Self {
328        self.hide_meshes = !is_visible;
329        self
330    }
331
332    /// Disables axis debug rendering.
333    pub fn without_axes(mut self) -> Self {
334        self.axis_lengths = None;
335        self
336    }
337
338    /// Disables AABB debug rendering.
339    pub fn without_aabbs(mut self) -> Self {
340        self.aabb_color = None;
341        self
342    }
343
344    /// Disables collider debug rendering.
345    pub fn without_colliders(mut self) -> Self {
346        self.collider_color = None;
347        self
348    }
349
350    /// Disables contact point debug rendering.
351    pub fn without_contact_points(mut self) -> Self {
352        self.contact_point_color = None;
353        self
354    }
355
356    /// Disables contact normal debug rendering.
357    pub fn without_contact_normals(mut self) -> Self {
358        self.contact_normal_color = None;
359        self
360    }
361
362    /// Disables joint debug rendering.
363    pub fn without_joints(mut self) -> Self {
364        self.joint_anchor_color = None;
365        self.joint_separation_color = None;
366        self
367    }
368
369    /// Disables raycast debug rendering.
370    pub fn without_raycasts(mut self) -> Self {
371        self.raycast_color = None;
372        self.raycast_point_color = None;
373        self.raycast_normal_color = None;
374        self
375    }
376
377    /// Disables shapecast debug rendering.
378    pub fn without_shapecasts(mut self) -> Self {
379        self.shapecast_color = None;
380        self.shapecast_shape_color = None;
381        self.shapecast_point_color = None;
382        self.shapecast_normal_color = None;
383        self
384    }
385}
386
387/// A component for the debug render configuration of an entity. See [`PhysicsDebugPlugin`].
388///
389/// This overwrites the global [`PhysicsGizmos`] for this specific entity.
390///
391/// # Example
392///
393/// ```no_run
394#[cfg_attr(feature = "2d", doc = "use avian2d::prelude::*;")]
395#[cfg_attr(feature = "3d", doc = "use avian3d::prelude::*;")]
396/// use bevy::prelude::*;
397///
398/// fn main() {
399///     App::new()
400///         .add_plugins((
401///             DefaultPlugins,
402///             PhysicsPlugins::default(),
403///             // Enables debug rendering
404///             PhysicsDebugPlugin,
405///         ))
406///         .run();
407/// }
408///
409/// fn setup(mut commands: Commands) {
410///     // This rigid body and its collider and AABB will get rendered
411///     commands.spawn((
412///         RigidBody::Dynamic,
413#[cfg_attr(feature = "2d", doc = "        Collider::circle(0.5),")]
414#[cfg_attr(feature = "3d", doc = "        Collider::sphere(0.5),")]
415///         // Overwrite default collider color (optional)
416///         DebugRender::default().with_collider_color(Color::srgb(1.0, 0.0, 0.0)),
417///     ));
418/// }
419/// ```
420#[derive(Component, Reflect, Clone, Copy, PartialEq)]
421#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
422#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
423#[reflect(Component, PartialEq)]
424pub struct DebugRender {
425    /// The lengths of the axes drawn for the entity at the center of mass.
426    pub axis_lengths: Option<Vector>,
427    /// The color of the [AABB](ColliderAabb). If `None`, the AABB will not be rendered.
428    pub aabb_color: Option<Color>,
429    /// The color of the [collider](Collider) wireframe. If `None`, the collider will not be rendered.
430    pub collider_color: Option<Color>,
431    /// If the entity is [sleeping](Sleeping), its colors (in HSLA) will be multiplied by this array.
432    /// If `None`, sleeping will have no effect on the colors.
433    pub sleeping_color_multiplier: Option<[f32; 4]>,
434    /// Determines if the entity's visibility should be set to `Visibility::Hidden`, which will only show the debug render.
435    pub hide_mesh: bool,
436}
437
438impl Default for DebugRender {
439    fn default() -> Self {
440        Self {
441            #[cfg(feature = "2d")]
442            axis_lengths: Some(Vector::new(5.0, 5.0)),
443            #[cfg(feature = "3d")]
444            axis_lengths: Some(Vector::new(0.5, 0.5, 0.5)),
445            aabb_color: None,
446            collider_color: Some(ORANGE.into()),
447            sleeping_color_multiplier: Some([1.0, 1.0, 0.4, 1.0]),
448            hide_mesh: false,
449        }
450    }
451}
452
453impl DebugRender {
454    /// Creates a [`DebugRender`] configuration with all rendering options enabled.
455    pub fn all() -> Self {
456        Self {
457            #[cfg(feature = "2d")]
458            axis_lengths: Some(Vector::new(5.0, 5.0)),
459            #[cfg(feature = "3d")]
460            axis_lengths: Some(Vector::new(0.5, 0.5, 0.5)),
461            aabb_color: Some(Color::srgb(0.8, 0.8, 0.8)),
462            collider_color: Some(ORANGE.into()),
463            sleeping_color_multiplier: Some([1.0, 1.0, 0.4, 1.0]),
464            hide_mesh: true,
465        }
466    }
467
468    /// Disables all debug rendering for this entity.
469    pub fn none() -> Self {
470        Self {
471            axis_lengths: None,
472            aabb_color: None,
473            collider_color: None,
474            sleeping_color_multiplier: None,
475            hide_mesh: false,
476        }
477    }
478
479    /// Creates a [`DebugRender`] configuration with the given lengths for the axes
480    /// that are drawn for the entity at the center of mass. Other debug rendering options will be disabled.
481    pub fn axes(axis_lengths: Vector) -> Self {
482        Self {
483            axis_lengths: Some(axis_lengths),
484            ..Self::none()
485        }
486    }
487
488    /// Creates a [`DebugRender`] configuration with a given AABB color.
489    /// Other debug rendering options will be disabled.
490    pub fn aabb(color: Color) -> Self {
491        Self {
492            aabb_color: Some(color),
493            ..Self::none()
494        }
495    }
496
497    /// Creates a [`DebugRender`] configuration with a given collider color.
498    /// Other debug rendering options will be disabled.
499    pub fn collider(color: Color) -> Self {
500        Self {
501            collider_color: Some(color),
502            ..Self::none()
503        }
504    }
505
506    /// Sets the lengths of the axes drawn for the entity at the center of mass.
507    pub fn with_axes(mut self, axis_lengths: Vector) -> Self {
508        self.axis_lengths = Some(axis_lengths);
509        self
510    }
511
512    /// Sets the AABB color.
513    pub fn with_aabb_color(mut self, color: Color) -> Self {
514        self.aabb_color = Some(color);
515        self
516    }
517
518    /// Sets the collider color.
519    pub fn with_collider_color(mut self, color: Color) -> Self {
520        self.collider_color = Some(color);
521        self
522    }
523
524    /// Sets the multiplier used for the colors (in HSLA) of [sleeping](Sleeping) bodies.
525    pub fn with_sleeping_color_multiplier(mut self, color_multiplier: [f32; 4]) -> Self {
526        self.sleeping_color_multiplier = Some(color_multiplier);
527        self
528    }
529
530    /// Sets the visibility of the entity's visual mesh.
531    pub fn with_mesh_visibility(mut self, is_visible: bool) -> Self {
532        self.hide_mesh = !is_visible;
533        self
534    }
535
536    /// Disables axis debug rendering.
537    pub fn without_axes(mut self) -> Self {
538        self.axis_lengths = None;
539        self
540    }
541
542    /// Disables AABB debug rendering.
543    pub fn without_aabb(mut self) -> Self {
544        self.aabb_color = None;
545        self
546    }
547
548    /// Disables collider debug rendering.
549    pub fn without_collider(mut self) -> Self {
550        self.collider_color = None;
551        self
552    }
553}