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