Files
rapier/benchmarks3d/ray_cast3.rs
Sébastien Crozet 95bd6fcfeb feat: switch to the new Bvh from parry for the broad-phase (#853)
* feat: switch to the new Bvh from parry for the broad-phase

* chore: cargo fmt + update testbed

* chore: remove the multi-grid SAP broad-phase

* fix soft-ccd handling in broad-phase

* Fix contact cleanup in broad-phase after collider removal

* chore: clippy fixes

* fix CCD regression

* chore: update changelog

* fix build with the parallel feature enabled

* chore: remove the now useless broad-phase proxy index from colliders

* fix tests
2025-07-11 22:36:40 +02:00

90 lines
3.2 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
use rapier_testbed3d::{Color, Testbed};
use rapier3d::prelude::*;
pub fn init_world(testbed: &mut Testbed) {
let settings = testbed.example_settings_mut();
// NOTE: this demo is a bit special. It takes as a setting the builder of another demo,
// builds it, and add a ton of rays into it. This gives us an easy way to check
// ray-casting in a wide variety of situations.
let demos: Vec<_> = crate::demo_builders()
.into_iter()
.filter(|(_, builder)| {
!std::ptr::fn_addr_eq(*builder, self::init_world as fn(&mut Testbed))
})
.collect();
let demo_names: Vec<_> = demos.iter().map(|(name, _)| name.to_string()).collect();
let selected = settings.get_or_set_string("Scene", 0, demo_names);
demos[selected].1(testbed);
/*
* Cast rays at each frame.
*/
let ray_ball_radius = 100.0;
let ray_ball = Ball::new(ray_ball_radius);
let (ray_origins, _) = ray_ball.to_trimesh(100, 100);
let rays: Vec<_> = ray_origins
.into_iter()
.map(|pt| Ray::new(pt, -pt.coords.normalize()))
.collect();
let mut centered_rays = rays.clone();
testbed.add_callback(move |graphics, physics, _, _| {
let Some(graphics) = graphics else {
return;
};
// Re-center the ray relative to the current position of all objects.
// This ensures demos with falling objects dont end up with a boring situation
// where all the rays point into the void.
let mut center = Point::origin();
for (_, b) in physics.bodies.iter() {
center += b.translation();
}
center /= physics.bodies.len() as Real;
for (centered, ray) in centered_rays.iter_mut().zip(rays.iter()) {
centered.origin = center + ray.origin.coords;
}
// Cast the rays.
let t1 = std::time::Instant::now();
let max_toi = ray_ball_radius - 1.0;
let Some(broad_phase) = physics.broad_phase.downcast_ref::<BroadPhaseBvh>() else {
return;
};
let query_pipeline = broad_phase.as_query_pipeline(
physics.narrow_phase.query_dispatcher(),
&physics.bodies,
&physics.colliders,
Default::default(),
);
for ray in &centered_rays {
if let Some((_, toi)) = query_pipeline.cast_ray(ray, max_toi, true) {
let a = ray.origin;
let b = ray.point_at(toi);
graphics
.gizmos
.line(a.into(), b.into(), Color::srgba(0.0, 1.0f32, 0.0, 0.1));
} else {
let a = ray.origin;
let b = ray.point_at(max_toi);
graphics
.gizmos
.line(a.into(), b.into(), Color::srgba(1.0f32, 0.0, 0.0, 0.1));
}
}
let main_check_time = t1.elapsed().as_secs_f32();
if let Some(settings) = &mut graphics.settings {
settings.set_label("Ray count:", format!("{}", rays.len()));
settings.set_label(
"Ray-cast time",
format!("{:.2}ms", main_check_time * 1000.0,),
);
}
});
}