Take collision groups into account for ray-casting.

This commit is contained in:
Crozet Sébastien
2020-10-27 14:29:58 +01:00
parent 5a5ba9cf59
commit b4d322a6ca
2 changed files with 35 additions and 21 deletions

View File

@@ -1,5 +1,7 @@
use crate::dynamics::RigidBodySet;
use crate::geometry::{Collider, ColliderHandle, ColliderSet, Ray, RayIntersection, WQuadtree};
use crate::geometry::{
Collider, ColliderHandle, ColliderSet, InteractionGroups, Ray, RayIntersection, WQuadtree,
};
/// A pipeline for performing queries on all the colliders of a scene.
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
@@ -59,6 +61,7 @@ impl QueryPipeline {
colliders: &'a ColliderSet,
ray: &Ray,
max_toi: f32,
groups: InteractionGroups,
) -> Option<(ColliderHandle, &'a Collider, RayIntersection)> {
// TODO: avoid allocation?
let mut inter = Vec::new();
@@ -69,14 +72,17 @@ impl QueryPipeline {
for handle in inter {
let collider = &colliders[handle];
if let Some(inter) =
collider
.shape()
.toi_and_normal_with_ray(collider.position(), ray, max_toi, true)
{
if inter.toi < best {
best = inter.toi;
result = Some((handle, collider, inter));
if collider.collision_groups.test(groups) {
if let Some(inter) = collider.shape().toi_and_normal_with_ray(
collider.position(),
ray,
max_toi,
true,
) {
if inter.toi < best {
best = inter.toi;
result = Some((handle, collider, inter));
}
}
}
}
@@ -99,6 +105,7 @@ impl QueryPipeline {
colliders: &'a ColliderSet,
ray: &Ray,
max_toi: f32,
groups: InteractionGroups,
mut callback: impl FnMut(ColliderHandle, &'a Collider, RayIntersection) -> bool,
) {
// TODO: avoid allocation?
@@ -107,13 +114,17 @@ impl QueryPipeline {
for handle in inter {
let collider = &colliders[handle];
if let Some(inter) =
collider
.shape()
.toi_and_normal_with_ray(collider.position(), ray, max_toi, true)
{
if !callback(handle, collider, inter) {
return;
if collider.collision_groups.test(groups) {
if let Some(inter) = collider.shape().toi_and_normal_with_ray(
collider.position(),
ray,
max_toi,
true,
) {
if !callback(handle, collider, inter) {
return;
}
}
}
}

View File

@@ -24,7 +24,8 @@ use rapier::dynamics::{
#[cfg(feature = "dim3")]
use rapier::geometry::Ray;
use rapier::geometry::{
BroadPhase, ColliderHandle, ColliderSet, ContactEvent, NarrowPhase, ProximityEvent,
BroadPhase, ColliderHandle, ColliderSet, ContactEvent, InteractionGroups, NarrowPhase,
ProximityEvent,
};
use rapier::math::Vector;
use rapier::pipeline::{ChannelEventCollector, PhysicsPipeline, QueryPipeline};
@@ -1188,10 +1189,12 @@ impl Testbed {
.camera()
.unproject(&self.cursor_pos, &na::convert(size));
let ray = Ray::new(pos, dir);
let hit = self
.physics
.query_pipeline
.cast_ray(&self.physics.colliders, &ray, f32::MAX);
let hit = self.physics.query_pipeline.cast_ray(
&self.physics.colliders,
&ray,
f32::MAX,
InteractionGroups::all(),
);
if let Some((_, collider, _)) = hit {
if self.physics.bodies[collider.parent()].is_dynamic() {