rapier
rapier copied to clipboard
set_shape() with flipped sign on half extents causes panic on next step if half_extents.abs() < position.abs()
Summary:
Calling set_shape() with a SharedShape::cuboid(...) that flips the sign of one of the half
extents (e.g. from 1.0 to -1.0) causes a panic during the next PhysicsPipeline::step(),
but only if the absolute value of the half extent is smaller than the body's absolute position along
that axis.
thread 'main' panicked at /home/johannes/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rapier2d-0.26.1/src/geometry/broad_phase_multi_sap/sap_utils.rs:18:5:
assertion `left != right` failed
left: 0
right: 0
Reproduction steps:
use rapier2d::prelude::*;
fn main() {
let mut rigid_body_set = RigidBodySet::new();
let mut collider_set = ColliderSet::new();
/* Create cuboid. */
let rigid_body = RigidBodyBuilder::kinematic_position_based()
.translation(vector![3.0, 3.0])
.build();
let rb_handle = rigid_body_set.insert(rigid_body);
let collider = ColliderBuilder::cuboid(1.0, 1.0).build();
let coll_handle = collider_set.insert_with_parent(
collider,
rb_handle,
&mut rigid_body_set
);
/* Create other structures necessary for the simulation. */
let gravity = vector![0.0, -9.81];
let integration_parameters = IntegrationParameters::default();
let mut physics_pipeline = PhysicsPipeline::new();
let mut island_manager = IslandManager::new();
let mut broad_phase = DefaultBroadPhase::new();
let mut narrow_phase = NarrowPhase::new();
let mut impulse_joint_set = ImpulseJointSet::new();
let mut multibody_joint_set = MultibodyJointSet::new();
let mut ccd_solver = CCDSolver::new();
let mut query_pipeline = QueryPipeline::new();
let physics_hooks = ();
let event_handler = ();
/* Run the game loop, stepping the simulation once per frame. */
for _ in 0..2 {
physics_pipeline.step(
&gravity,
&integration_parameters,
&mut island_manager,
&mut broad_phase,
&mut narrow_phase,
&mut rigid_body_set,
&mut collider_set,
&mut impulse_joint_set,
&mut multibody_joint_set,
&mut ccd_solver,
Some(&mut query_pipeline),
&physics_hooks,
&event_handler,
);
let collider = collider_set.get_mut(coll_handle).unwrap();
collider.set_shape(SharedShape::cuboid(1.0, -1.0));
}
}
Rapier2d version:
rapier2d = "0.26.1"
Note:
The condition about abs(half_extent) < abs(position) is just an observation; I haven't tested it thoroughly.
This happened to me by accident.
I wasn’t intentionally using negative half extents.
I’m not sure how critical this is.