1use crate::prelude::*;
2use bevy::{color::palettes::css::*, prelude::*};
3
4#[cfg_attr(feature = "2d", doc = "use avian2d::prelude::*;")]
15#[cfg_attr(feature = "3d", doc = "use avian3d::prelude::*;")]
16#[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#[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 pub axis_lengths: Option<Vector>,
55 pub aabb_color: Option<Color>,
57 pub collider_color: Option<Color>,
59 pub sleeping_color_multiplier: Option<[f32; 4]>,
62 pub contact_point_color: Option<Color>,
64 pub contact_normal_color: Option<Color>,
66 pub contact_normal_scale: ContactGizmoScale,
68 pub joint_anchor_color: Option<Color>,
70 pub joint_separation_color: Option<Color>,
72 pub raycast_color: Option<Color>,
74 pub raycast_point_color: Option<Color>,
76 pub raycast_normal_color: Option<Color>,
78 pub shapecast_color: Option<Color>,
80 pub shapecast_shape_color: Option<Color>,
82 pub shapecast_point_color: Option<Color>,
84 pub shapecast_normal_color: Option<Color>,
86 pub island_color: Option<Color>,
88 pub collider_tree_color: Option<Color>,
90 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#[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 Constant(Scalar),
129 Scaled(Scalar),
131}
132
133impl Default for ContactGizmoScale {
134 fn default() -> Self {
135 Self::Scaled(0.025)
136 }
137}
138
139impl PhysicsGizmos {
140 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 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 pub fn axes(axis_lengths: Vector) -> Self {
195 Self {
196 axis_lengths: Some(axis_lengths),
197 ..Self::none()
198 }
199 }
200
201 pub fn aabbs(color: Color) -> Self {
204 Self {
205 aabb_color: Some(color),
206 ..Self::none()
207 }
208 }
209
210 pub fn colliders(color: Color) -> Self {
213 Self {
214 collider_color: Some(color),
215 ..Self::none()
216 }
217 }
218
219 pub fn contact_points(color: Color) -> Self {
222 Self {
223 contact_point_color: Some(color),
224 ..Self::none()
225 }
226 }
227
228 pub fn contact_normals(color: Color) -> Self {
231 Self {
232 contact_normal_color: Some(color),
233 ..Self::none()
234 }
235 }
236
237 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 pub fn with_axes(mut self, axis_lengths: Vector) -> Self {
249 self.axis_lengths = Some(axis_lengths);
250 self
251 }
252
253 pub fn with_aabb_color(mut self, color: Color) -> Self {
255 self.aabb_color = Some(color);
256 self
257 }
258
259 pub fn with_collider_color(mut self, color: Color) -> Self {
261 self.collider_color = Some(color);
262 self
263 }
264
265 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 pub fn with_contact_point_color(mut self, color: Color) -> Self {
273 self.contact_point_color = Some(color);
274 self
275 }
276
277 pub fn with_contact_normal_color(mut self, color: Color) -> Self {
279 self.contact_normal_color = Some(color);
280 self
281 }
282
283 pub fn with_contact_normal_scale(mut self, scale: ContactGizmoScale) -> Self {
285 self.contact_normal_scale = scale;
286 self
287 }
288
289 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 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 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 pub fn with_mesh_visibility(mut self, is_visible: bool) -> Self {
328 self.hide_meshes = !is_visible;
329 self
330 }
331
332 pub fn without_axes(mut self) -> Self {
334 self.axis_lengths = None;
335 self
336 }
337
338 pub fn without_aabbs(mut self) -> Self {
340 self.aabb_color = None;
341 self
342 }
343
344 pub fn without_colliders(mut self) -> Self {
346 self.collider_color = None;
347 self
348 }
349
350 pub fn without_contact_points(mut self) -> Self {
352 self.contact_point_color = None;
353 self
354 }
355
356 pub fn without_contact_normals(mut self) -> Self {
358 self.contact_normal_color = None;
359 self
360 }
361
362 pub fn without_joints(mut self) -> Self {
364 self.joint_anchor_color = None;
365 self.joint_separation_color = None;
366 self
367 }
368
369 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 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#[cfg_attr(feature = "2d", doc = "use avian2d::prelude::*;")]
395#[cfg_attr(feature = "3d", doc = "use avian3d::prelude::*;")]
396#[cfg_attr(feature = "2d", doc = " Collider::circle(0.5),")]
414#[cfg_attr(feature = "3d", doc = " Collider::sphere(0.5),")]
415#[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 pub axis_lengths: Option<Vector>,
427 pub aabb_color: Option<Color>,
429 pub collider_color: Option<Color>,
431 pub sleeping_color_multiplier: Option<[f32; 4]>,
434 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 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 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 pub fn axes(axis_lengths: Vector) -> Self {
482 Self {
483 axis_lengths: Some(axis_lengths),
484 ..Self::none()
485 }
486 }
487
488 pub fn aabb(color: Color) -> Self {
491 Self {
492 aabb_color: Some(color),
493 ..Self::none()
494 }
495 }
496
497 pub fn collider(color: Color) -> Self {
500 Self {
501 collider_color: Some(color),
502 ..Self::none()
503 }
504 }
505
506 pub fn with_axes(mut self, axis_lengths: Vector) -> Self {
508 self.axis_lengths = Some(axis_lengths);
509 self
510 }
511
512 pub fn with_aabb_color(mut self, color: Color) -> Self {
514 self.aabb_color = Some(color);
515 self
516 }
517
518 pub fn with_collider_color(mut self, color: Color) -> Self {
520 self.collider_color = Some(color);
521 self
522 }
523
524 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 pub fn with_mesh_visibility(mut self, is_visible: bool) -> Self {
532 self.hide_mesh = !is_visible;
533 self
534 }
535
536 pub fn without_axes(mut self) -> Self {
538 self.axis_lengths = None;
539 self
540 }
541
542 pub fn without_aabb(mut self) -> Self {
544 self.aabb_color = None;
545 self
546 }
547
548 pub fn without_collider(mut self) -> Self {
550 self.collider_color = None;
551 self
552 }
553}