epa3.rs panic in `closest_points`
bellwether-softworks opened this issue · 4 comments
Didn't want to hijack #246 since my conditions are different, but I am running into my own crash for the epa3.rs *self.heap.peek()
statement. I can reliably encounter it in the wild, but despite my best efforts to reproduce it outside of that environment I've been unable to.
I've modified the affected statement (and added some Debug
annotations where appropriate) to be able to capture the state of the process at the time of failure:
let Some(mut best_face_id) = self.heap.peek().cloned() else {
eprintln!("dim {}, vertices = {:?}, faces = {:?}, silhouette = {:?}, heap = {:?}", simplex.dimension(), self.vertices, self.faces, self.silhouette, self.heap);
panic!("Failed to identify best face ID")
};
...which results in the following output:
dim 3, vertices = [CSOPoint { point: [29.890513266324994, -24.872264105217, 0.4688], orig1: [5.953013266325, -47.813363182955, 0.0], orig2: [-23.937499999999996, -22.941099077738002, -0.4688] }, CSOPoint { point: [-3.552713678800501e-15, 3.552713678800501e-15, 0.0], orig1: [-23.9375, -22.941099077738, -0.4688], orig2: [-23.937499999999996, -22.941099077738002, -0.4688] }, CSOPoint { point: [-47.875000000302, 24.872264105232002, 0.0], orig1: [-23.9375, -22.941099077738, -0.4688], orig2: [23.937500000302002, -47.81336318297, -0.4688] }, CSOPoint { point: [29.890513266303003, -47.875000000023995, 0.4688], orig1: [5.953013266325, -47.813363182955, 0.0], orig2: [-23.937499999978, 0.06163681706899734, -0.4688] }], faces = [Face { pts: [0, 1, 2], adj: [3, 1, 2], normal: [[0.026025342318247643, 0.05009448509481979, 0.9984053405908359]], bcoords: [0.0, 0.0, 0.0], deleted: false }, Face { pts: [1, 3, 2], adj: [3, 2, 0], normal: [[-0.007528594704585582, -0.014491301232543998, -0.999866652334381]], bcoords: [0.0, 0.0, 0.0], deleted: false }, Face { pts: [0, 2, 3], adj: [0, 1, 3], normal: [[-0.0060282696291206455, 5.7632045364500204e-15, 0.9999818298175616]], bcoords: [0.0, 0.0, 0.0], deleted: false }, Face { pts: [0, 3, 1], adj: [2, 1, 0], normal: [[0.0156819773416449, -1.4992435394608913e-14, -0.9998770302325463]], bcoords: [0.0, 0.0, 0.0], deleted: false }], silhouette = [], heap = []
Despite it not actually panicking, I'm also pasting my attempt to reproduce my problems:
[package]
name = "eps3_panic"
version = "0.1.0"
edition = "2021"
[dependencies]
rapier3d-f64 = { version = "0.22.0", features = ["parallel", "serde-serialize", "simd-stable"] }
use rapier3d_f64::dynamics::{RigidBodyBuilder, RigidBodySet};
use rapier3d_f64::geometry::{ActiveCollisionTypes, BroadPhaseMultiSap, ColliderBuilder, ColliderSet, CollisionEvent, ContactPair, NarrowPhase};
use rapier3d_f64::na::{Isometry3, Point3, Quaternion, Translation3, UnitQuaternion};
use rapier3d_f64::pipeline::{ActiveEvents, CollisionPipeline, EventHandler, PhysicsHooks};
fn to_points(data: &[[f64; 3]]) -> Vec<Point3<f64>> {
data.iter().map(|[x, y, z]| Point3::new(*x, *y, *z)).collect()
}
fn given_data() -> Vec<(Vec<Point3<f64>>, Vec<[u32; 3]>)> {
vec![
(to_points(&[[-23.9375, -22.941099077738, 0.0], [23.937500000302, -47.81336318297, 0.0], [5.953013266325, -47.813363182955, 0.0]]), vec![[0, 1, 2], [2, 1, 0]]),
(to_points(&[[5.953013266325, -47.813363182955, 0.0], [-23.9375, -22.941099077738, 0.0], [-23.9375, -22.941099077738, -0.4688], [5.953013266325, -47.813363182955, -0.4688]]), vec![[0, 1, 2], [0, 2, 3], [3, 1, 0], [3, 2, 1]]),
(to_points(&[[-23.9375, -22.941099077738, -0.4688], [23.937500000302, -47.81336318297, -0.4688], [23.937500000302, -47.81336318297, 0.0], [-23.9375, -22.941099077738, 0.0]]), vec![[0, 1, 2], [0, 2, 3], [3, 1, 0], [3, 2, 1]]),
(to_points(&[[23.937500000302, -47.81336318297, -0.4688], [23.937500000302, -47.81336318297, 0.0], [5.953013266325, -47.813363182955, 0.0], [5.953013266325, -47.813363182955, -0.4688]]), vec![[0, 1, 2], [0, 2, 3], [3, 1, 0], [3, 2, 1]]),
(to_points(&[[-23.9375, -22.941099077738, -0.4688], [23.937500000302, -47.81336318297, -0.4688], [5.953013266325, -47.813363182955, -0.4688]]), vec![[0, 1, 2], [2, 1, 0]]),
(to_points(&[[-23.937499999978, 0.061636817069, 0.0], [23.937500000302, -47.81336318297, 0.0], [-23.9375, -22.941099077738, 0.0]]), vec![[0, 1, 2], [2, 1, 0]]),
(to_points(&[[-23.9375, -22.941099077738, 0.0], [-23.937499999978, 0.061636817069, 0.0], [-23.937499999978, 0.061636817069, -0.4688], [-23.9375, -22.941099077738, -0.4688]]), vec![[0, 1, 2], [0, 2, 3], [3, 1, 0], [3, 2, 1]]),
(to_points(&[[-23.937499999978, 0.061636817069, -0.4688], [23.937500000302, -47.81336318297, -0.4688], [23.937500000302, -47.81336318297, 0.0], [-23.937499999978, 0.061636817069, 0.0]]), vec![[0, 1, 2], [0, 2, 3], [3, 1, 0], [3, 2, 1]]),
(to_points(&[[23.937500000302, -47.81336318297, -0.4688], [23.937500000302, -47.81336318297, 0.0], [-23.9375, -22.941099077738, 0.0], [-23.9375, -22.941099077738, -0.4688]]), vec![[0, 1, 2], [0, 2, 3], [3, 1, 0], [3, 2, 1]]),
(to_points(&[[-23.937499999978, 0.061636817069, -0.4688], [23.937500000302, -47.81336318297, -0.4688], [-23.9375, -22.941099077738, -0.4688]]), vec![[0, 1, 2], [2, 1, 0]]),
(to_points(&[[23.937500000302, -47.81336318297, 0.0], [-23.937499999978, 0.061636817069, 0.0], [23.937500000109, 0.061636817029, 0.0]]), vec![[0, 1, 2], [2, 1, 0]]),
(to_points(&[[23.937500000109, 0.061636817029, 0.0], [-23.937499999978, 0.061636817069, 0.0], [-23.937499999978, 0.061636817069, -0.4688], [23.937500000109, 0.061636817029, -0.4688]]), vec![[0, 1, 2], [0, 2, 3], [3, 1, 0], [3, 2, 1]]),
(to_points(&[[23.937500000109, 0.061636817029, -0.4688], [23.937500000302, -47.81336318297, -0.4688], [23.937500000302, -47.81336318297, 0.0], [23.937500000109, 0.061636817029, 0.0]]), vec![[0, 1, 2], [0, 2, 3], [3, 1, 0], [3, 2, 1]]),
(to_points(&[[23.937500000302, -47.81336318297, -0.4688], [23.937500000302, -47.81336318297, 0.0], [-23.937499999978, 0.061636817069, 0.0], [-23.937499999978, 0.061636817069, -0.4688]]), vec![[0, 1, 2], [0, 2, 3], [3, 1, 0], [3, 2, 1]]),
(to_points(&[[23.937500000302, -47.81336318297, -0.4688], [-23.937499999978, 0.061636817069, -0.4688], [23.937500000109, 0.061636817029, -0.4688]]), vec![[0, 1, 2], [2, 1, 0]]),
]
}
fn main() {
let mut rigid_bodies = RigidBodySet::new();
let mut collider_set = ColliderSet::new();
let event_handler = CustomContactEventHandler::new();
let isometry = Isometry3::from_parts(
Translation3::new(181.62011133541, 288.9152079550468, 154.9445640326959),
UnitQuaternion::from_quaternion(Quaternion::new(0.676779498744411, -0.20490470825103754, -0.2049119891163854, -0.6767530179707012))
);
for (index, (vertices, indices)) in given_data().into_iter().enumerate() {
add_collider(
&mut rigid_bodies,
&mut collider_set,
isometry,
vertices,
indices,
index as u128,
);
}
let mut collision_pipeline = CollisionPipeline::new();
let mut broad_phase = BroadPhaseMultiSap::new();
let mut narrow_phase = NarrowPhase::new();
collision_pipeline.step(
0.005,
&mut broad_phase,
&mut narrow_phase,
&mut rigid_bodies,
&mut collider_set,
None,
&(),
&event_handler,
);
}
fn add_collider(
mut rigid_bodies: &mut RigidBodySet,
collider_set: &mut ColliderSet,
isometry: Isometry3<f64>,
vertices: Vec<Point3<f64>>,
indices: Vec<[u32; 3]>,
index: u128,
) {
let collider_builder = ColliderBuilder::trimesh(vertices, indices);
let rigid_body = RigidBodyBuilder::dynamic()
.position(isometry)
.additional_mass(1.)
.build();
let collider = collider_builder
.active_collision_types(ActiveCollisionTypes::all())
.active_events(ActiveEvents::COLLISION_EVENTS)
.user_data(index)
.build();
let rigid_body_handle = rigid_bodies.insert(rigid_body);
collider_set.insert_with_parent(collider, rigid_body_handle, &mut rigid_bodies);
}
pub struct CustomContactEventHandler;
impl CustomContactEventHandler {
pub fn new() -> Self {
Self
}
}
impl EventHandler for CustomContactEventHandler {
fn handle_collision_event(
&self,
_bodies: &RigidBodySet,
_colliders: &ColliderSet,
_event: CollisionEvent,
contact_pair: Option<&ContactPair>,
) {
if let Some(_pair) = contact_pair {
println!("Pair encountered");
}
}
fn handle_contact_force_event(
&self,
_dt: f64,
_bodies: &RigidBodySet,
_colliders: &ColliderSet,
_contact_pair: &ContactPair,
_total_force_magnitude: f64,
) { /* NOP */ }
}
impl PhysicsHooks for CustomContactEventHandler {}
I ran into this issue today. I don't use any sort of rigid bodies or parent-child relationships. I simply add my static model, call step and boom. I've encountered this in both Parry 0.17 and 0.14. I'm now wondering how to reproduce it myself
Here's a repro with just two triangles. I simplified it as much as I could, even removing digits after decimal points.
Interestingly enough, if I center the triangle pair, the panic doesn't occur.
use rapier3d::na::Point3;
use rapier3d::prelude::Triangle;
use rapier3d::
prelude::{
ActiveCollisionTypes, ColliderBuilder, ColliderSet, CollisionPipeline, DefaultBroadPhase, NarrowPhase, QueryPipeline, RigidBodySet, SharedShape,
}
;
#[test]
fn down_to_triangles_v2() {
let mesh1 = Triangle::new(
Point3::new(-13.174434, 1.0, 8.736801),
Point3::new(3.5251038, 1.0, 12.1),
Point3::new(3.2048466, 1.0, 12.218325),
);
let mesh2 = Triangle::new(
Point3::new(-1.63, 0.0, 11.19),
Point3::new(-2.349647, 0.0, 11.037681),
Point3::new(-2.349647, 1.0, 11.037681),
);
let collider1 = ColliderBuilder::new(SharedShape::new(mesh1))
.active_collision_types(ActiveCollisionTypes::FIXED_FIXED)
.build();
let collider2 = ColliderBuilder::new(SharedShape::new(mesh2))
.active_collision_types(ActiveCollisionTypes::FIXED_FIXED)
.build();
let mut collision_pipeline = CollisionPipeline::new();
let mut broad_phase = DefaultBroadPhase::new();
let mut narrow_phase = NarrowPhase::new();
let physics_hooks = ();
let event_handler = ();
let mut query_pipeline = QueryPipeline::new();
let mut rigid_body_set = RigidBodySet::new();
let mut collider_set = ColliderSet::new();
collider_set.insert(collider1);
collider_set.insert(collider2);
collision_pipeline.step(
0.01,
&mut broad_phase,
&mut narrow_phase,
&mut rigid_body_set,
&mut collider_set,
Some(&mut query_pipeline),
&physics_hooks,
&event_handler,
);
}
I further simplified the repro to just the following code:
let mesh1 = Triangle::new(
Point3::new(-13.174434, 1.0, 8.736801),
Point3::new(3.5251038, 1.0, 12.1),
Point3::new(3.2048466, 1.0, 12.218325),
);
let mesh2 = Triangle::new(
Point3::new(-1.63, 0.0, 11.19),
Point3::new(-2.349647, 0.0, 11.037681),
Point3::new(-2.349647, 1.0, 11.037681),
);
query::details::contact_support_map_support_map_with_params(
&Isometry3::identity(),
&mesh1,
&mesh2,
0.00999999977,
&mut VoronoiSimplex::new(),
None,
);