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
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
name = "rapier-examples-2d"
|
||||
version = "0.1.0"
|
||||
authors = ["Sébastien Crozet <sebcrozet@dimforge.com>"]
|
||||
edition = "2021"
|
||||
edition = "2024"
|
||||
default-run = "all_examples2"
|
||||
|
||||
[features]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use rapier2d::{na::UnitComplex, prelude::*};
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::{na::UnitComplex, prelude::*};
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
let mut bodies = RigidBodySet::new();
|
||||
@@ -24,7 +24,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
|
||||
// Callback that will be executed on the main loop to handle proximities.
|
||||
testbed.add_callback(move |mut graphics, physics, _, state| {
|
||||
let rot = state.time * -1.0;
|
||||
let rot = -state.time;
|
||||
for rb_handle in &platform_handles {
|
||||
let rb = physics.bodies.get_mut(*rb_handle).unwrap();
|
||||
rb.set_next_kinematic_rotation(UnitComplex::new(rot));
|
||||
|
||||
@@ -20,6 +20,7 @@ mod debug_total_overlap2;
|
||||
mod debug_vertical_column2;
|
||||
mod drum2;
|
||||
mod heightfield2;
|
||||
mod inv_pyramid2;
|
||||
mod inverse_kinematics2;
|
||||
mod joint_motor_position2;
|
||||
mod joints2;
|
||||
@@ -59,6 +60,7 @@ pub fn main() {
|
||||
("Drum", drum2::init_world),
|
||||
("Heightfield", heightfield2::init_world),
|
||||
("Inverse kinematics", inverse_kinematics2::init_world),
|
||||
("Inv pyramid", inv_pyramid2::init_world),
|
||||
("Joints", joints2::init_world),
|
||||
("Locked rotations", locked_rotations2::init_world),
|
||||
("One-way platforms", one_way_platforms2::init_world),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use rapier2d::prelude::*;
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use crate::utils::character;
|
||||
use crate::utils::character::CharacterControlMode;
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::control::{KinematicCharacterController, PidController};
|
||||
use rapier2d::prelude::*;
|
||||
use rapier_testbed2d::Testbed;
|
||||
use std::f32::consts::PI;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use rapier2d::prelude::*;
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use rand::distributions::{Distribution, Standard};
|
||||
use rand::{rngs::StdRng, SeedableRng};
|
||||
use rapier2d::prelude::*;
|
||||
use rand::{SeedableRng, rngs::StdRng};
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use rapier2d::prelude::*;
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use rapier2d::prelude::*;
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use rapier2d::prelude::*;
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use rapier2d::prelude::*;
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
@@ -39,22 +39,29 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![0.0, 0.0], 50.0);
|
||||
|
||||
testbed.add_callback(move |graphics, physics, _, run| {
|
||||
testbed.add_callback(move |mut graphics, physics, _, run| {
|
||||
let slow_time = run.timestep_id as f32 / 3.0;
|
||||
let intersection = physics.query_pipeline.intersection_with_shape(
|
||||
|
||||
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,
|
||||
&Isometry::translation(slow_time.cos() * 10.0, slow_time.sin() * 10.0),
|
||||
&Ball::new(rad / 2.0),
|
||||
QueryFilter::default(),
|
||||
);
|
||||
|
||||
if let Some(graphics) = graphics {
|
||||
for (handle, _) in physics.bodies.iter() {
|
||||
graphics.set_body_color(handle, [0.5, 0.5, 0.5]);
|
||||
}
|
||||
if let Some(intersection) = intersection {
|
||||
let collider = physics.colliders.get(intersection).unwrap();
|
||||
for intersection in query_pipeline.intersect_shape(
|
||||
&Isometry::translation(slow_time.cos() * 10.0, slow_time.sin() * 10.0),
|
||||
&Ball::new(rad / 2.0),
|
||||
) {
|
||||
if let Some(graphics) = graphics.as_deref_mut() {
|
||||
for (handle, _) in physics.bodies.iter() {
|
||||
graphics.set_body_color(handle, [0.5, 0.5, 0.5]);
|
||||
}
|
||||
|
||||
let collider = physics.colliders.get(intersection.0).unwrap();
|
||||
let body_handle = collider.parent().unwrap();
|
||||
|
||||
graphics.set_body_color(body_handle, [1.0, 0.0, 0.0]);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use rapier2d::prelude::*;
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use rapier2d::prelude::*;
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use rapier2d::prelude::*;
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::na::DVector;
|
||||
use rapier2d::prelude::*;
|
||||
use rapier_testbed2d::Testbed;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
|
||||
47
examples2d/inv_pyramid2.rs
Normal file
47
examples2d/inv_pyramid2.rs
Normal file
@@ -0,0 +1,47 @@
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* World
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
*/
|
||||
let ground_size = 10.0;
|
||||
let ground_thickness = 1.0;
|
||||
|
||||
let rigid_body = RigidBodyBuilder::fixed();
|
||||
let ground_handle = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::cuboid(ground_size, ground_thickness);
|
||||
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
||||
|
||||
/*
|
||||
* Create the cubes
|
||||
*/
|
||||
let num = 6;
|
||||
let mut rad = 0.5;
|
||||
let mut y = rad;
|
||||
|
||||
for _ in 0usize..num {
|
||||
// Build the rigid body.
|
||||
let rigid_body =
|
||||
RigidBodyBuilder::dynamic().translation(vector![0.0, y + ground_thickness]);
|
||||
let handle = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::cuboid(rad, rad);
|
||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||
y += rad + rad * 2.0;
|
||||
rad *= 2.0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![0.0, 2.5], 20.0);
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
use rapier2d::prelude::*;
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use rapier2d::prelude::*;
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use rapier2d::prelude::*;
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use rapier2d::prelude::*;
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::prelude::*;
|
||||
|
||||
// This shows a bug when a cylinder is in contact with a very large
|
||||
// but very thin cuboid. In this case the EPA returns an incorrect
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use rapier2d::prelude::*;
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::prelude::*;
|
||||
|
||||
struct OneWayPlatformHook {
|
||||
platform1: ColliderHandle,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use rapier2d::prelude::*;
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::na::ComplexField;
|
||||
use rapier2d::prelude::*;
|
||||
use rapier_testbed2d::Testbed;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use rapier2d::prelude::*;
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use rapier2d::prelude::*;
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use crate::utils::character;
|
||||
use crate::utils::character::CharacterControlMode;
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::control::{KinematicCharacterController, PidController};
|
||||
use rapier2d::prelude::*;
|
||||
use rapier_testbed2d::Testbed;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use rapier2d::prelude::*;
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use rapier2d::prelude::*;
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use rapier2d::prelude::*;
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use rapier2d::prelude::*;
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use rapier2d::prelude::*;
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use rapier2d::prelude::*;
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use rapier2d::prelude::*;
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use rapier2d::prelude::*;
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use rapier2d::prelude::*;
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use rapier2d::prelude::*;
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use rapier2d::prelude::*;
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use rapier2d::prelude::*;
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use rapier2d::prelude::*;
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
use rapier_testbed2d::ui::egui::Align2;
|
||||
use rapier_testbed2d::{
|
||||
KeyCode, PhysicsState, TestbedGraphics,
|
||||
ui::egui::{ComboBox, Slider, Ui, Window},
|
||||
};
|
||||
use rapier2d::{
|
||||
control::{CharacterLength, KinematicCharacterController, PidController},
|
||||
prelude::*,
|
||||
};
|
||||
use rapier_testbed2d::ui::egui::Align2;
|
||||
use rapier_testbed2d::{
|
||||
ui::egui::{ComboBox, Slider, Ui, Window},
|
||||
KeyCode, PhysicsState, TestbedGraphics,
|
||||
};
|
||||
|
||||
pub type CharacterSpeed = Real;
|
||||
|
||||
@@ -133,18 +133,27 @@ fn update_kinematic_controller(
|
||||
|
||||
let character_body = &phx.bodies[character_handle];
|
||||
let character_collider = &phx.colliders[character_body.colliders()[0]];
|
||||
let character_collider_pose = *character_collider.position();
|
||||
let character_shape = character_collider.shared_shape().clone();
|
||||
let character_mass = character_body.mass();
|
||||
|
||||
let Some(broad_phase) = phx.broad_phase.downcast_ref::<BroadPhaseBvh>() else {
|
||||
return;
|
||||
};
|
||||
let query_pipeline = broad_phase.as_query_pipeline_mut(
|
||||
phx.narrow_phase.query_dispatcher(),
|
||||
&mut phx.bodies,
|
||||
&mut phx.colliders,
|
||||
QueryFilter::new().exclude_rigid_body(character_handle),
|
||||
);
|
||||
|
||||
let mut collisions = vec![];
|
||||
let mvt = controller.move_shape(
|
||||
phx.integration_parameters.dt,
|
||||
&phx.bodies,
|
||||
&phx.colliders,
|
||||
&phx.query_pipeline,
|
||||
character_collider.shape(),
|
||||
character_collider.position(),
|
||||
desired_movement,
|
||||
QueryFilter::new().exclude_rigid_body(character_handle),
|
||||
&query_pipeline.as_ref(),
|
||||
&*character_shape,
|
||||
&character_collider_pose,
|
||||
desired_movement.cast::<Real>(),
|
||||
|c| collisions.push(c),
|
||||
);
|
||||
|
||||
@@ -156,13 +165,10 @@ fn update_kinematic_controller(
|
||||
|
||||
controller.solve_character_collision_impulses(
|
||||
phx.integration_parameters.dt,
|
||||
&mut phx.bodies,
|
||||
&phx.colliders,
|
||||
&phx.query_pipeline,
|
||||
character_collider.shape(),
|
||||
query_pipeline,
|
||||
&*character_shape,
|
||||
character_mass,
|
||||
&*collisions,
|
||||
QueryFilter::new().exclude_rigid_body(character_handle),
|
||||
);
|
||||
|
||||
let character_body = &mut phx.bodies[character_handle];
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use rapier_testbed2d::Testbed;
|
||||
use rapier2d::parry::transformation::voxelization::FillMode;
|
||||
use rapier2d::prelude::*;
|
||||
use rapier_testbed2d::Testbed;
|
||||
|
||||
const VOXEL_SIZE: Real = 0.1; // 0.25;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user