Merge pull request #474 from dimforge/debug-render-filtering

Add a predicate to the DebugRenderBackend to filter out objects that are being rendered
This commit is contained in:
Sébastien Crozet
2023-07-08 14:27:39 +02:00
committed by GitHub
3 changed files with 92 additions and 58 deletions

View File

@@ -8,6 +8,8 @@
### Modified ### Modified
- Make `Wheel::friction_slip` public to customize the front friction applied to the vehicle controllers wheels. - Make `Wheel::friction_slip` public to customize the front friction applied to the vehicle controllers wheels.
- Add the `DebugRenderBackend::filter_object` predicate that can be implemented to apply custom filtering rules
on the objects being rendered.
## v0.17.2 (26 Feb. 2023) ## v0.17.2 (26 Feb. 2023)
### Fix ### Fix

View File

@@ -1,7 +1,7 @@
use crate::dynamics::{ use crate::dynamics::{
ImpulseJoint, ImpulseJointHandle, Multibody, MultibodyLink, RigidBody, RigidBodyHandle, ImpulseJoint, ImpulseJointHandle, Multibody, MultibodyLink, RigidBody, RigidBodyHandle,
}; };
use crate::geometry::Collider; use crate::geometry::{Aabb, Collider, ContactPair};
use crate::math::{Isometry, Point, Real, Vector}; use crate::math::{Isometry, Point, Real, Vector};
use crate::prelude::{ColliderHandle, MultibodyJointHandle}; use crate::prelude::{ColliderHandle, MultibodyJointHandle};
use na::Scale; use na::Scale;
@@ -13,12 +13,14 @@ pub enum DebugRenderObject<'a> {
RigidBody(RigidBodyHandle, &'a RigidBody), RigidBody(RigidBodyHandle, &'a RigidBody),
/// A collider is being rendered. /// A collider is being rendered.
Collider(ColliderHandle, &'a Collider), Collider(ColliderHandle, &'a Collider),
/// The AABB of a collider is being rendered.
ColliderAabb(ColliderHandle, &'a Collider, &'a Aabb),
/// An impulse-joint is being rendered. /// An impulse-joint is being rendered.
ImpulseJoint(ImpulseJointHandle, &'a ImpulseJoint), ImpulseJoint(ImpulseJointHandle, &'a ImpulseJoint),
/// A multibody joint is being rendered. /// A multibody joint is being rendered.
MultibodyJoint(MultibodyJointHandle, &'a Multibody, &'a MultibodyLink), MultibodyJoint(MultibodyJointHandle, &'a Multibody, &'a MultibodyLink),
/// Another element is being rendered. /// The contacts of a contact-pair are being rendered.
Other, ContactPair(&'a ContactPair, &'a Collider, &'a Collider),
} }
/// Trait implemented by graphics backends responsible for rendering the physics scene. /// Trait implemented by graphics backends responsible for rendering the physics scene.
@@ -28,6 +30,11 @@ pub enum DebugRenderObject<'a> {
/// `DebugRenderStyle`. The backend is free to apply its own style, for example based on /// `DebugRenderStyle`. The backend is free to apply its own style, for example based on
/// the `object` being rendered. /// the `object` being rendered.
pub trait DebugRenderBackend { pub trait DebugRenderBackend {
/// Predicate to filter-out some objects from the debug-rendering.
fn filter_object(&self, _object: DebugRenderObject) -> bool {
true
}
/// Draws a colored line. /// Draws a colored line.
/// ///
/// Note that this method can be called multiple time for the same `object`. /// Note that this method can be called multiple time for the same `object`.

View File

@@ -105,22 +105,26 @@ impl DebugRenderPipeline {
if let (Some(co1), Some(co2)) = if let (Some(co1), Some(co2)) =
(colliders.get(pair.collider1), colliders.get(pair.collider2)) (colliders.get(pair.collider1), colliders.get(pair.collider2))
{ {
for manifold in &pair.manifolds { let object = DebugRenderObject::ContactPair(pair, co1, co2);
for contact in manifold.contacts() {
backend.draw_line( if backend.filter_object(object) {
DebugRenderObject::Other, for manifold in &pair.manifolds {
co1.position() * contact.local_p1, for contact in manifold.contacts() {
co2.position() * contact.local_p2, backend.draw_line(
self.style.contact_depth_color, object,
); co1.position() * contact.local_p1,
backend.draw_line( co2.position() * contact.local_p2,
DebugRenderObject::Other, self.style.contact_depth_color,
co1.position() * contact.local_p1, );
co1.position() backend.draw_line(
* (contact.local_p1 object,
+ manifold.local_n1 * self.style.contact_normal_length), co1.position() * contact.local_p1,
self.style.contact_normal_color, co1.position()
); * (contact.local_p1
+ manifold.local_n1 * self.style.contact_normal_length),
self.style.contact_normal_color,
);
}
} }
} }
} }
@@ -129,14 +133,23 @@ impl DebugRenderPipeline {
if self.mode.contains(DebugRenderMode::SOLVER_CONTACTS) { if self.mode.contains(DebugRenderMode::SOLVER_CONTACTS) {
for pair in narrow_phase.contact_pairs() { for pair in narrow_phase.contact_pairs() {
for manifold in &pair.manifolds { if let (Some(co1), Some(co2)) =
for contact in &manifold.data.solver_contacts { (colliders.get(pair.collider1), colliders.get(pair.collider2))
backend.draw_line( {
DebugRenderObject::Other, let object = DebugRenderObject::ContactPair(pair, co1, co2);
contact.point,
contact.point + manifold.data.normal * self.style.contact_normal_length, if backend.filter_object(object) {
self.style.contact_normal_color, for manifold in &pair.manifolds {
); for contact in &manifold.data.solver_contacts {
backend.draw_line(
object,
contact.point,
contact.point
+ manifold.data.normal * self.style.contact_normal_length,
self.style.contact_normal_color,
);
}
}
} }
} }
} }
@@ -157,6 +170,10 @@ impl DebugRenderPipeline {
mut anchor_color: [f32; 4], mut anchor_color: [f32; 4],
mut separation_color: [f32; 4], mut separation_color: [f32; 4],
object| { object| {
if !backend.filter_object(object) {
return;
}
if let (Some(rb1), Some(rb2)) = (bodies.get(body1), bodies.get(body2)) { if let (Some(rb1), Some(rb2)) = (bodies.get(body1), bodies.get(body2)) {
let coeff = if (rb1.is_fixed() || rb1.is_sleeping()) let coeff = if (rb1.is_fixed() || rb1.is_sleeping())
&& (rb2.is_fixed() || rb2.is_sleeping()) && (rb2.is_fixed() || rb2.is_sleeping())
@@ -230,6 +247,7 @@ impl DebugRenderPipeline {
if self.style.rigid_body_axes_length != 0.0 if self.style.rigid_body_axes_length != 0.0
&& self.mode.contains(DebugRenderMode::RIGID_BODY_AXES) && self.mode.contains(DebugRenderMode::RIGID_BODY_AXES)
&& backend.filter_object(object)
{ {
let basis = rb.rotation().to_rotation_matrix().into_inner(); let basis = rb.rotation().to_rotation_matrix().into_inner();
let coeff = if rb.is_sleeping() { let coeff = if rb.is_sleeping() {
@@ -262,46 +280,53 @@ impl DebugRenderPipeline {
if self.mode.contains(DebugRenderMode::COLLIDER_SHAPES) { if self.mode.contains(DebugRenderMode::COLLIDER_SHAPES) {
for (h, co) in colliders.iter() { for (h, co) in colliders.iter() {
let object = DebugRenderObject::Collider(h, co); let object = DebugRenderObject::Collider(h, co);
let color = if let Some(parent) = co.parent().and_then(|p| bodies.get(p)) {
let coeff = if parent.is_sleeping() { if backend.filter_object(object) {
self.style.sleep_color_multiplier let color = if let Some(parent) = co.parent().and_then(|p| bodies.get(p)) {
let coeff = if parent.is_sleeping() {
self.style.sleep_color_multiplier
} else {
[1.0; 4]
};
let c = match parent.body_type {
RigidBodyType::Fixed => self.style.collider_fixed_color,
RigidBodyType::Dynamic => self.style.collider_dynamic_color,
RigidBodyType::KinematicPositionBased
| RigidBodyType::KinematicVelocityBased => {
self.style.collider_kinematic_color
}
};
[
c[0] * coeff[0],
c[1] * coeff[1],
c[2] * coeff[2],
c[3] * coeff[3],
]
} else { } else {
[1.0; 4] self.style.collider_parentless_color
};
let c = match parent.body_type {
RigidBodyType::Fixed => self.style.collider_fixed_color,
RigidBodyType::Dynamic => self.style.collider_dynamic_color,
RigidBodyType::KinematicPositionBased
| RigidBodyType::KinematicVelocityBased => {
self.style.collider_kinematic_color
}
}; };
[ self.render_shape(object, backend, co.shape(), co.position(), color)
c[0] * coeff[0], }
c[1] * coeff[1],
c[2] * coeff[2],
c[3] * coeff[3],
]
} else {
self.style.collider_parentless_color
};
self.render_shape(object, backend, co.shape(), co.position(), color)
} }
} }
if self.mode.contains(DebugRenderMode::COLLIDER_AABBS) { if self.mode.contains(DebugRenderMode::COLLIDER_AABBS) {
for (_, co) in colliders.iter() { for (h, co) in colliders.iter() {
let aabb = co.compute_aabb(); let aabb = co.compute_aabb();
let cuboid = Cuboid::new(aabb.half_extents()); let cuboid = Cuboid::new(aabb.half_extents());
self.render_shape( let object = DebugRenderObject::ColliderAabb(h, co, &aabb);
DebugRenderObject::Other,
backend, if backend.filter_object(object) {
&cuboid, self.render_shape(
&aabb.center().into(), object,
self.style.collider_aabb_color, backend,
); &cuboid,
&aabb.center().into(),
self.style.collider_aabb_color,
);
}
} }
} }
} }