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