diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d3dcf9..52f5a35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,71 @@ ## v0.9.0 +The user-guide has been fully rewritten and is now exhaustive! Check it out on [rapier.rs](https://rapier.rs/) + +### Added +- A prelude has been added in order to simplify the most common imports. For example: `use rapier3d::prelude::*` +- Add `RigidBody::set_translation` and `RigidBody.translation()`. +- Add `RigidBody::set_rotation` and `RigidBody.rotation(). +- Add `RigidBody::set_next_translation` for setting the next translation of a position-based kinematic body. +- Add `RigidBody::set_next_rotation` for setting the next rotation of a position-based kinematic body. +- Add kinematic bodies controlled at the velocity level: use `RigidBodyBuilder::new_kinematic_velocity_based` or + `RigidBodyType::KinematicVelocityBased`. ### Modified +The use of `RigidBodySet, ColliderSet, RigidBody, Collider` is no longer mandatory. Rigid-bodies and colliders have +been split into multiple components that can be stored in a user-defined set. This is useful for integrating Rapier +with other engines (for example this allows use to use Bevy's Query as our rigid-body/collider sets). + +The `RigidBodySet, ColliderSet, RigidBody, Collider` are still the best option for whoever doesn't want to +provide their own component sets. + +#### Rigid-bodies - Renamed `BodyStatus` to `RigidBodyType`. +- `RigidBodyBuilder::translation` now takes a vector instead of individual components. +- `RigidBodyBuilder::linvel` now takes a vector instead of individual components. +- The `RigidBodyBuilder::new_kinematic` has be replaced by the `RigidBodyBuilder::new_kinematic_position_based` and + `RigidBodyBuilder::new_kinematic_velocity_based` constructors. +- The `RigidBodyType::Kinematic` variant has been replaced by two variants: `RigidBodyType::KinematicVelocityBased` and + `RigidBodyType::KinematicPositionBased`. + +#### Colliders +- `Colliderbuilder::translation` now takes a vector instead of individual components. +- The way `PhysicsHooks` are enabled changed. Now, a physics hooks is executed if any of the two + colliders involved in the contact/intersection pair contains the related `PhysicsHooksFlag`. + These flags are configured on each collider with `ColliderBuilder::active_hooks`. As a result, + there is no `PhysicsHooks::active_hooks` method any more. +- All events are now disabled for all colliders by default. Enable events for specific colliders by setting its + `active_events` bit mask to `ActiveEvents::CONTACT_EVENTS` and/or `ActiveEvents::PROXIMITY_EVENTS`. +- Add a simpler way of enabling collision-detection between colliders attached to two non-dynamic rigid-bodies: see + `ColliderBuilder::active_collision_types`. +- The `InteractionGroups` is now a structures with two `u32` integers: one integers for the groups + membership and one for the group filter mask. (Before, both were only 16-bits wide, and were + packed into a single `u32`). +- Before, sensor colliders had a default density set to 0.0 whereas non-sensor colliders had a + default density of 1.0. This has been unified by setting the default density to 1.0 for both + sensor and non-sensor colliders. +- Colliders are no longer required to be attached to a rigid-body. Therefore, `ColliderSet::insert` + only takes the collider as argument now. In order to attach the collider to a rigid-body, + (i.e., the old behavior of `ColliderSet::insert`), use `ColliderSet::insert_with_parent`. +- Fixed a bug where collision groups were ignored by CCD. + +#### Joints +- The fields `FixedJoint::local_anchor1` and `FixedJoint::local_anchor2` have been renamed to + `FixedJoint::local_frame1` and `FixedJoint::local_frame2`. + +#### Pipelines and others +- The field `ContactPair::pair` (which contained two collider handles) has been replaced by two + fields: `ContactPair::collider1` and `ContactPair::collider2`. +- The list of active dynamic bodies is no retrieved with `IslandManager::active_dynamic_bodies` + instead of `RigidBodySet::iter_active_dynamic`. +- The list of active kinematic bodies is no retrieved with `IslandManager::active_kinematic_bodies` + instead of `RigidBodySet::iter_active_kinematic`. +- `NarrowPhase::contacts_with` now returns an `impl Iterator` instead of + an `Option>`. The colliders + handles can be read from the contact-pair itself. +- `NarrowPhase::intersections_with` now returns an iterator directly instead of an `Option`. +- Rename `PhysicsHooksFlags` to `ActiveHooks`. +- Add the contact pair as an argument to `EventHandler::handle_contact_event` + ## v0.8.0 ### Modified diff --git a/Cargo.toml b/Cargo.toml index 99e7b5b..7021ade 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,9 +18,6 @@ resolver = "2" #parry3d-f64 = { path = "../parry/build/parry3d-f64" } #nalgebra = { path = "../nalgebra" } -#bevy-orbit-controls = { path = "../bevy-orbit-controls" } -bevy-orbit-controls = { git = "https://github.com/sebcrozet/bevy-orbit-controls" } - #kiss3d = { git = "https://github.com/sebcrozet/kiss3d" } #nalgebra = { git = "https://github.com/dimforge/nalgebra", branch = "dev" } #parry2d = { git = "https://github.com/dimforge/parry", branch = "special_cases" } diff --git a/benchmarks2d/Cargo.toml b/benchmarks2d/Cargo.toml index fdb1690..92e2959 100644 --- a/benchmarks2d/Cargo.toml +++ b/benchmarks2d/Cargo.toml @@ -14,7 +14,7 @@ enhanced-determinism = [ "rapier2d/enhanced-determinism" ] [dependencies] rand = "0.8" Inflector = "0.11" -nalgebra = "0.26" +nalgebra = "0.27" [dependencies.rapier_testbed2d] path = "../build/rapier_testbed2d" diff --git a/benchmarks2d/balls2.rs b/benchmarks2d/balls2.rs index 8fa9775..ec55f24 100644 --- a/benchmarks2d/balls2.rs +++ b/benchmarks2d/balls2.rs @@ -1,6 +1,4 @@ -use na::Point2; -use rapier2d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet, RigidBodyType}; -use rapier2d::geometry::{ColliderBuilder, ColliderSet}; +use rapier2d::prelude::*; use rapier_testbed2d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -22,7 +20,7 @@ pub fn init_world(testbed: &mut Testbed) { let co = ColliderDesc::new(ground_shape) .translation(-Vector2::y()) .build(BodyPartHandle(ground_handle, 0)); - colliders.insert(co); + colliders.insert_with_parent(co); */ /* @@ -48,10 +46,12 @@ pub fn init_world(testbed: &mut Testbed) { }; // Build the rigid body. - let rigid_body = RigidBodyBuilder::new(status).translation(x, y).build(); + let rigid_body = RigidBodyBuilder::new(status) + .translation(vector![x, y]) + .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::ball(rad).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } } @@ -59,5 +59,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point2::new(0.0, 2.5), 5.0); + testbed.look_at(point![0.0, 2.5], 5.0); } diff --git a/benchmarks2d/boxes2.rs b/benchmarks2d/boxes2.rs index e524386..2e4c5e4 100644 --- a/benchmarks2d/boxes2.rs +++ b/benchmarks2d/boxes2.rs @@ -1,6 +1,4 @@ -use na::Point2; -use rapier2d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier2d::geometry::{ColliderBuilder, ColliderSet}; +use rapier2d::prelude::*; use rapier_testbed2d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -19,23 +17,23 @@ pub fn init_world(testbed: &mut Testbed) { let rigid_body = RigidBodyBuilder::new_static().build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, 1.2).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); let rigid_body = RigidBodyBuilder::new_static() .rotation(std::f32::consts::FRAC_PI_2) - .translation(ground_size, ground_size * 2.0) + .translation(vector![ground_size, ground_size * 2.0]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size * 2.0, 1.2).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); let rigid_body = RigidBodyBuilder::new_static() .rotation(std::f32::consts::FRAC_PI_2) - .translation(-ground_size, ground_size * 2.0) + .translation(vector![-ground_size, ground_size * 2.0]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size * 2.0, 1.2).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * Create the cubes @@ -53,10 +51,12 @@ pub fn init_world(testbed: &mut Testbed) { let y = j as f32 * shift + centery + 2.0; // Build the rigid body. - let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y).build(); + let rigid_body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y]) + .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(rad, rad).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } } @@ -64,5 +64,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point2::new(0.0, 50.0), 10.0); + testbed.look_at(point![0.0, 50.0], 10.0); } diff --git a/benchmarks2d/capsules2.rs b/benchmarks2d/capsules2.rs index 89ddfde..e75afe4 100644 --- a/benchmarks2d/capsules2.rs +++ b/benchmarks2d/capsules2.rs @@ -1,6 +1,4 @@ -use na::Point2; -use rapier2d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier2d::geometry::{ColliderBuilder, ColliderSet}; +use rapier2d::prelude::*; use rapier_testbed2d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -19,23 +17,23 @@ pub fn init_world(testbed: &mut Testbed) { let rigid_body = RigidBodyBuilder::new_static().build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, 1.2).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); let rigid_body = RigidBodyBuilder::new_static() .rotation(std::f32::consts::FRAC_PI_2) - .translation(ground_size, ground_size * 4.0) + .translation(vector![ground_size, ground_size * 4.0]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size * 4.0, 1.2).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); let rigid_body = RigidBodyBuilder::new_static() .rotation(std::f32::consts::FRAC_PI_2) - .translation(-ground_size, ground_size * 4.0) + .translation(vector![-ground_size, ground_size * 4.0]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size * 4.0, 1.2).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * Create the cubes @@ -55,10 +53,12 @@ pub fn init_world(testbed: &mut Testbed) { let y = j as f32 * shifty + centery + 3.0; // Build the rigid body. - let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y).build(); + let rigid_body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y]) + .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::capsule_y(rad * 1.5, rad).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } } @@ -66,5 +66,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point2::new(0.0, 50.0), 10.0); + testbed.look_at(point![0.0, 50.0], 10.0); } diff --git a/benchmarks2d/convex_polygons2.rs b/benchmarks2d/convex_polygons2.rs index 99f5a14..6c9792e 100644 --- a/benchmarks2d/convex_polygons2.rs +++ b/benchmarks2d/convex_polygons2.rs @@ -1,8 +1,6 @@ -use na::Point2; use rand::distributions::{Distribution, Standard}; use rand::{rngs::StdRng, SeedableRng}; -use rapier2d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier2d::geometry::{ColliderBuilder, ColliderSet}; +use rapier2d::prelude::*; use rapier_testbed2d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -21,23 +19,23 @@ pub fn init_world(testbed: &mut Testbed) { let rigid_body = RigidBodyBuilder::new_static().build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, 1.2).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); let rigid_body = RigidBodyBuilder::new_static() .rotation(std::f32::consts::FRAC_PI_2) - .translation(ground_size, ground_size * 2.0) + .translation(vector![ground_size, ground_size * 2.0]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size * 2.0, 1.2).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); let rigid_body = RigidBodyBuilder::new_static() .rotation(std::f32::consts::FRAC_PI_2) - .translation(-ground_size, ground_size * 2.0) + .translation(vector![-ground_size, ground_size * 2.0]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size * 2.0, 1.2).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * Create the convex polygons @@ -58,18 +56,20 @@ pub fn init_world(testbed: &mut Testbed) { let x = i as f32 * shift - centerx; let y = j as f32 * shift * 2.0 + centery + 2.0; - let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y).build(); + let rigid_body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y]) + .build(); let handle = bodies.insert(rigid_body); let mut points = Vec::new(); for _ in 0..10 { - let pt: Point2 = distribution.sample(&mut rng); + let pt: Point = distribution.sample(&mut rng); points.push(pt * scale); } let collider = ColliderBuilder::convex_hull(&points).unwrap().build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } } @@ -77,5 +77,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point2::new(0.0, 50.0), 10.0); + testbed.look_at(point![0.0, 50.0], 10.0); } diff --git a/benchmarks2d/heightfield2.rs b/benchmarks2d/heightfield2.rs index 1a30849..a07eb6e 100644 --- a/benchmarks2d/heightfield2.rs +++ b/benchmarks2d/heightfield2.rs @@ -1,6 +1,5 @@ -use na::{DVector, Point2, Vector2}; -use rapier2d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier2d::geometry::{ColliderBuilder, ColliderSet}; +use na::DVector; +use rapier2d::prelude::*; use rapier_testbed2d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -14,7 +13,7 @@ pub fn init_world(testbed: &mut Testbed) { /* * Ground */ - let ground_size = Vector2::new(50.0, 1.0); + let ground_size = Vector::new(50.0, 1.0); let nsubdivs = 2000; let heights = DVector::from_fn(nsubdivs + 1, |i, _| { @@ -28,7 +27,7 @@ pub fn init_world(testbed: &mut Testbed) { let rigid_body = RigidBodyBuilder::new_static().build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::heightfield(heights, ground_size).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * Create the cubes @@ -46,15 +45,17 @@ pub fn init_world(testbed: &mut Testbed) { let y = j as f32 * shift + centery + 3.0; // Build the rigid body. - let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y).build(); + let rigid_body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y]) + .build(); let handle = bodies.insert(rigid_body); if j % 2 == 0 { let collider = ColliderBuilder::cuboid(rad, rad).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } else { let collider = ColliderBuilder::ball(rad).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } } } @@ -63,5 +64,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point2::new(0.0, 50.0), 10.0); + testbed.look_at(point![0.0, 50.0], 10.0); } diff --git a/benchmarks2d/joint_ball2.rs b/benchmarks2d/joint_ball2.rs index 1ad2d39..aadf91e 100644 --- a/benchmarks2d/joint_ball2.rs +++ b/benchmarks2d/joint_ball2.rs @@ -1,6 +1,4 @@ -use na::Point2; -use rapier2d::dynamics::{BallJoint, JointSet, RigidBodyBuilder, RigidBodySet, RigidBodyType}; -use rapier2d::geometry::{ColliderBuilder, ColliderSet}; +use rapier2d::prelude::*; use rapier_testbed2d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -34,16 +32,16 @@ pub fn init_world(testbed: &mut Testbed) { }; let rigid_body = RigidBodyBuilder::new(status) - .translation(fk * shift, -fi * shift) + .translation(vector![fk * shift, -fi * shift]) .build(); let child_handle = bodies.insert(rigid_body); let collider = ColliderBuilder::ball(rad).build(); - colliders.insert(collider, child_handle, &mut bodies); + colliders.insert_with_parent(collider, child_handle, &mut bodies); // Vertical joint. if i > 0 { let parent_handle = *body_handles.last().unwrap(); - let joint = BallJoint::new(Point2::origin(), Point2::new(0.0, shift)); + let joint = BallJoint::new(Point::origin(), point![0.0, shift]); joints.insert(&mut bodies, parent_handle, child_handle, joint); } @@ -51,7 +49,7 @@ pub fn init_world(testbed: &mut Testbed) { if k > 0 { let parent_index = body_handles.len() - numi; let parent_handle = body_handles[parent_index]; - let joint = BallJoint::new(Point2::origin(), Point2::new(-shift, 0.0)); + let joint = BallJoint::new(Point::origin(), point![-shift, 0.0]); joints.insert(&mut bodies, parent_handle, child_handle, joint); } @@ -63,5 +61,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point2::new(numk as f32 * rad, numi as f32 * -rad), 5.0); + testbed.look_at(point![numk as f32 * rad, numi as f32 * -rad], 5.0); } diff --git a/benchmarks2d/joint_fixed2.rs b/benchmarks2d/joint_fixed2.rs index e42ad99..baaa250 100644 --- a/benchmarks2d/joint_fixed2.rs +++ b/benchmarks2d/joint_fixed2.rs @@ -1,6 +1,4 @@ -use na::{Isometry2, Point2}; -use rapier2d::dynamics::{FixedJoint, JointSet, RigidBodyBuilder, RigidBodySet, RigidBodyType}; -use rapier2d::geometry::{ColliderBuilder, ColliderSet}; +use rapier2d::prelude::*; use rapier_testbed2d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -39,18 +37,18 @@ pub fn init_world(testbed: &mut Testbed) { }; let rigid_body = RigidBodyBuilder::new(status) - .translation(x + fk * shift, y - fi * shift) + .translation(vector![x + fk * shift, y - fi * shift]) .build(); let child_handle = bodies.insert(rigid_body); let collider = ColliderBuilder::ball(rad).build(); - colliders.insert(collider, child_handle, &mut bodies); + colliders.insert_with_parent(collider, child_handle, &mut bodies); // Vertical joint. if i > 0 { let parent_handle = *body_handles.last().unwrap(); let joint = FixedJoint::new( - Isometry2::identity(), - Isometry2::translation(0.0, shift), + Isometry::identity(), + Isometry::translation(0.0, shift), ); joints.insert(&mut bodies, parent_handle, child_handle, joint); } @@ -60,8 +58,8 @@ pub fn init_world(testbed: &mut Testbed) { let parent_index = body_handles.len() - num; let parent_handle = body_handles[parent_index]; let joint = FixedJoint::new( - Isometry2::identity(), - Isometry2::translation(-shift, 0.0), + Isometry::identity(), + Isometry::translation(-shift, 0.0), ); joints.insert(&mut bodies, parent_handle, child_handle, joint); } @@ -76,5 +74,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point2::new(50.0, 50.0), 5.0); + testbed.look_at(point![50.0, 50.0], 5.0); } diff --git a/benchmarks2d/joint_prismatic2.rs b/benchmarks2d/joint_prismatic2.rs index e393542..0cbf859 100644 --- a/benchmarks2d/joint_prismatic2.rs +++ b/benchmarks2d/joint_prismatic2.rs @@ -1,6 +1,4 @@ -use na::{Point2, Unit, Vector2}; -use rapier2d::dynamics::{JointSet, PrismaticJoint, RigidBodyBuilder, RigidBodySet}; -use rapier2d::geometry::{ColliderBuilder, ColliderSet}; +use rapier2d::prelude::*; use rapier_testbed2d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -25,27 +23,31 @@ pub fn init_world(testbed: &mut Testbed) { for j in 0..50 { let x = j as f32 * shift * 4.0; - let ground = RigidBodyBuilder::new_static().translation(x, y).build(); + let ground = RigidBodyBuilder::new_static() + .translation(vector![x, y]) + .build(); let mut curr_parent = bodies.insert(ground); let collider = ColliderBuilder::cuboid(rad, rad).build(); - colliders.insert(collider, curr_parent, &mut bodies); + colliders.insert_with_parent(collider, curr_parent, &mut bodies); for i in 0..num { let y = y - (i + 1) as f32 * shift; let density = 1.0; - let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y).build(); + let rigid_body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y]) + .build(); let curr_child = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(rad, rad).density(density).build(); - colliders.insert(collider, curr_child, &mut bodies); + colliders.insert_with_parent(collider, curr_child, &mut bodies); let axis = if i % 2 == 0 { - Unit::new_normalize(Vector2::new(1.0, 1.0)) + UnitVector::new_normalize(vector![1.0, 1.0]) } else { - Unit::new_normalize(Vector2::new(-1.0, 1.0)) + UnitVector::new_normalize(vector![-1.0, 1.0]) }; let mut prism = - PrismaticJoint::new(Point2::origin(), axis, Point2::new(0.0, shift), axis); + PrismaticJoint::new(Point::origin(), axis, point![0.0, shift], axis); prism.limits_enabled = true; prism.limits[0] = -1.5; prism.limits[1] = 1.5; @@ -60,5 +62,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point2::new(80.0, 80.0), 15.0); + testbed.look_at(point![80.0, 80.0], 15.0); } diff --git a/benchmarks2d/pyramid2.rs b/benchmarks2d/pyramid2.rs index c3eb6ad..a557ff4 100644 --- a/benchmarks2d/pyramid2.rs +++ b/benchmarks2d/pyramid2.rs @@ -1,6 +1,4 @@ -use na::Point2; -use rapier2d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier2d::geometry::{ColliderBuilder, ColliderSet}; +use rapier2d::prelude::*; use rapier_testbed2d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -20,7 +18,7 @@ pub fn init_world(testbed: &mut Testbed) { let rigid_body = RigidBodyBuilder::new_static().build(); let ground_handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_thickness).build(); - colliders.insert(collider, ground_handle, &mut bodies); + colliders.insert_with_parent(collider, ground_handle, &mut bodies); /* * Create the cubes @@ -40,10 +38,12 @@ pub fn init_world(testbed: &mut Testbed) { let y = fi * shift + centery; // Build the rigid body. - let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y).build(); + let rigid_body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y]) + .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(rad, rad).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } } @@ -51,5 +51,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point2::new(0.0, 2.5), 5.0); + testbed.look_at(point![0.0, 2.5], 5.0); } diff --git a/benchmarks3d/Cargo.toml b/benchmarks3d/Cargo.toml index a986136..8fca510 100644 --- a/benchmarks3d/Cargo.toml +++ b/benchmarks3d/Cargo.toml @@ -14,7 +14,7 @@ enhanced-determinism = [ "rapier3d/enhanced-determinism" ] [dependencies] rand = "0.8" Inflector = "0.11" -nalgebra = "0.26" +nalgebra = "0.27" [dependencies.rapier_testbed3d] path = "../build/rapier_testbed3d" diff --git a/benchmarks3d/balls3.rs b/benchmarks3d/balls3.rs index 492aeac..3f0bf36 100644 --- a/benchmarks3d/balls3.rs +++ b/benchmarks3d/balls3.rs @@ -1,6 +1,4 @@ -use na::Point3; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet, RigidBodyType}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -37,10 +35,12 @@ pub fn init_world(testbed: &mut Testbed) { let density = 0.477; // Build the rigid body. - let rigid_body = RigidBodyBuilder::new(status).translation(x, y, z).build(); + let rigid_body = RigidBodyBuilder::new(status) + .translation(vector![x, y, z]) + .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::ball(rad).density(density).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } } } @@ -49,5 +49,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(100.0, 100.0, 100.0), Point3::origin()); + testbed.look_at(point![100.0, 100.0, 100.0], Point::origin()); } diff --git a/benchmarks3d/boxes3.rs b/benchmarks3d/boxes3.rs index 86213af..9c7ed81 100644 --- a/benchmarks3d/boxes3.rs +++ b/benchmarks3d/boxes3.rs @@ -1,6 +1,4 @@ -use na::Point3; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -18,11 +16,11 @@ pub fn init_world(testbed: &mut Testbed) { let ground_height = 0.1; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, -ground_height, 0.0) + .translation(vector![0.0, -ground_height, 0.0]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * Create the cubes @@ -45,10 +43,12 @@ pub fn init_world(testbed: &mut Testbed) { let z = k as f32 * shift - centerz + offset; // Build the rigid body. - let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y, z).build(); + let rigid_body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y, z]) + .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(rad, rad, rad).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } } @@ -59,5 +59,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(100.0, 100.0, 100.0), Point3::origin()); + testbed.look_at(point![100.0, 100.0, 100.0], Point::origin()); } diff --git a/benchmarks3d/capsules3.rs b/benchmarks3d/capsules3.rs index edd6d57..8565503 100644 --- a/benchmarks3d/capsules3.rs +++ b/benchmarks3d/capsules3.rs @@ -1,6 +1,4 @@ -use na::Point3; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -18,11 +16,11 @@ pub fn init_world(testbed: &mut Testbed) { let ground_height = 0.1; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, -ground_height, 0.0) + .translation(vector![0.0, -ground_height, 0.0]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * Create the cubes @@ -46,10 +44,12 @@ pub fn init_world(testbed: &mut Testbed) { let z = k as f32 * shift - centerz + offset; // Build the rigid body. - let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y, z).build(); + let rigid_body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y, z]) + .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::capsule_y(rad, rad).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } } @@ -60,5 +60,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(100.0, 100.0, 100.0), Point3::origin()); + testbed.look_at(point![100.0, 100.0, 100.0], Point::origin()); } diff --git a/benchmarks3d/ccd3.rs b/benchmarks3d/ccd3.rs index a496648..987aba6 100644 --- a/benchmarks3d/ccd3.rs +++ b/benchmarks3d/ccd3.rs @@ -1,6 +1,4 @@ -use na::Point3; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -18,11 +16,11 @@ pub fn init_world(testbed: &mut Testbed) { let ground_height = 0.1; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, -ground_height, 0.0) + .translation(vector![0.0, -ground_height, 0.0]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * Create the cubes @@ -49,8 +47,8 @@ pub fn init_world(testbed: &mut Testbed) { // Build the rigid body. let rigid_body = RigidBodyBuilder::new_dynamic() - .translation(x, y, z) - .linvel(0.0, -1000.0, 0.0) + .translation(vector![x, y, z]) + .linvel(vector![0.0, -1000.0, 0.0]) .ccd_enabled(true) .build(); let handle = bodies.insert(rigid_body); @@ -65,7 +63,7 @@ pub fn init_world(testbed: &mut Testbed) { _ => ColliderBuilder::capsule_y(rad, rad), }; - colliders.insert(collider.build(), handle, &mut bodies); + colliders.insert_with_parent(collider.build(), handle, &mut bodies); } } @@ -76,5 +74,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(100.0, 100.0, 100.0), Point3::origin()); + testbed.look_at(point![100.0, 100.0, 100.0], Point::origin()); } diff --git a/benchmarks3d/compound3.rs b/benchmarks3d/compound3.rs index 3f82ca0..a914ce9 100644 --- a/benchmarks3d/compound3.rs +++ b/benchmarks3d/compound3.rs @@ -1,6 +1,4 @@ -use na::Point3; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -18,11 +16,11 @@ pub fn init_world(testbed: &mut Testbed) { let ground_height = 0.1; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, -ground_height, 0.0) + .translation(vector![0.0, -ground_height, 0.0]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * Create the cubes @@ -45,18 +43,20 @@ pub fn init_world(testbed: &mut Testbed) { let z = k as f32 * shift * 2.0 - centerz + offset; // Build the rigid body. - let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y, z).build(); + let rigid_body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y, z]) + .build(); let handle = bodies.insert(rigid_body); let collider1 = ColliderBuilder::cuboid(rad * 10.0, rad, rad).build(); let collider2 = ColliderBuilder::cuboid(rad, rad * 10.0, rad) - .translation(rad * 10.0, rad * 10.0, 0.0) + .translation(vector![rad * 10.0, rad * 10.0, 0.0]) .build(); let collider3 = ColliderBuilder::cuboid(rad, rad * 10.0, rad) - .translation(-rad * 10.0, rad * 10.0, 0.0) + .translation(vector![-rad * 10.0, rad * 10.0, 0.0]) .build(); - colliders.insert(collider1, handle, &mut bodies); - colliders.insert(collider2, handle, &mut bodies); - colliders.insert(collider3, handle, &mut bodies); + colliders.insert_with_parent(collider1, handle, &mut bodies); + colliders.insert_with_parent(collider2, handle, &mut bodies); + colliders.insert_with_parent(collider3, handle, &mut bodies); } } @@ -67,5 +67,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(100.0, 100.0, 100.0), Point3::origin()); + testbed.look_at(point![100.0, 100.0, 100.0], Point::origin()); } diff --git a/benchmarks3d/convex_polyhedron3.rs b/benchmarks3d/convex_polyhedron3.rs index 0e14782..7065cd5 100644 --- a/benchmarks3d/convex_polyhedron3.rs +++ b/benchmarks3d/convex_polyhedron3.rs @@ -1,8 +1,6 @@ -use na::Point3; use rand::distributions::{Distribution, Standard}; use rand::{rngs::StdRng, SeedableRng}; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -20,11 +18,11 @@ pub fn init_world(testbed: &mut Testbed) { let ground_height = 0.1; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, -ground_height, 0.0) + .translation(vector![0.0, -ground_height, 0.0]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * Create the cubes @@ -53,17 +51,19 @@ pub fn init_world(testbed: &mut Testbed) { let mut points = Vec::new(); for _ in 0..10 { - let pt: Point3 = distribution.sample(&mut rng); + let pt: Point = distribution.sample(&mut rng); points.push(pt * scale); } // Build the rigid body. - let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y, z).build(); + let rigid_body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y, z]) + .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::round_convex_hull(&points, border_rad) .unwrap() .build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } } @@ -74,5 +74,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(100.0, 100.0, 100.0), Point3::origin()); + testbed.look_at(point![100.0, 100.0, 100.0], Point::origin()); } diff --git a/benchmarks3d/heightfield3.rs b/benchmarks3d/heightfield3.rs index 062e7c5..3ddc0ec 100644 --- a/benchmarks3d/heightfield3.rs +++ b/benchmarks3d/heightfield3.rs @@ -1,6 +1,5 @@ -use na::{ComplexField, DMatrix, Point3, Vector3}; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use na::ComplexField; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -14,7 +13,7 @@ pub fn init_world(testbed: &mut Testbed) { /* * Ground */ - let ground_size = Vector3::new(200.0, 1.0, 200.0); + let ground_size = vector![200.0, 1.0, 200.0]; let nsubdivs = 20; let heights = DMatrix::from_fn(nsubdivs + 1, nsubdivs + 1, |i, j| { @@ -34,7 +33,7 @@ pub fn init_world(testbed: &mut Testbed) { let rigid_body = RigidBodyBuilder::new_static().build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::heightfield(heights, ground_size).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * Create the cubes @@ -55,15 +54,17 @@ pub fn init_world(testbed: &mut Testbed) { let z = k as f32 * shift - centerz; // Build the rigid body. - let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y, z).build(); + let rigid_body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y, z]) + .build(); let handle = bodies.insert(rigid_body); if j % 2 == 0 { let collider = ColliderBuilder::cuboid(rad, rad, rad).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } else { let collider = ColliderBuilder::ball(rad).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } } } @@ -73,5 +74,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(100.0, 100.0, 100.0), Point3::origin()); + testbed.look_at(point![100.0, 100.0, 100.0], Point::origin()); } diff --git a/benchmarks3d/joint_ball3.rs b/benchmarks3d/joint_ball3.rs index e7b3e3d..5e3eb10 100644 --- a/benchmarks3d/joint_ball3.rs +++ b/benchmarks3d/joint_ball3.rs @@ -1,6 +1,4 @@ -use na::Point3; -use rapier3d::dynamics::{BallJoint, JointSet, RigidBodyBuilder, RigidBodySet, RigidBodyType}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -29,16 +27,16 @@ pub fn init_world(testbed: &mut Testbed) { }; let rigid_body = RigidBodyBuilder::new(status) - .translation(fk * shift, 0.0, fi * shift) + .translation(vector![fk * shift, 0.0, fi * shift]) .build(); let child_handle = bodies.insert(rigid_body); let collider = ColliderBuilder::ball(rad).build(); - colliders.insert(collider, child_handle, &mut bodies); + colliders.insert_with_parent(collider, child_handle, &mut bodies); // Vertical joint. if i > 0 { let parent_handle = *body_handles.last().unwrap(); - let joint = BallJoint::new(Point3::origin(), Point3::new(0.0, 0.0, -shift)); + let joint = BallJoint::new(Point::origin(), point![0.0, 0.0, -shift]); joints.insert(&mut bodies, parent_handle, child_handle, joint); } @@ -46,7 +44,7 @@ pub fn init_world(testbed: &mut Testbed) { if k > 0 { let parent_index = body_handles.len() - num; let parent_handle = body_handles[parent_index]; - let joint = BallJoint::new(Point3::origin(), Point3::new(-shift, 0.0, 0.0)); + let joint = BallJoint::new(Point::origin(), point![-shift, 0.0, 0.0]); joints.insert(&mut bodies, parent_handle, child_handle, joint); } @@ -58,8 +56,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at( - Point3::new(-110.0, -46.0, 170.0), - Point3::new(54.0, -38.0, 29.0), - ); + testbed.look_at(point![-110.0, -46.0, 170.0], point![54.0, -38.0, 29.0]); } diff --git a/benchmarks3d/joint_fixed3.rs b/benchmarks3d/joint_fixed3.rs index 0475258..5647dde 100644 --- a/benchmarks3d/joint_fixed3.rs +++ b/benchmarks3d/joint_fixed3.rs @@ -1,6 +1,4 @@ -use na::{Isometry3, Point3}; -use rapier3d::dynamics::{FixedJoint, JointSet, RigidBodyBuilder, RigidBodySet, RigidBodyType}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -42,18 +40,18 @@ pub fn init_world(testbed: &mut Testbed) { }; let rigid_body = RigidBodyBuilder::new(status) - .translation(x + fk * shift, y, z + fi * shift) + .translation(vector![x + fk * shift, y, z + fi * shift]) .build(); let child_handle = bodies.insert(rigid_body); let collider = ColliderBuilder::ball(rad).build(); - colliders.insert(collider, child_handle, &mut bodies); + colliders.insert_with_parent(collider, child_handle, &mut bodies); // Vertical joint. if i > 0 { let parent_handle = *body_handles.last().unwrap(); let joint = FixedJoint::new( - Isometry3::identity(), - Isometry3::translation(0.0, 0.0, -shift), + Isometry::identity(), + Isometry::translation(0.0, 0.0, -shift), ); joints.insert(&mut bodies, parent_handle, child_handle, joint); } @@ -63,8 +61,8 @@ pub fn init_world(testbed: &mut Testbed) { let parent_index = body_handles.len() - num; let parent_handle = body_handles[parent_index]; let joint = FixedJoint::new( - Isometry3::identity(), - Isometry3::translation(-shift, 0.0, 0.0), + Isometry::identity(), + Isometry::translation(-shift, 0.0, 0.0), ); joints.insert(&mut bodies, parent_handle, child_handle, joint); } @@ -80,8 +78,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at( - Point3::new(-38.0, 14.0, 108.0), - Point3::new(46.0, 12.0, 23.0), - ); + testbed.look_at(point![-38.0, 14.0, 108.0], point![46.0, 12.0, 23.0]); } diff --git a/benchmarks3d/joint_prismatic3.rs b/benchmarks3d/joint_prismatic3.rs index afc18fb..b310b14 100644 --- a/benchmarks3d/joint_prismatic3.rs +++ b/benchmarks3d/joint_prismatic3.rs @@ -1,6 +1,4 @@ -use na::{Point3, Unit, Vector3}; -use rapier3d::dynamics::{JointSet, PrismaticJoint, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -24,33 +22,37 @@ pub fn init_world(testbed: &mut Testbed) { for j in 0..50 { let x = j as f32 * shift * 4.0; - let ground = RigidBodyBuilder::new_static().translation(x, y, z).build(); + let ground = RigidBodyBuilder::new_static() + .translation(vector![x, y, z]) + .build(); let mut curr_parent = bodies.insert(ground); let collider = ColliderBuilder::cuboid(rad, rad, rad).build(); - colliders.insert(collider, curr_parent, &mut bodies); + colliders.insert_with_parent(collider, curr_parent, &mut bodies); for i in 0..num { let z = z + (i + 1) as f32 * shift; let density = 1.0; - let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y, z).build(); + let rigid_body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y, z]) + .build(); let curr_child = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(rad, rad, rad) .density(density) .build(); - colliders.insert(collider, curr_child, &mut bodies); + colliders.insert_with_parent(collider, curr_child, &mut bodies); let axis = if i % 2 == 0 { - Unit::new_normalize(Vector3::new(1.0, 1.0, 0.0)) + UnitVector::new_normalize(vector![1.0, 1.0, 0.0]) } else { - Unit::new_normalize(Vector3::new(-1.0, 1.0, 0.0)) + UnitVector::new_normalize(vector![-1.0, 1.0, 0.0]) }; - let z = Vector3::z(); + let z = Vector::z(); let mut prism = PrismaticJoint::new( - Point3::origin(), + Point::origin(), axis, z, - Point3::new(0.0, 0.0, -shift), + point![0.0, 0.0, -shift], axis, z, ); @@ -69,8 +71,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at( - Point3::new(262.0, 63.0, 124.0), - Point3::new(101.0, 4.0, -3.0), - ); + testbed.look_at(point![262.0, 63.0, 124.0], point![101.0, 4.0, -3.0]); } diff --git a/benchmarks3d/joint_revolute3.rs b/benchmarks3d/joint_revolute3.rs index 0c647a6..7c0f6cb 100644 --- a/benchmarks3d/joint_revolute3.rs +++ b/benchmarks3d/joint_revolute3.rs @@ -1,6 +1,4 @@ -use na::{Isometry3, Point3, Vector3}; -use rapier3d::dynamics::{JointSet, RevoluteJoint, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -22,20 +20,20 @@ pub fn init_world(testbed: &mut Testbed) { let x = j as f32 * shift * 4.0; let ground = RigidBodyBuilder::new_static() - .translation(x, y, 0.0) + .translation(vector![x, y, 0.0]) .build(); let mut curr_parent = bodies.insert(ground); let collider = ColliderBuilder::cuboid(rad, rad, rad).build(); - colliders.insert(collider, curr_parent, &mut bodies); + colliders.insert_with_parent(collider, curr_parent, &mut bodies); for i in 0..num { // Create four bodies. let z = i as f32 * shift * 2.0 + shift; let positions = [ - Isometry3::translation(x, y, z), - Isometry3::translation(x + shift, y, z), - Isometry3::translation(x + shift, y, z + shift), - Isometry3::translation(x, y, z + shift), + Isometry::translation(x, y, z), + Isometry::translation(x + shift, y, z), + Isometry::translation(x + shift, y, z + shift), + Isometry::translation(x, y, z + shift), ]; let mut handles = [curr_parent; 4]; @@ -48,19 +46,19 @@ pub fn init_world(testbed: &mut Testbed) { let collider = ColliderBuilder::cuboid(rad, rad, rad) .density(density) .build(); - colliders.insert(collider, handles[k], &mut bodies); + colliders.insert_with_parent(collider, handles[k], &mut bodies); } // Setup four joints. - let o = Point3::origin(); - let x = Vector3::x_axis(); - let z = Vector3::z_axis(); + let o = Point::origin(); + let x = Vector::x_axis(); + let z = Vector::z_axis(); let revs = [ - RevoluteJoint::new(o, z, Point3::new(0.0, 0.0, -shift), z), - RevoluteJoint::new(o, x, Point3::new(-shift, 0.0, 0.0), x), - RevoluteJoint::new(o, z, Point3::new(0.0, 0.0, -shift), z), - RevoluteJoint::new(o, x, Point3::new(shift, 0.0, 0.0), x), + RevoluteJoint::new(o, z, point![0.0, 0.0, -shift], z), + RevoluteJoint::new(o, x, point![-shift, 0.0, 0.0], x), + RevoluteJoint::new(o, z, point![0.0, 0.0, -shift], z), + RevoluteJoint::new(o, x, point![shift, 0.0, 0.0], x), ]; joints.insert(&mut bodies, curr_parent, handles[0], revs[0]); @@ -77,8 +75,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at( - Point3::new(478.0, 83.0, 228.0), - Point3::new(134.0, 83.0, -116.0), - ); + testbed.look_at(point![478.0, 83.0, 228.0], point![134.0, 83.0, -116.0]); } diff --git a/benchmarks3d/keva3.rs b/benchmarks3d/keva3.rs index 9e6807a..38a0432 100644 --- a/benchmarks3d/keva3.rs +++ b/benchmarks3d/keva3.rs @@ -1,14 +1,12 @@ -use na::{Point3, Vector3}; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; pub fn build_block( testbed: &mut Testbed, bodies: &mut RigidBodySet, colliders: &mut ColliderSet, - half_extents: Vector3, - shift: Vector3, + half_extents: Vector, + shift: Vector, mut numx: usize, numy: usize, mut numz: usize, @@ -17,8 +15,8 @@ pub fn build_block( let block_width = 2.0 * half_extents.z * numx as f32; let block_height = 2.0 * half_extents.y * numy as f32; let spacing = (half_extents.z * numx as f32 - half_extents.x) / (numz as f32 - 1.0); - let mut color0 = Point3::new(0.7, 0.5, 0.9); - let mut color1 = Point3::new(0.6, 1.0, 0.6); + let mut color0 = [0.7, 0.5, 0.9]; + let mut color1 = [0.6, 1.0, 0.6]; for i in 0..numy { std::mem::swap(&mut numx, &mut numz); @@ -41,15 +39,15 @@ pub fn build_block( // Build the rigid body. let rigid_body = RigidBodyBuilder::new_dynamic() - .translation( + .translation(vector![ x + dim.x + shift.x, y + dim.y + shift.y, - z + dim.z + shift.z, - ) + z + dim.z + shift.z + ]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(dim.x, dim.y, dim.z).build(); - colliders.insert(collider, handle, bodies); + colliders.insert_with_parent(collider, handle, bodies); testbed.set_initial_body_color(handle, color0); std::mem::swap(&mut color0, &mut color1); @@ -64,15 +62,15 @@ pub fn build_block( for j in 0..(block_width / (dim.z as f32 * 2.0)) as usize { // Build the rigid body. let rigid_body = RigidBodyBuilder::new_dynamic() - .translation( + .translation(vector![ i as f32 * dim.x * 2.0 + dim.x + shift.x, dim.y + shift.y + block_height, - j as f32 * dim.z * 2.0 + dim.z + shift.z, - ) + j as f32 * dim.z * 2.0 + dim.z + shift.z + ]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(dim.x, dim.y, dim.z).build(); - colliders.insert(collider, handle, bodies); + colliders.insert_with_parent(collider, handle, bodies); testbed.set_initial_body_color(handle, color0); std::mem::swap(&mut color0, &mut color1); } @@ -94,16 +92,16 @@ pub fn init_world(testbed: &mut Testbed) { let ground_height = 0.1; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, -ground_height, 0.0) + .translation(vector![0.0, -ground_height, 0.0]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * Create the cubes */ - let half_extents = Vector3::new(0.02, 0.1, 0.4) / 2.0 * 10.0; + let half_extents = vector![0.02, 0.1, 0.4] / 2.0 * 10.0; let mut block_height = 0.0; // These should only be set to odd values otherwise // the blocks won't align in the nicest way. @@ -120,7 +118,7 @@ pub fn init_world(testbed: &mut Testbed) { &mut bodies, &mut colliders, half_extents, - Vector3::new(-block_width / 2.0, block_height, -block_width / 2.0), + vector![-block_width / 2.0, block_height, -block_width / 2.0], numx, numy, numz, @@ -135,5 +133,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(100.0, 100.0, 100.0), Point3::origin()); + testbed.look_at(point![100.0, 100.0, 100.0], Point::origin()); } diff --git a/benchmarks3d/pyramid3.rs b/benchmarks3d/pyramid3.rs index 3b31eac..655ecb7 100644 --- a/benchmarks3d/pyramid3.rs +++ b/benchmarks3d/pyramid3.rs @@ -1,14 +1,12 @@ -use na::{Point3, Vector3}; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; fn create_pyramid( bodies: &mut RigidBodySet, colliders: &mut ColliderSet, - offset: Vector3, + offset: Vector, stack_height: usize, - half_extents: Vector3, + half_extents: Vector, ) { let shift = half_extents * 2.5; for i in 0usize..stack_height { @@ -24,12 +22,14 @@ fn create_pyramid( - stack_height as f32 * half_extents.z; // Build the rigid body. - let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y, z).build(); + let rigid_body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y, z]) + .build(); let rigid_body_handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(half_extents.x, half_extents.y, half_extents.z).build(); - colliders.insert(collider, rigid_body_handle, bodies); + colliders.insert_with_parent(collider, rigid_body_handle, bodies); } } } @@ -50,22 +50,22 @@ pub fn init_world(testbed: &mut Testbed) { let ground_height = 0.1; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, -ground_height, 0.0) + .translation(vector![0.0, -ground_height, 0.0]) .build(); let ground_handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size).build(); - colliders.insert(collider, ground_handle, &mut bodies); + colliders.insert_with_parent(collider, ground_handle, &mut bodies); /* * Create the cubes */ let cube_size = 1.0; - let hext = Vector3::repeat(cube_size); + let hext = Vector::repeat(cube_size); let bottomy = cube_size; create_pyramid( &mut bodies, &mut colliders, - Vector3::new(0.0, bottomy, 0.0), + vector![0.0, bottomy, 0.0], 24, hext, ); @@ -74,5 +74,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(100.0, 100.0, 100.0), Point3::origin()); + testbed.look_at(point![100.0, 100.0, 100.0], Point::origin()); } diff --git a/benchmarks3d/stacks3.rs b/benchmarks3d/stacks3.rs index 31dff0a..39386ea 100644 --- a/benchmarks3d/stacks3.rs +++ b/benchmarks3d/stacks3.rs @@ -1,15 +1,13 @@ -use na::{Point3, Translation3, UnitQuaternion, Vector3}; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; fn create_tower_circle( bodies: &mut RigidBodySet, colliders: &mut ColliderSet, - offset: Vector3, + offset: Vector, stack_height: usize, nsubdivs: usize, - half_extents: Vector3, + half_extents: Vector, ) { let ang_step = std::f32::consts::PI * 2.0 / nsubdivs as f32; let radius = 1.3 * nsubdivs as f32 * half_extents.x / std::f32::consts::PI; @@ -20,16 +18,16 @@ fn create_tower_circle( let fj = j as f32; let fi = i as f32; let y = fi * shift.y; - let pos = Translation3::from(offset) - * UnitQuaternion::new(Vector3::y() * (fi / 2.0 + fj) * ang_step) - * Translation3::new(0.0, y, radius); + let pos = Translation::from(offset) + * Rotation::new(Vector::y() * (fi / 2.0 + fj) * ang_step) + * Translation::new(0.0, y, radius); // Build the rigid body. let rigid_body = RigidBodyBuilder::new_dynamic().position(pos).build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(half_extents.x, half_extents.y, half_extents.z).build(); - colliders.insert(collider, handle, bodies); + colliders.insert_with_parent(collider, handle, bodies); } } } @@ -37,9 +35,9 @@ fn create_tower_circle( fn create_wall( bodies: &mut RigidBodySet, colliders: &mut ColliderSet, - offset: Vector3, + offset: Vector, stack_height: usize, - half_extents: Vector3, + half_extents: Vector, ) { let shift = half_extents * 2.0; for i in 0usize..stack_height { @@ -52,11 +50,13 @@ fn create_wall( - stack_height as f32 * half_extents.z; // Build the rigid body. - let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y, z).build(); + let rigid_body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y, z]) + .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(half_extents.x, half_extents.y, half_extents.z).build(); - colliders.insert(collider, handle, bodies); + colliders.insert_with_parent(collider, handle, bodies); } } } @@ -64,9 +64,9 @@ fn create_wall( fn create_pyramid( bodies: &mut RigidBodySet, colliders: &mut ColliderSet, - offset: Vector3, + offset: Vector, stack_height: usize, - half_extents: Vector3, + half_extents: Vector, ) { let shift = half_extents * 2.0; @@ -83,11 +83,13 @@ fn create_pyramid( - stack_height as f32 * half_extents.z; // Build the rigid body. - let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y, z).build(); + let rigid_body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y, z]) + .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(half_extents.x, half_extents.y, half_extents.z).build(); - colliders.insert(collider, handle, bodies); + colliders.insert_with_parent(collider, handle, bodies); } } } @@ -108,71 +110,71 @@ pub fn init_world(testbed: &mut Testbed) { let ground_height = 0.1; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, -ground_height, 0.0) + .translation(vector![0.0, -ground_height, 0.0]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * Create the cubes */ let cube_size = 1.0; - let hext = Vector3::repeat(cube_size); + let hext = Vector::repeat(cube_size); let bottomy = cube_size * 50.0; create_pyramid( &mut bodies, &mut colliders, - Vector3::new(-110.0, bottomy, 0.0), + vector![-110.0, bottomy, 0.0], 12, hext, ); create_pyramid( &mut bodies, &mut colliders, - Vector3::new(-80.0, bottomy, 0.0), + vector![-80.0, bottomy, 0.0], 12, hext, ); create_pyramid( &mut bodies, &mut colliders, - Vector3::new(-50.0, bottomy, 0.0), + vector![-50.0, bottomy, 0.0], 12, hext, ); create_pyramid( &mut bodies, &mut colliders, - Vector3::new(-20.0, bottomy, 0.0), + vector![-20.0, bottomy, 0.0], 12, hext, ); create_wall( &mut bodies, &mut colliders, - Vector3::new(-2.0, bottomy, 0.0), + vector![-2.0, bottomy, 0.0], 12, hext, ); create_wall( &mut bodies, &mut colliders, - Vector3::new(4.0, bottomy, 0.0), + vector![4.0, bottomy, 0.0], 12, hext, ); create_wall( &mut bodies, &mut colliders, - Vector3::new(10.0, bottomy, 0.0), + vector![10.0, bottomy, 0.0], 12, hext, ); create_tower_circle( &mut bodies, &mut colliders, - Vector3::new(25.0, bottomy, 0.0), + vector![25.0, bottomy, 0.0], 8, 24, hext, @@ -182,5 +184,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(100.0, 100.0, 100.0), Point3::origin()); + testbed.look_at(point![100.0, 100.0, 100.0], Point::origin()); } diff --git a/benchmarks3d/trimesh3.rs b/benchmarks3d/trimesh3.rs index 0501d6f..fe8f377 100644 --- a/benchmarks3d/trimesh3.rs +++ b/benchmarks3d/trimesh3.rs @@ -1,6 +1,5 @@ -use na::{ComplexField, DMatrix, Point3, Vector3}; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet, HeightField}; +use na::ComplexField; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -14,7 +13,7 @@ pub fn init_world(testbed: &mut Testbed) { /* * Ground */ - let ground_size = Vector3::new(200.0, 1.0, 200.0); + let ground_size = vector![200.0, 1.0, 200.0]; let nsubdivs = 20; let heights = DMatrix::from_fn(nsubdivs + 1, nsubdivs + 1, |i, j| { @@ -39,7 +38,7 @@ pub fn init_world(testbed: &mut Testbed) { let rigid_body = RigidBodyBuilder::new_static().build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::trimesh(vertices, indices).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * Create the cubes @@ -60,15 +59,17 @@ pub fn init_world(testbed: &mut Testbed) { let z = k as f32 * shift - centerz; // Build the rigid body. - let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y, z).build(); + let rigid_body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y, z]) + .build(); let handle = bodies.insert(rigid_body); if j % 2 == 0 { let collider = ColliderBuilder::cuboid(rad, rad, rad).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } else { let collider = ColliderBuilder::ball(rad).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } } } @@ -78,5 +79,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(100.0, 100.0, 100.0), Point3::origin()); + testbed.look_at(point![100.0, 100.0, 100.0], Point::origin()); } diff --git a/build/rapier2d-f64/Cargo.toml b/build/rapier2d-f64/Cargo.toml index d244d9b..cfa121e 100644 --- a/build/rapier2d-f64/Cargo.toml +++ b/build/rapier2d-f64/Cargo.toml @@ -44,13 +44,13 @@ required-features = [ "dim2", "f64" ] vec_map = { version = "0.8", optional = true } instant = { version = "0.1", features = [ "now" ]} num-traits = "0.2" -nalgebra = "0.26" -parry2d-f64 = "0.4" -simba = "0.4" -approx = "0.4" +nalgebra = "0.27" +parry2d-f64 = "0.5" +simba = "0.5" +approx = "0.5" rayon = { version = "1", optional = true } crossbeam = "0.8" -arrayvec = "0.6" +arrayvec = "0.7" bit-vec = "0.6" rustc-hash = "1" serde = { version = "1", features = [ "derive" ], optional = true } diff --git a/build/rapier2d/Cargo.toml b/build/rapier2d/Cargo.toml index a149bd9..79135d4 100644 --- a/build/rapier2d/Cargo.toml +++ b/build/rapier2d/Cargo.toml @@ -44,13 +44,13 @@ required-features = [ "dim2", "f32" ] vec_map = { version = "0.8", optional = true } instant = { version = "0.1", features = [ "now" ]} num-traits = "0.2" -nalgebra = "0.26" -parry2d = "0.4" -simba = "0.4" -approx = "0.4" +nalgebra = "0.27" +parry2d = "0.5" +simba = "0.5" +approx = "0.5" rayon = { version = "1", optional = true } crossbeam = "0.8" -arrayvec = "0.6" +arrayvec = "0.7" bit-vec = "0.6" rustc-hash = "1" serde = { version = "1", features = [ "derive" ], optional = true } diff --git a/build/rapier3d-f64/Cargo.toml b/build/rapier3d-f64/Cargo.toml index 4b6519c..cfbc836 100644 --- a/build/rapier3d-f64/Cargo.toml +++ b/build/rapier3d-f64/Cargo.toml @@ -44,13 +44,13 @@ required-features = [ "dim3", "f64" ] vec_map = { version = "0.8", optional = true } instant = { version = "0.1", features = [ "now" ]} num-traits = "0.2" -nalgebra = "0.26" -parry3d-f64 = "0.4" -simba = "0.4" -approx = "0.4" +nalgebra = "0.27" +parry3d-f64 = "0.5" +simba = "0.5" +approx = "0.5" rayon = { version = "1", optional = true } crossbeam = "0.8" -arrayvec = "0.6" +arrayvec = "0.7" bit-vec = "0.6" rustc-hash = "1" serde = { version = "1", features = [ "derive" ], optional = true } diff --git a/build/rapier3d/Cargo.toml b/build/rapier3d/Cargo.toml index 8a3877b..1ddb201 100644 --- a/build/rapier3d/Cargo.toml +++ b/build/rapier3d/Cargo.toml @@ -44,13 +44,13 @@ required-features = [ "dim3", "f32" ] vec_map = { version = "0.8", optional = true } instant = { version = "0.1", features = [ "now" ]} num-traits = "0.2" -nalgebra = "0.26" -parry3d = "0.4" -simba = "0.4" -approx = "0.4" +nalgebra = "0.27" +parry3d = "0.5" +simba = "0.5" +approx = "0.5" rayon = { version = "1", optional = true } crossbeam = "0.8" -arrayvec = "0.6" +arrayvec = "0.7" bit-vec = "0.6" rustc-hash = "1" serde = { version = "1", features = [ "derive" ], optional = true } diff --git a/build/rapier_testbed2d/Cargo.toml b/build/rapier_testbed2d/Cargo.toml index b501a1f..67fb07b 100644 --- a/build/rapier_testbed2d/Cargo.toml +++ b/build/rapier_testbed2d/Cargo.toml @@ -26,23 +26,22 @@ other-backends = [ "wrapped2d", "nphysics2d" ] [dependencies] -nalgebra = { version = "0.26", features = [ "rand" ] } +nalgebra = { version = "0.27", features = [ "rand" ] } rand = "0.8" rand_pcg = "0.3" instant = { version = "0.1", features = [ "web-sys", "now" ]} bitflags = "1" num_cpus = { version = "1", optional = true } wrapped2d = { version = "0.4", optional = true } -parry2d = "0.4" -ncollide2d = "0.29" -nphysics2d = { version = "0.21", optional = true } +parry2d = "0.5" +ncollide2d = "0.30" +nphysics2d = { version = "0.22", optional = true } crossbeam = "0.8" bincode = "1" Inflector = "0.11" md5 = "0.7" -bevy_egui = "0.4" -bevy-orbit-controls = "2" +bevy_egui = "0.5" # Dependencies for native only. [target.'cfg(not(target_arch = "wasm32"))'.dependencies] diff --git a/build/rapier_testbed3d/Cargo.toml b/build/rapier_testbed3d/Cargo.toml index 0038fa8..2dfdad7 100644 --- a/build/rapier_testbed3d/Cargo.toml +++ b/build/rapier_testbed3d/Cargo.toml @@ -25,16 +25,16 @@ parallel = [ "rapier3d/parallel", "num_cpus" ] other-backends = [ "physx", "physx-sys", "glam", "nphysics3d" ] [dependencies] -nalgebra = { version = "0.26", features = [ "rand" ] } +nalgebra = { version = "0.27", features = [ "rand" ] } rand = "0.8" rand_pcg = "0.3" instant = { version = "0.1", features = [ "web-sys", "now" ]} bitflags = "1" glam = { version = "0.12", optional = true } num_cpus = { version = "1", optional = true } -parry3d = "0.4" -ncollide3d = "0.29" -nphysics3d = { version = "0.21", optional = true } +parry3d = "0.5" +ncollide3d = "0.30" +nphysics3d = { version = "0.22", optional = true } physx = { version = "0.11", optional = true } physx-sys = { version = "0.4", optional = true } crossbeam = "0.8" @@ -43,8 +43,7 @@ md5 = "0.7" Inflector = "0.11" serde = { version = "1", features = [ "derive" ] } -bevy_egui = "0.4" -bevy-orbit-controls = "2" +bevy_egui = "0.5" # Dependencies for native only. [target.'cfg(not(target_arch = "wasm32"))'.dependencies] diff --git a/examples2d/Cargo.toml b/examples2d/Cargo.toml index b367ff8..6ade796 100644 --- a/examples2d/Cargo.toml +++ b/examples2d/Cargo.toml @@ -15,7 +15,7 @@ enhanced-determinism = [ "rapier2d/enhanced-determinism" ] [dependencies] rand = "0.8" Inflector = "0.11" -nalgebra = "0.26" +nalgebra = "0.27" lyon = "0.17" usvg = "0.13" diff --git a/examples2d/add_remove2.rs b/examples2d/add_remove2.rs index 9f9f65a..056e63e 100644 --- a/examples2d/add_remove2.rs +++ b/examples2d/add_remove2.rs @@ -1,6 +1,4 @@ -use na::Point2; -use rapier2d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier2d::geometry::{ColliderBuilder, ColliderSet}; +use rapier2d::prelude::*; use rapier_testbed2d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -12,13 +10,13 @@ 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, _, _| { let rigid_body = RigidBodyBuilder::new_dynamic() - .translation(0.0, 10.0) + .translation(vector![0.0, 10.0]) .build(); let handle = physics.bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(rad, rad).build(); physics .colliders - .insert(collider, handle, &mut physics.bodies); + .insert_with_parent(collider, handle, &mut physics.bodies); if let Some(graphics) = &mut graphics { graphics.add_body(handle, &physics.bodies, &physics.colliders); @@ -48,5 +46,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point2::new(0.0, 0.0), 20.0); + testbed.look_at(point![0.0, 0.0], 20.0); } diff --git a/examples2d/ccd2.rs b/examples2d/ccd2.rs index 18a6bfe..1f25586 100644 --- a/examples2d/ccd2.rs +++ b/examples2d/ccd2.rs @@ -1,6 +1,4 @@ -use na::{Isometry2, Point2, Point3}; -use rapier2d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier2d::geometry::{ColliderBuilder, ColliderSet, SharedShape}; +use rapier2d::prelude::*; use rapier_testbed2d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -21,23 +19,24 @@ pub fn init_world(testbed: &mut Testbed) { let ground_handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_thickness).build(); - colliders.insert(collider, ground_handle, &mut bodies); + colliders.insert_with_parent(collider, ground_handle, &mut bodies); let collider = ColliderBuilder::cuboid(ground_thickness, ground_size) - .translation(-3.0, 0.0) + .translation(vector![-3.0, 0.0]) .build(); - colliders.insert(collider, ground_handle, &mut bodies); + colliders.insert_with_parent(collider, ground_handle, &mut bodies); let collider = ColliderBuilder::cuboid(ground_thickness, ground_size) - .translation(6.0, 0.0) + .translation(vector![6.0, 0.0]) .build(); - colliders.insert(collider, ground_handle, &mut bodies); + colliders.insert_with_parent(collider, ground_handle, &mut bodies); let collider = ColliderBuilder::cuboid(ground_thickness, ground_size) - .translation(2.5, 0.0) + .translation(vector![2.5, 0.0]) .sensor(true) + .active_events(ActiveEvents::INTERSECTION_EVENTS) .build(); - let sensor_handle = colliders.insert(collider, ground_handle, &mut bodies); + let sensor_handle = colliders.insert_with_parent(collider, ground_handle, &mut bodies); /* * Create the shapes @@ -45,9 +44,9 @@ pub fn init_world(testbed: &mut Testbed) { let radx = 0.4; let rady = 0.05; - let delta1 = Isometry2::translation(0.0, radx - rady); - let delta2 = Isometry2::translation(-radx + rady, 0.0); - let delta3 = Isometry2::translation(radx - rady, 0.0); + let delta1 = Isometry::translation(0.0, radx - rady); + let delta2 = Isometry::translation(-radx + rady, 0.0); + let delta3 = Isometry::translation(radx - rady, 0.0); let mut compound_parts = Vec::new(); let vertical = SharedShape::cuboid(rady, radx); @@ -70,8 +69,8 @@ pub fn init_world(testbed: &mut Testbed) { // Build the rigid body. let rigid_body = RigidBodyBuilder::new_dynamic() - .translation(x, y) - .linvel(100.0, -10.0) + .translation(vector![x, y]) + .linvel(vector![100.0, -10.0]) .ccd_enabled(true) .build(); let handle = bodies.insert(rigid_body); @@ -80,12 +79,12 @@ pub fn init_world(testbed: &mut Testbed) { // let collider = ColliderBuilder::new(part.1.clone()) // .position_wrt_parent(part.0) // .build(); - // colliders.insert(collider, handle, &mut bodies); + // colliders.insert_with_parent(collider, handle, &mut bodies); // } let collider = ColliderBuilder::new(compound_shape.clone()).build(); // let collider = ColliderBuilder::cuboid(radx, rady).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } } @@ -93,13 +92,23 @@ pub fn init_world(testbed: &mut Testbed) { testbed.add_callback(move |mut graphics, physics, events, _| { while let Ok(prox) = events.intersection_events.try_recv() { let color = if prox.intersecting { - Point3::new(1.0, 1.0, 0.0) + [1.0, 1.0, 0.0] } else { - Point3::new(0.5, 0.5, 1.0) + [0.5, 0.5, 1.0] }; - let parent_handle1 = physics.colliders.get(prox.collider1).unwrap().parent(); - let parent_handle2 = physics.colliders.get(prox.collider2).unwrap().parent(); + let parent_handle1 = physics + .colliders + .get(prox.collider1) + .unwrap() + .parent() + .unwrap(); + let parent_handle2 = physics + .colliders + .get(prox.collider2) + .unwrap() + .parent() + .unwrap(); if let Some(graphics) = &mut graphics { if parent_handle1 != ground_handle && prox.collider1 != sensor_handle { graphics.set_body_color(parent_handle1, color); @@ -115,5 +124,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point2::new(0.0, 2.5), 20.0); + testbed.look_at(point![0.0, 2.5], 20.0); } diff --git a/examples2d/collision_groups2.rs b/examples2d/collision_groups2.rs index 08b73fb..3f2a786 100644 --- a/examples2d/collision_groups2.rs +++ b/examples2d/collision_groups2.rs @@ -1,6 +1,4 @@ -use na::{Point2, Point3}; -use rapier2d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier2d::geometry::{ColliderBuilder, ColliderSet, InteractionGroups}; +use rapier2d::prelude::*; use rapier_testbed2d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -18,11 +16,11 @@ pub fn init_world(testbed: &mut Testbed) { let ground_height = 0.1; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, -ground_height) + .translation(vector![0.0, -ground_height]) .build(); let floor_handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_height).build(); - colliders.insert(collider, floor_handle, &mut bodies); + colliders.insert_with_parent(collider, floor_handle, &mut bodies); /* * Setup groups @@ -34,23 +32,24 @@ pub fn init_world(testbed: &mut Testbed) { * A green floor that will collide with the GREEN group only. */ let green_floor = ColliderBuilder::cuboid(1.0, 0.1) - .translation(0.0, 1.0) + .translation(vector![0.0, 1.0]) .collision_groups(GREEN_GROUP) .build(); - let green_collider_handle = colliders.insert(green_floor, floor_handle, &mut bodies); + let green_collider_handle = + colliders.insert_with_parent(green_floor, floor_handle, &mut bodies); - testbed.set_initial_collider_color(green_collider_handle, Point3::new(0.0, 1.0, 0.0)); + testbed.set_initial_collider_color(green_collider_handle, [0.0, 1.0, 0.0]); /* * A blue floor that will collide with the BLUE group only. */ let blue_floor = ColliderBuilder::cuboid(1.0, 0.1) - .translation(0.0, 2.0) + .translation(vector![0.0, 2.0]) .collision_groups(BLUE_GROUP) .build(); - let blue_collider_handle = colliders.insert(blue_floor, floor_handle, &mut bodies); + let blue_collider_handle = colliders.insert_with_parent(blue_floor, floor_handle, &mut bodies); - testbed.set_initial_collider_color(blue_collider_handle, Point3::new(0.0, 0.0, 1.0)); + testbed.set_initial_collider_color(blue_collider_handle, [0.0, 0.0, 1.0]); /* * Create the cubes @@ -69,17 +68,19 @@ pub fn init_world(testbed: &mut Testbed) { // Alternate between the green and blue groups. let (group, color) = if i % 2 == 0 { - (GREEN_GROUP, Point3::new(0.0, 1.0, 0.0)) + (GREEN_GROUP, [0.0, 1.0, 0.0]) } else { - (BLUE_GROUP, Point3::new(0.0, 0.0, 1.0)) + (BLUE_GROUP, [0.0, 0.0, 1.0]) }; - let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y).build(); + let rigid_body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y]) + .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(rad, rad) .collision_groups(group) .build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); testbed.set_initial_body_color(handle, color); } @@ -89,5 +90,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point2::new(0.0, 1.0), 100.0); + testbed.look_at(point![0.0, 1.0], 100.0); } diff --git a/examples2d/convex_polygons2.rs b/examples2d/convex_polygons2.rs index 0e4fb0c..4373fcb 100644 --- a/examples2d/convex_polygons2.rs +++ b/examples2d/convex_polygons2.rs @@ -1,8 +1,6 @@ -use na::Point2; use rand::distributions::{Distribution, Standard}; use rand::{rngs::StdRng, SeedableRng}; -use rapier2d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier2d::geometry::{ColliderBuilder, ColliderSet}; +use rapier2d::prelude::*; use rapier_testbed2d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -21,23 +19,23 @@ pub fn init_world(testbed: &mut Testbed) { let rigid_body = RigidBodyBuilder::new_static().build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, 1.2).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); let rigid_body = RigidBodyBuilder::new_static() .rotation(std::f32::consts::FRAC_PI_2) - .translation(ground_size, ground_size * 2.0) + .translation(vector![ground_size, ground_size * 2.0]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size * 2.0, 1.2).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); let rigid_body = RigidBodyBuilder::new_static() .rotation(std::f32::consts::FRAC_PI_2) - .translation(-ground_size, ground_size * 2.0) + .translation(vector![-ground_size, ground_size * 2.0]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size * 2.0, 1.2).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * Create the convex polygons @@ -58,18 +56,20 @@ pub fn init_world(testbed: &mut Testbed) { let x = i as f32 * shift - centerx; let y = j as f32 * shift * 2.0 + centery + 2.0; - let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y).build(); + let rigid_body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y]) + .build(); let handle = bodies.insert(rigid_body); let mut points = Vec::new(); for _ in 0..10 { - let pt: Point2 = distribution.sample(&mut rng); + let pt: Point = distribution.sample(&mut rng); points.push(pt * scale); } let collider = ColliderBuilder::convex_hull(&points).unwrap().build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } } @@ -77,5 +77,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point2::new(0.0, 50.0), 10.0); + testbed.look_at(point![0.0, 50.0], 10.0); } diff --git a/examples2d/damping2.rs b/examples2d/damping2.rs index 68fd77d..e308de6 100644 --- a/examples2d/damping2.rs +++ b/examples2d/damping2.rs @@ -1,6 +1,4 @@ -use na::{Point2, Vector2}; -use rapier2d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier2d::geometry::{ColliderBuilder, ColliderSet}; +use rapier2d::prelude::*; use rapier_testbed2d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -24,8 +22,8 @@ pub fn init_world(testbed: &mut Testbed) { // Build the rigid body. let rb = RigidBodyBuilder::new_dynamic() - .translation(x, y) - .linvel(x * 10.0, y * 10.0) + .translation(vector![x, y]) + .linvel(vector![x * 10.0, y * 10.0]) .angvel(100.0) .linear_damping((i + 1) as f32 * subdiv * 10.0) .angular_damping((num - i) as f32 * subdiv * 10.0) @@ -34,12 +32,12 @@ pub fn init_world(testbed: &mut Testbed) { // Build the collider. let co = ColliderBuilder::cuboid(rad, rad).build(); - colliders.insert(co, rb_handle, &mut bodies); + colliders.insert_with_parent(co, rb_handle, &mut bodies); } /* * Set up the testbed. */ - testbed.set_world_with_params(bodies, colliders, joints, Vector2::zeros(), ()); - testbed.look_at(Point2::new(3.0, 2.0), 50.0); + testbed.set_world_with_params(bodies, colliders, joints, Vector::zeros(), ()); + testbed.look_at(point![3.0, 2.0], 50.0); } diff --git a/examples2d/debug_box_ball2.rs b/examples2d/debug_box_ball2.rs index aad72ae..63b6f95 100644 --- a/examples2d/debug_box_ball2.rs +++ b/examples2d/debug_box_ball2.rs @@ -1,6 +1,4 @@ -use na::Point2; -use rapier2d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier2d::geometry::{ColliderBuilder, ColliderSet}; +use rapier2d::prelude::*; use rapier_testbed2d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -16,25 +14,25 @@ pub fn init_world(testbed: &mut Testbed) { */ let rad = 1.0; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, -rad) + .translation(vector![0.0, -rad]) .rotation(std::f32::consts::PI / 4.0) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(rad, rad).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); // Build the dynamic box rigid body. let rigid_body = RigidBodyBuilder::new_dynamic() - .translation(0.0, 3.0 * rad) + .translation(vector![0.0, 3.0 * rad]) .can_sleep(false) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::ball(rad).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point2::new(0.0, 0.0), 50.0); + testbed.look_at(point![0.0, 0.0], 50.0); } diff --git a/examples2d/heightfield2.rs b/examples2d/heightfield2.rs index a834a2c..6246c40 100644 --- a/examples2d/heightfield2.rs +++ b/examples2d/heightfield2.rs @@ -1,6 +1,5 @@ -use na::{DVector, Point2, Vector2}; -use rapier2d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier2d::geometry::{ColliderBuilder, ColliderSet}; +use na::DVector; +use rapier2d::prelude::*; use rapier_testbed2d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -14,7 +13,7 @@ pub fn init_world(testbed: &mut Testbed) { /* * Ground */ - let ground_size = Vector2::new(50.0, 1.0); + let ground_size = Vector::new(50.0, 1.0); let nsubdivs = 2000; let heights = DVector::from_fn(nsubdivs + 1, |i, _| { @@ -28,7 +27,7 @@ pub fn init_world(testbed: &mut Testbed) { let rigid_body = RigidBodyBuilder::new_static().build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::heightfield(heights, ground_size).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * Create the cubes @@ -46,15 +45,17 @@ pub fn init_world(testbed: &mut Testbed) { let y = j as f32 * shift + centery + 3.0; // Build the rigid body. - let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y).build(); + let rigid_body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y]) + .build(); let handle = bodies.insert(rigid_body); if j % 2 == 0 { let collider = ColliderBuilder::cuboid(rad, rad).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } else { let collider = ColliderBuilder::ball(rad).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } } } @@ -63,5 +64,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point2::new(0.0, 0.0), 10.0); + testbed.look_at(point![0.0, 0.0], 10.0); } diff --git a/examples2d/joints2.rs b/examples2d/joints2.rs index ff5c663..9c94968 100644 --- a/examples2d/joints2.rs +++ b/examples2d/joints2.rs @@ -1,6 +1,4 @@ -use na::Point2; -use rapier2d::dynamics::{BallJoint, JointSet, RigidBodyBuilder, RigidBodySet, RigidBodyType}; -use rapier2d::geometry::{ColliderBuilder, ColliderSet}; +use rapier2d::prelude::*; use rapier_testbed2d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -15,7 +13,7 @@ pub fn init_world(testbed: &mut Testbed) { * Create the balls */ // Build the rigid body. - // NOTE: a smaller radius (e.g. 0.1) breaks Box2D so + // NOTE: a smaller radius (e.g. 0.1) breaks Box2D so // in order to be able to compare rapier with Box2D, // we set it to 0.4. let rad = 0.4; @@ -37,16 +35,16 @@ pub fn init_world(testbed: &mut Testbed) { }; let rigid_body = RigidBodyBuilder::new(status) - .translation(fk * shift, -fi * shift) + .translation(vector![fk * shift, -fi * shift]) .build(); let child_handle = bodies.insert(rigid_body); let collider = ColliderBuilder::ball(rad).build(); - colliders.insert(collider, child_handle, &mut bodies); + colliders.insert_with_parent(collider, child_handle, &mut bodies); // Vertical joint. if i > 0 { let parent_handle = *body_handles.last().unwrap(); - let joint = BallJoint::new(Point2::origin(), Point2::new(0.0, shift)); + let joint = BallJoint::new(Point::origin(), point![0.0, shift]); joints.insert(&mut bodies, parent_handle, child_handle, joint); } @@ -54,7 +52,7 @@ pub fn init_world(testbed: &mut Testbed) { if k > 0 { let parent_index = body_handles.len() - numi; let parent_handle = body_handles[parent_index]; - let joint = BallJoint::new(Point2::origin(), Point2::new(-shift, 0.0)); + let joint = BallJoint::new(Point::origin(), point![-shift, 0.0]); joints.insert(&mut bodies, parent_handle, child_handle, joint); } @@ -66,5 +64,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point2::new(numk as f32 * rad, numi as f32 * -rad), 20.0); + testbed.look_at(point![numk as f32 * rad, numi as f32 * -rad], 20.0); } diff --git a/examples2d/locked_rotations2.rs b/examples2d/locked_rotations2.rs index 03fb2e7..a1f7ba5 100644 --- a/examples2d/locked_rotations2.rs +++ b/examples2d/locked_rotations2.rs @@ -1,6 +1,4 @@ -use na::Point2; -use rapier2d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier2d::geometry::{ColliderBuilder, ColliderSet}; +use rapier2d::prelude::*; use rapier_testbed2d::Testbed; // This shows a bug when a cylinder is in contact with a very large @@ -21,38 +19,38 @@ pub fn init_world(testbed: &mut Testbed) { let ground_height = 0.1; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, -ground_height) + .translation(vector![0.0, -ground_height]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_height).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * A rectangle that only rotate. */ let rigid_body = RigidBodyBuilder::new_dynamic() - .translation(0.0, 3.0) + .translation(vector![0.0, 3.0]) .lock_translations() .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(2.0, 0.6).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * A tilted capsule that cannot rotate. */ let rigid_body = RigidBodyBuilder::new_dynamic() - .translation(0.0, 5.0) + .translation(vector![0.0, 5.0]) .rotation(1.0) .lock_rotations() .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::capsule_y(0.6, 0.4).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point2::new(0.0, 0.0), 40.0); + testbed.look_at(point![0.0, 0.0], 40.0); } diff --git a/examples2d/one_way_platforms2.rs b/examples2d/one_way_platforms2.rs index 19b9968..6cbb2f0 100644 --- a/examples2d/one_way_platforms2.rs +++ b/examples2d/one_way_platforms2.rs @@ -1,7 +1,4 @@ -use na::{Point2, Vector2}; -use rapier2d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier2d::geometry::{ColliderBuilder, ColliderHandle, ColliderSet}; -use rapier2d::pipeline::{ContactModificationContext, PhysicsHooks, PhysicsHooksFlags}; +use rapier2d::prelude::*; use rapier_testbed2d::Testbed; struct OneWayPlatformHook { @@ -10,10 +7,6 @@ struct OneWayPlatformHook { } impl PhysicsHooks for OneWayPlatformHook { - fn active_hooks(&self) -> PhysicsHooksFlags { - PhysicsHooksFlags::MODIFY_SOLVER_CONTACTS - } - fn modify_solver_contacts( &self, context: &mut ContactModificationContext, @@ -30,20 +23,20 @@ impl PhysicsHooks for OneWayPlatformHook { // - If context.collider_handle2 == self.platform1 then the allowed normal is -y. // - If context.collider_handle1 == self.platform2 then its allowed normal +y needs to be flipped to -y. // - If context.collider_handle2 == self.platform2 then the allowed normal -y needs to be flipped to +y. - let mut allowed_local_n1 = Vector2::zeros(); + let mut allowed_local_n1 = Vector::zeros(); if context.collider1 == self.platform1 { - allowed_local_n1 = Vector2::y(); + allowed_local_n1 = Vector::y(); } else if context.collider2 == self.platform1 { // Flip the allowed direction. - allowed_local_n1 = -Vector2::y(); + allowed_local_n1 = -Vector::y(); } if context.collider1 == self.platform2 { - allowed_local_n1 = -Vector2::y(); + allowed_local_n1 = -Vector::y(); } else if context.collider2 == self.platform2 { // Flip the allowed direction. - allowed_local_n1 = Vector2::y(); + allowed_local_n1 = Vector::y(); } // Call the helper function that simulates one-way platforms. @@ -78,15 +71,15 @@ pub fn init_world(testbed: &mut Testbed) { let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(25.0, 0.5) - .translation(30.0, 2.0) - .modify_solver_contacts(true) + .translation(vector![30.0, 2.0]) + .active_hooks(ActiveHooks::MODIFY_SOLVER_CONTACTS) .build(); - let platform1 = colliders.insert(collider, handle, &mut bodies); + let platform1 = colliders.insert_with_parent(collider, handle, &mut bodies); let collider = ColliderBuilder::cuboid(25.0, 0.5) - .translation(-30.0, -2.0) - .modify_solver_contacts(true) + .translation(vector![-30.0, -2.0]) + .active_hooks(ActiveHooks::MODIFY_SOLVER_CONTACTS) .build(); - let platform2 = colliders.insert(collider, handle, &mut bodies); + let platform2 = colliders.insert_with_parent(collider, handle, &mut bodies); /* * Setup the one-way platform hook. @@ -105,12 +98,12 @@ pub fn init_world(testbed: &mut Testbed) { // Spawn a new cube. let collider = ColliderBuilder::cuboid(1.5, 2.0).build(); let body = RigidBodyBuilder::new_dynamic() - .translation(20.0, 10.0) + .translation(vector![20.0, 10.0]) .build(); let handle = physics.bodies.insert(body); physics .colliders - .insert(collider, handle, &mut physics.bodies); + .insert_with_parent(collider, handle, &mut physics.bodies); if let Some(graphics) = graphics { graphics.add_body(handle, &physics.bodies, &physics.colliders); @@ -134,8 +127,8 @@ pub fn init_world(testbed: &mut Testbed) { bodies, colliders, joints, - Vector2::new(0.0, -9.81), + vector![0.0, -9.81], physics_hooks, ); - testbed.look_at(Point2::new(0.0, 0.0), 20.0); + testbed.look_at(point![0.0, 0.0], 20.0); } diff --git a/examples2d/platform2.rs b/examples2d/platform2.rs index 7542cd6..48129a0 100644 --- a/examples2d/platform2.rs +++ b/examples2d/platform2.rs @@ -1,6 +1,4 @@ -use na::Point2; -use rapier2d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier2d::geometry::{ColliderBuilder, ColliderSet}; +use rapier2d::prelude::*; use rapier_testbed2d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -18,11 +16,11 @@ pub fn init_world(testbed: &mut Testbed) { let ground_height = 0.1; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, -ground_height) + .translation(vector![0.0, -ground_height]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_height).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * Create the boxes @@ -40,47 +38,57 @@ pub fn init_world(testbed: &mut Testbed) { let y = j as f32 * shift + centery; // Build the rigid body. - let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y).build(); + let rigid_body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y]) + .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(rad, rad).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } } /* - * Setup a kinematic rigid body. + * Setup a position-based kinematic rigid body. */ - let platform_body = RigidBodyBuilder::new_kinematic() - .translation(-10.0 * rad, 1.5 + 0.8) + let platform_body = RigidBodyBuilder::new_kinematic_velocity_based() + .translation(vector![-10.0 * rad, 1.5 + 0.8]) .build(); - let platform_handle = bodies.insert(platform_body); + let velocity_based_platform_handle = bodies.insert(platform_body); let collider = ColliderBuilder::cuboid(rad * 10.0, rad).build(); - colliders.insert(collider, platform_handle, &mut bodies); + colliders.insert_with_parent(collider, velocity_based_platform_handle, &mut bodies); + + /* + * Setup a velocity-based kinematic rigid body. + */ + let platform_body = RigidBodyBuilder::new_kinematic_position_based() + .translation(vector![-10.0 * rad, 2.0 + 1.5 + 0.8]) + .build(); + let position_based_platform_handle = bodies.insert(platform_body); + let collider = ColliderBuilder::cuboid(rad * 10.0, rad).build(); + colliders.insert_with_parent(collider, position_based_platform_handle, &mut bodies); /* * Setup a callback to control the platform. */ testbed.add_callback(move |_, physics, _, run_state| { - let platform = physics.bodies.get_mut(platform_handle).unwrap(); - let mut next_pos = *platform.position(); + let velocity = vector![run_state.time.sin() * 5.0, (run_state.time * 5.0).sin()]; - let dt = 0.016; - next_pos.translation.vector.y += (run_state.time * 5.0).sin() * dt; - next_pos.translation.vector.x += run_state.time.sin() * 5.0 * dt; - - if next_pos.translation.vector.x >= rad * 10.0 { - next_pos.translation.vector.x -= dt; - } - if next_pos.translation.vector.x <= -rad * 10.0 { - next_pos.translation.vector.x += dt; + // Update the velocity-based kinematic body by setting its velocity. + if let Some(platform) = physics.bodies.get_mut(velocity_based_platform_handle) { + platform.set_linvel(velocity, true); } - platform.set_next_kinematic_position(next_pos); + // Update the position-based kinematic body by setting its next position. + if let Some(platform) = physics.bodies.get_mut(position_based_platform_handle) { + let mut next_tra = *platform.translation(); + next_tra += velocity * physics.integration_parameters.dt; + platform.set_next_kinematic_translation(next_tra); + } }); /* * Run the simulation. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point2::new(0.0, 1.0), 40.0); + testbed.look_at(point![0.0, 1.0], 40.0); } diff --git a/examples2d/polyline2.rs b/examples2d/polyline2.rs index 0b3be0c..7405e24 100644 --- a/examples2d/polyline2.rs +++ b/examples2d/polyline2.rs @@ -1,6 +1,5 @@ -use na::{ComplexField, Point2}; -use rapier2d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier2d::geometry::{ColliderBuilder, ColliderSet}; +use na::ComplexField; +use rapier2d::prelude::*; use rapier_testbed2d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -19,18 +18,18 @@ pub fn init_world(testbed: &mut Testbed) { let step_size = ground_size / (nsubdivs as f32); let mut points = Vec::new(); - points.push(Point2::new(-ground_size / 2.0, 40.0)); + points.push(point![-ground_size / 2.0, 40.0]); for i in 1..nsubdivs - 1 { let x = -ground_size / 2.0 + i as f32 * step_size; let y = ComplexField::cos(i as f32 * step_size) * 2.0; - points.push(Point2::new(x, y)); + points.push(point![x, y]); } - points.push(Point2::new(ground_size / 2.0, 40.0)); + points.push(point![ground_size / 2.0, 40.0]); let rigid_body = RigidBodyBuilder::new_static().build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::polyline(points, None).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * Create the cubes @@ -48,15 +47,17 @@ pub fn init_world(testbed: &mut Testbed) { let y = j as f32 * shift + centery + 3.0; // Build the rigid body. - let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y).build(); + let rigid_body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y]) + .build(); let handle = bodies.insert(rigid_body); if j % 2 == 0 { let collider = ColliderBuilder::cuboid(rad, rad).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } else { let collider = ColliderBuilder::ball(rad).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } } } @@ -65,5 +66,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point2::new(0.0, 0.0), 10.0); + testbed.look_at(point![0.0, 0.0], 10.0); } diff --git a/examples2d/pyramid2.rs b/examples2d/pyramid2.rs index dfa64c9..76616be 100644 --- a/examples2d/pyramid2.rs +++ b/examples2d/pyramid2.rs @@ -1,6 +1,4 @@ -use na::Point2; -use rapier2d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier2d::geometry::{ColliderBuilder, ColliderSet}; +use rapier2d::prelude::*; use rapier_testbed2d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -20,7 +18,7 @@ pub fn init_world(testbed: &mut Testbed) { let rigid_body = RigidBodyBuilder::new_static().build(); let ground_handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_thickness).build(); - colliders.insert(collider, ground_handle, &mut bodies); + colliders.insert_with_parent(collider, ground_handle, &mut bodies); /* * Create the cubes @@ -40,10 +38,12 @@ pub fn init_world(testbed: &mut Testbed) { let y = fi * shift + centery; // Build the rigid body. - let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y).build(); + let rigid_body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y]) + .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(rad, rad).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } } @@ -51,5 +51,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point2::new(0.0, 2.5), 20.0); + testbed.look_at(point![0.0, 2.5], 20.0); } diff --git a/examples2d/restitution2.rs b/examples2d/restitution2.rs index 025a9cd..1be4298 100644 --- a/examples2d/restitution2.rs +++ b/examples2d/restitution2.rs @@ -1,6 +1,4 @@ -use na::Point2; -use rapier2d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier2d::geometry::{ColliderBuilder, ColliderSet}; +use rapier2d::prelude::*; use rapier_testbed2d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -18,13 +16,13 @@ pub fn init_world(testbed: &mut Testbed) { let ground_height = 1.0; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, -ground_height) + .translation(vector![0.0, -ground_height]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_height) .restitution(1.0) .build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); let num = 10; let rad = 0.5; @@ -33,13 +31,13 @@ pub fn init_world(testbed: &mut Testbed) { for i in 0..=num { let x = (i as f32) - num as f32 / 2.0; let rigid_body = RigidBodyBuilder::new_dynamic() - .translation(x * 2.0, 10.0 * (j as f32 + 1.0)) + .translation(vector![x * 2.0, 10.0 * (j as f32 + 1.0)]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::ball(rad) .restitution((i as f32) / (num as f32)) .build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } } @@ -47,5 +45,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point2::new(0.0, 1.0), 25.0); + testbed.look_at(point![0.0, 1.0], 25.0); } diff --git a/examples2d/sensor2.rs b/examples2d/sensor2.rs index a651f64..5dc5940 100644 --- a/examples2d/sensor2.rs +++ b/examples2d/sensor2.rs @@ -1,6 +1,4 @@ -use na::{Point2, Point3}; -use rapier2d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier2d::geometry::{ColliderBuilder, ColliderSet}; +use rapier2d::prelude::*; use rapier_testbed2d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -18,11 +16,11 @@ pub fn init_world(testbed: &mut Testbed) { let ground_height = 0.1; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, -ground_height) + .translation(vector![0.0, -ground_height]) .build(); let ground_handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_height).build(); - colliders.insert(collider, ground_handle, &mut bodies); + colliders.insert_with_parent(collider, ground_handle, &mut bodies); /* * Create some boxes. @@ -38,12 +36,14 @@ pub fn init_world(testbed: &mut Testbed) { let y = 3.0; // Build the rigid body. - let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y).build(); + let rigid_body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y]) + .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(rad, rad).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); - testbed.set_initial_body_color(handle, Point3::new(0.5, 0.5, 1.0)); + testbed.set_initial_body_color(handle, [0.5, 0.5, 1.0]); } /* @@ -52,33 +52,38 @@ pub fn init_world(testbed: &mut Testbed) { // Rigid body so that the sensor can move. let sensor = RigidBodyBuilder::new_dynamic() - .translation(0.0, 10.0) + .translation(vector![0.0, 10.0]) .build(); let sensor_handle = bodies.insert(sensor); // Solid cube attached to the sensor which // other colliders can touch. let collider = ColliderBuilder::cuboid(rad, rad).build(); - colliders.insert(collider, sensor_handle, &mut bodies); + colliders.insert_with_parent(collider, sensor_handle, &mut bodies); // We create a collider desc without density because we don't // want it to contribute to the rigid body mass. - let sensor_collider = ColliderBuilder::ball(rad * 5.0).sensor(true).build(); - colliders.insert(sensor_collider, sensor_handle, &mut bodies); + let sensor_collider = ColliderBuilder::ball(rad * 5.0) + .density(0.0) + .sensor(true) + .active_events(ActiveEvents::INTERSECTION_EVENTS) + .build(); + colliders.insert_with_parent(sensor_collider, sensor_handle, &mut bodies); - testbed.set_initial_body_color(sensor_handle, Point3::new(0.5, 1.0, 1.0)); + testbed.set_initial_body_color(sensor_handle, [0.5, 1.0, 1.0]); // Callback that will be executed on the main loop to handle proximities. testbed.add_callback(move |mut graphics, physics, events, _| { while let Ok(prox) = events.intersection_events.try_recv() { let color = if prox.intersecting { - Point3::new(1.0, 1.0, 0.0) + [1.0, 1.0, 0.0] } else { - Point3::new(0.5, 0.5, 1.0) + [0.5, 0.5, 1.0] }; - let parent_handle1 = physics.colliders.get(prox.collider1).unwrap().parent(); - let parent_handle2 = physics.colliders.get(prox.collider2).unwrap().parent(); + let parent_handle1 = physics.colliders[prox.collider1].parent().unwrap(); + let parent_handle2 = physics.colliders[prox.collider2].parent().unwrap(); + if let Some(graphics) = &mut graphics { if parent_handle1 != ground_handle && parent_handle1 != sensor_handle { graphics.set_body_color(parent_handle1, color); @@ -94,5 +99,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point2::new(0.0, 1.0), 100.0); + testbed.look_at(point![0.0, 1.0], 100.0); } diff --git a/examples2d/trimesh2.rs b/examples2d/trimesh2.rs index adc8b6b..a4b049a 100644 --- a/examples2d/trimesh2.rs +++ b/examples2d/trimesh2.rs @@ -1,6 +1,4 @@ -use na::Point2; -use rapier2d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier2d::geometry::{ColliderBuilder, ColliderSet}; +use rapier2d::prelude::*; use rapier_testbed2d::Testbed; use lyon::math::Point; @@ -25,23 +23,23 @@ pub fn init_world(testbed: &mut Testbed) { let rigid_body = RigidBodyBuilder::new_static().build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, 1.2).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); let rigid_body = RigidBodyBuilder::new_static() .rotation(std::f32::consts::FRAC_PI_2) - .translation(ground_size, ground_size) + .translation(vector![ground_size, ground_size]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, 1.2).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); let rigid_body = RigidBodyBuilder::new_static() .rotation(std::f32::consts::FRAC_PI_2) - .translation(-ground_size, ground_size) + .translation(vector![-ground_size, ground_size]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, 1.2).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * Create the trimeshes from a tesselated SVG. @@ -83,18 +81,18 @@ pub fn init_world(testbed: &mut Testbed) { let vertices: Vec<_> = mesh .vertices .iter() - .map(|v| Point2::new(v.position[0] * sx, v.position[1] * -sy)) + .map(|v| point![v.position[0] * sx, v.position[1] * -sy]) .collect(); for k in 0..5 { let collider = ColliderBuilder::trimesh(vertices.clone(), indices.clone()).build(); let rigid_body = RigidBodyBuilder::new_dynamic() - .translation(ith as f32 * 8.0 - 20.0, 20.0 + k as f32 * 11.0) + .translation(vector![ith as f32 * 8.0 - 20.0, 20.0 + k as f32 * 11.0]) .rotation(angle) .build(); let handle = bodies.insert(rigid_body); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } ith += 1; @@ -106,7 +104,7 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point2::new(0.0, 20.0), 17.0); + testbed.look_at(point![0.0, 20.0], 17.0); } const RAPIER_SVG_STR: &'static str = r#" diff --git a/examples3d/Cargo.toml b/examples3d/Cargo.toml index 37c641f..a80f3dc 100644 --- a/examples3d/Cargo.toml +++ b/examples3d/Cargo.toml @@ -16,7 +16,7 @@ enhanced-determinism = [ "rapier3d/enhanced-determinism" ] rand = "0.8" getrandom = { version = "0.2", features = [ "js" ] } Inflector = "0.11" -nalgebra = "0.26" +nalgebra = "0.27" wasm-bindgen = "0.2" obj-rs = { version = "0.6", default-features = false } diff --git a/examples3d/ccd3.rs b/examples3d/ccd3.rs index e5dee33..8d676e3 100644 --- a/examples3d/ccd3.rs +++ b/examples3d/ccd3.rs @@ -1,15 +1,13 @@ -use na::{Point3, Vector3}; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; fn create_wall( testbed: &mut Testbed, bodies: &mut RigidBodySet, colliders: &mut ColliderSet, - offset: Vector3, + offset: Vector, stack_height: usize, - half_extents: Vector3, + half_extents: Vector, ) { let shift = half_extents * 2.0; let mut k = 0; @@ -23,22 +21,18 @@ fn create_wall( - stack_height as f32 * half_extents.z; // Build the rigid body. - let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y, z).build(); + let rigid_body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y, z]) + .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(half_extents.x, half_extents.y, half_extents.z).build(); - colliders.insert(collider, handle, bodies); + colliders.insert_with_parent(collider, handle, bodies); k += 1; if k % 2 == 0 { - testbed.set_initial_body_color( - handle, - Point3::new(255. / 255., 131. / 255., 244.0 / 255.), - ); + testbed.set_initial_body_color(handle, [255. / 255., 131. / 255., 244.0 / 255.]); } else { - testbed.set_initial_body_color( - handle, - Point3::new(131. / 255., 255. / 255., 244.0 / 255.), - ); + testbed.set_initial_body_color(handle, [131. / 255., 255. / 255., 244.0 / 255.]); } } } @@ -59,11 +53,11 @@ pub fn init_world(testbed: &mut Testbed) { let ground_height = 0.1; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, -ground_height, 0.0) + .translation(vector![0.0, -ground_height, 0.0]) .build(); let ground_handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size).build(); - colliders.insert(collider, ground_handle, &mut bodies); + colliders.insert_with_parent(collider, ground_handle, &mut bodies); /* * Create the pyramids. @@ -79,18 +73,18 @@ pub fn init_world(testbed: &mut Testbed) { testbed, &mut bodies, &mut colliders, - Vector3::new(x, shift_y, 0.0), + vector![x, shift_y, 0.0], num_z, - Vector3::new(0.5, 0.5, 1.0), + vector![0.5, 0.5, 1.0], ); create_wall( testbed, &mut bodies, &mut colliders, - Vector3::new(x, shift_y, shift_z), + vector![x, shift_y, shift_z], num_z, - Vector3::new(0.5, 0.5, 1.0), + vector![0.5, 0.5, 1.0], ); } @@ -102,37 +96,48 @@ pub fn init_world(testbed: &mut Testbed) { let collider = ColliderBuilder::ball(1.0) .density(10.0) .sensor(true) + .active_events(ActiveEvents::INTERSECTION_EVENTS) .build(); let rigid_body = RigidBodyBuilder::new_dynamic() - .linvel(1000.0, 0.0, 0.0) - .translation(-20.0, shift_y + 2.0, 0.0) + .linvel(vector![1000.0, 0.0, 0.0]) + .translation(vector![-20.0, shift_y + 2.0, 0.0]) .ccd_enabled(true) .build(); let sensor_handle = bodies.insert(rigid_body); - colliders.insert(collider, sensor_handle, &mut bodies); + colliders.insert_with_parent(collider, sensor_handle, &mut bodies); // Second rigid-body with CCD enabled. let collider = ColliderBuilder::ball(1.0).density(10.0).build(); let rigid_body = RigidBodyBuilder::new_dynamic() - .linvel(1000.0, 0.0, 0.0) - .translation(-20.0, shift_y + 2.0, shift_z) + .linvel(vector![1000.0, 0.0, 0.0]) + .translation(vector![-20.0, shift_y + 2.0, shift_z]) .ccd_enabled(true) .build(); let handle = bodies.insert(rigid_body); - colliders.insert(collider.clone(), handle, &mut bodies); - testbed.set_initial_body_color(handle, Point3::new(0.2, 0.2, 1.0)); + colliders.insert_with_parent(collider.clone(), handle, &mut bodies); + testbed.set_initial_body_color(handle, [0.2, 0.2, 1.0]); // Callback that will be executed on the main loop to handle proximities. testbed.add_callback(move |mut graphics, physics, events, _| { while let Ok(prox) = events.intersection_events.try_recv() { let color = if prox.intersecting { - Point3::new(1.0, 1.0, 0.0) + [1.0, 1.0, 0.0] } else { - Point3::new(0.5, 0.5, 1.0) + [0.5, 0.5, 1.0] }; - let parent_handle1 = physics.colliders.get(prox.collider1).unwrap().parent(); - let parent_handle2 = physics.colliders.get(prox.collider2).unwrap().parent(); + let parent_handle1 = physics + .colliders + .get(prox.collider1) + .unwrap() + .parent() + .unwrap(); + let parent_handle2 = physics + .colliders + .get(prox.collider2) + .unwrap() + .parent() + .unwrap(); if let Some(graphics) = &mut graphics { if parent_handle1 != ground_handle && parent_handle1 != sensor_handle { @@ -149,5 +154,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(100.0, 100.0, 100.0), Point3::origin()); + testbed.look_at(point![100.0, 100.0, 100.0], Point::origin()); } diff --git a/examples3d/collision_groups3.rs b/examples3d/collision_groups3.rs index a79a4bc..8db86fa 100644 --- a/examples3d/collision_groups3.rs +++ b/examples3d/collision_groups3.rs @@ -1,6 +1,4 @@ -use na::Point3; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet, InteractionGroups}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -18,11 +16,11 @@ pub fn init_world(testbed: &mut Testbed) { let ground_height = 0.1; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, -ground_height, 0.0) + .translation(vector![0.0, -ground_height, 0.0]) .build(); let floor_handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size).build(); - colliders.insert(collider, floor_handle, &mut bodies); + colliders.insert_with_parent(collider, floor_handle, &mut bodies); /* * Setup groups @@ -34,23 +32,24 @@ pub fn init_world(testbed: &mut Testbed) { * A green floor that will collide with the GREEN group only. */ let green_floor = ColliderBuilder::cuboid(1.0, 0.1, 1.0) - .translation(0.0, 1.0, 0.0) + .translation(vector![0.0, 1.0, 0.0]) .collision_groups(GREEN_GROUP) .build(); - let green_collider_handle = colliders.insert(green_floor, floor_handle, &mut bodies); + let green_collider_handle = + colliders.insert_with_parent(green_floor, floor_handle, &mut bodies); - testbed.set_initial_collider_color(green_collider_handle, Point3::new(0.0, 1.0, 0.0)); + testbed.set_initial_collider_color(green_collider_handle, [0.0, 1.0, 0.0]); /* * A blue floor that will collide with the BLUE group only. */ let blue_floor = ColliderBuilder::cuboid(1.0, 0.1, 1.0) - .translation(0.0, 2.0, 0.0) + .translation(vector![0.0, 2.0, 0.0]) .collision_groups(BLUE_GROUP) .build(); - let blue_collider_handle = colliders.insert(blue_floor, floor_handle, &mut bodies); + let blue_collider_handle = colliders.insert_with_parent(blue_floor, floor_handle, &mut bodies); - testbed.set_initial_collider_color(blue_collider_handle, Point3::new(0.0, 0.0, 1.0)); + testbed.set_initial_collider_color(blue_collider_handle, [0.0, 0.0, 1.0]); /* * Create the cubes @@ -72,17 +71,19 @@ pub fn init_world(testbed: &mut Testbed) { // Alternate between the green and blue groups. let (group, color) = if k % 2 == 0 { - (GREEN_GROUP, Point3::new(0.0, 1.0, 0.0)) + (GREEN_GROUP, [0.0, 1.0, 0.0]) } else { - (BLUE_GROUP, Point3::new(0.0, 0.0, 1.0)) + (BLUE_GROUP, [0.0, 0.0, 1.0]) }; - let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y, z).build(); + let rigid_body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y, z]) + .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(rad, rad, rad) .collision_groups(group) .build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); testbed.set_initial_body_color(handle, color); } @@ -93,5 +94,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(10.0, 10.0, 10.0), Point3::origin()); + testbed.look_at(point!(10.0, 10.0, 10.0), Point::origin()); } diff --git a/examples3d/compound3.rs b/examples3d/compound3.rs index 51523f3..f5f1de1 100644 --- a/examples3d/compound3.rs +++ b/examples3d/compound3.rs @@ -1,6 +1,4 @@ -use na::{Isometry3, Point3}; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet, SharedShape}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -18,11 +16,11 @@ pub fn init_world(testbed: &mut Testbed) { let ground_height = 0.1; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, -ground_height, 0.0) + .translation(vector![0.0, -ground_height, 0.0]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * Create the cubes @@ -46,40 +44,42 @@ pub fn init_world(testbed: &mut Testbed) { let z = k as f32 * shift * 2.0 - centerz + offset; // Build the rigid body. - let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y, z).build(); + let rigid_body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y, z]) + .build(); let handle = bodies.insert(rigid_body); // First option: attach several colliders to a single rigid-body. if j < numy / 2 { let collider1 = ColliderBuilder::cuboid(rad * 10.0, rad, rad).build(); let collider2 = ColliderBuilder::cuboid(rad, rad * 10.0, rad) - .translation(rad * 10.0, rad * 10.0, 0.0) + .translation(vector![rad * 10.0, rad * 10.0, 0.0]) .build(); let collider3 = ColliderBuilder::cuboid(rad, rad * 10.0, rad) - .translation(-rad * 10.0, rad * 10.0, 0.0) + .translation(vector![-rad * 10.0, rad * 10.0, 0.0]) .build(); - colliders.insert(collider1, handle, &mut bodies); - colliders.insert(collider2, handle, &mut bodies); - colliders.insert(collider3, handle, &mut bodies); + colliders.insert_with_parent(collider1, handle, &mut bodies); + colliders.insert_with_parent(collider2, handle, &mut bodies); + colliders.insert_with_parent(collider3, handle, &mut bodies); } else { // Second option: create a compound shape and attach it to a single collider. let shapes = vec![ ( - Isometry3::identity(), + Isometry::identity(), SharedShape::cuboid(rad * 10.0, rad, rad), ), ( - Isometry3::translation(rad * 10.0, rad * 10.0, 0.0), + Isometry::translation(rad * 10.0, rad * 10.0, 0.0), SharedShape::cuboid(rad, rad * 10.0, rad), ), ( - Isometry3::translation(-rad * 10.0, rad * 10.0, 0.0), + Isometry::translation(-rad * 10.0, rad * 10.0, 0.0), SharedShape::cuboid(rad, rad * 10.0, rad), ), ]; let collider = ColliderBuilder::compound(shapes).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } } } @@ -91,5 +91,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(100.0, 100.0, 100.0), Point3::origin()); + testbed.look_at(point![100.0, 100.0, 100.0], Point::origin()); } diff --git a/examples3d/convex_decomposition3.rs b/examples3d/convex_decomposition3.rs index 1d19597..5676f6d 100644 --- a/examples3d/convex_decomposition3.rs +++ b/examples3d/convex_decomposition3.rs @@ -1,8 +1,6 @@ -use na::Point3; use obj::raw::object::Polygon; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet, SharedShape}; use rapier3d::parry::bounding_volume; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; use std::fs::File; use std::io::BufReader; @@ -26,11 +24,11 @@ pub fn init_world(testbed: &mut Testbed) { let ground_height = 0.1; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, -ground_height, 0.0) + .translation(vector![0.0, -ground_height, 0.0]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * Create the convex decompositions. @@ -52,7 +50,7 @@ pub fn init_world(testbed: &mut Testbed) { let mut vertices: Vec<_> = model .positions .iter() - .map(|v| Point3::new(v.0, v.1, v.2)) + .map(|v| point![v.0, v.1, v.2]) .collect(); use std::iter::FromIterator; let indices: Vec<_> = model @@ -90,12 +88,14 @@ pub fn init_world(testbed: &mut Testbed) { let y = (igeom / width) as f32 * shift + 4.0; let z = k as f32 * shift; - let body = RigidBodyBuilder::new_dynamic().translation(x, y, z).build(); + let body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y, z]) + .build(); let handle = bodies.insert(body); for shape in &shapes { let collider = ColliderBuilder::new(shape.clone()).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } } } @@ -105,7 +105,7 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(100.0, 100.0, 100.0), Point3::origin()); + testbed.look_at(point![100.0, 100.0, 100.0], Point::origin()); } fn models() -> Vec { diff --git a/examples3d/convex_polyhedron3.rs b/examples3d/convex_polyhedron3.rs index c43a781..896eb03 100644 --- a/examples3d/convex_polyhedron3.rs +++ b/examples3d/convex_polyhedron3.rs @@ -1,8 +1,6 @@ -use na::Point3; use rand::distributions::{Distribution, Standard}; use rand::{rngs::StdRng, SeedableRng}; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -20,11 +18,11 @@ pub fn init_world(testbed: &mut Testbed) { let ground_height = 0.1; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, -ground_height, 0.0) + .translation(vector![0.0, -ground_height, 0.0]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * Create the polyhedra @@ -50,17 +48,19 @@ pub fn init_world(testbed: &mut Testbed) { let mut points = Vec::new(); for _ in 0..10 { - let pt: Point3 = distribution.sample(&mut rng); + let pt: Point = distribution.sample(&mut rng); points.push(pt * scale); } // Build the rigid body. - let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y, z).build(); + let rigid_body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y, z]) + .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::round_convex_hull(&points, border_rad) .unwrap() .build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } } } @@ -69,5 +69,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(30.0, 30.0, 30.0), Point3::origin()); + testbed.look_at(point![30.0, 30.0, 30.0], Point::origin()); } diff --git a/examples3d/damping3.rs b/examples3d/damping3.rs index 3847ceb..c634a0a 100644 --- a/examples3d/damping3.rs +++ b/examples3d/damping3.rs @@ -1,6 +1,4 @@ -use na::{Point3, Vector3}; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -24,9 +22,9 @@ pub fn init_world(testbed: &mut Testbed) { // Build the rigid body. let rb = RigidBodyBuilder::new_dynamic() - .translation(x, y, 0.0) - .linvel(x * 10.0, y * 10.0, 0.0) - .angvel(Vector3::z() * 100.0) + .translation(vector![x, y, 0.0]) + .linvel(vector![x * 10.0, y * 10.0, 0.0]) + .angvel(Vector::z() * 100.0) .linear_damping((i + 1) as f32 * subdiv * 10.0) .angular_damping((num - i) as f32 * subdiv * 10.0) .build(); @@ -34,12 +32,12 @@ pub fn init_world(testbed: &mut Testbed) { // Build the collider. let co = ColliderBuilder::cuboid(rad, rad, rad).build(); - colliders.insert(co, rb_handle, &mut bodies); + colliders.insert_with_parent(co, rb_handle, &mut bodies); } /* * Set up the testbed. */ - testbed.set_world_with_params(bodies, colliders, joints, Vector3::zeros(), ()); - testbed.look_at(Point3::new(2.0, 2.5, 20.0), Point3::new(2.0, 2.5, 0.0)); + testbed.set_world_with_params(bodies, colliders, joints, Vector::zeros(), ()); + testbed.look_at(point![2.0, 2.5, 20.0], point![2.0, 2.5, 0.0]); } diff --git a/examples3d/debug_add_remove_collider3.rs b/examples3d/debug_add_remove_collider3.rs index 00a0ff3..12d58ec 100644 --- a/examples3d/debug_add_remove_collider3.rs +++ b/examples3d/debug_add_remove_collider3.rs @@ -1,6 +1,4 @@ -use na::Point3; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -17,22 +15,23 @@ pub fn init_world(testbed: &mut Testbed) { let ground_height = 0.1; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, -ground_height, 0.0) + .translation(vector![0.0, -ground_height, 0.0]) .build(); let ground_handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_height, 0.4).build(); - let mut ground_collider_handle = colliders.insert(collider, ground_handle, &mut bodies); + let mut ground_collider_handle = + colliders.insert_with_parent(collider, ground_handle, &mut bodies); /* * Rolling ball */ let ball_rad = 0.1; let rb = RigidBodyBuilder::new_dynamic() - .translation(0.0, 0.2, 0.0) + .translation(vector![0.0, 0.2, 0.0]) .build(); let ball_handle = bodies.insert(rb); let collider = ColliderBuilder::ball(ball_rad).density(100.0).build(); - colliders.insert(collider, ball_handle, &mut bodies); + colliders.insert_with_parent(collider, ball_handle, &mut bodies); testbed.add_callback(move |_, physics, _, _| { // Remove then re-add the ground collider. @@ -46,14 +45,15 @@ pub fn init_world(testbed: &mut Testbed) { true, ) .unwrap(); - ground_collider_handle = physics - .colliders - .insert(coll, ground_handle, &mut physics.bodies); + ground_collider_handle = + physics + .colliders + .insert_with_parent(coll, ground_handle, &mut physics.bodies); }); /* * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(10.0, 10.0, 10.0), Point3::origin()); + testbed.look_at(point![10.0, 10.0, 10.0], Point::origin()); } diff --git a/examples3d/debug_big_colliders3.rs b/examples3d/debug_big_colliders3.rs index a524f97..864782f 100644 --- a/examples3d/debug_big_colliders3.rs +++ b/examples3d/debug_big_colliders3.rs @@ -1,6 +1,4 @@ -use na::{Point3, Vector3}; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet, HalfSpace, SharedShape}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -16,9 +14,9 @@ pub fn init_world(testbed: &mut Testbed) { */ let rigid_body = RigidBodyBuilder::new_static().build(); let handle = bodies.insert(rigid_body); - let halfspace = SharedShape::new(HalfSpace::new(Vector3::y_axis())); + let halfspace = SharedShape::new(HalfSpace::new(Vector::y_axis())); let collider = ColliderBuilder::new(halfspace).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); let mut curr_y = 0.0; let mut curr_width = 10_000.0; @@ -28,11 +26,11 @@ pub fn init_world(testbed: &mut Testbed) { curr_y += curr_height * 4.0; let rigid_body = RigidBodyBuilder::new_dynamic() - .translation(0.0, curr_y, 0.0) + .translation(vector![0.0, curr_y, 0.0]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(curr_width, curr_height, curr_width).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); curr_width /= 5.0; } @@ -41,5 +39,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(10.0, 10.0, 10.0), Point3::origin()); + testbed.look_at(point![10.0, 10.0, 10.0], Point::origin()); } diff --git a/examples3d/debug_boxes3.rs b/examples3d/debug_boxes3.rs index cba9d01..ea39a8a 100644 --- a/examples3d/debug_boxes3.rs +++ b/examples3d/debug_boxes3.rs @@ -1,6 +1,4 @@ -use na::{Point3, Vector3}; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -19,28 +17,28 @@ pub fn init_world(testbed: &mut Testbed) { for _ in 0..6 { let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, -ground_height, 0.0) + .translation(vector![0.0, -ground_height, 0.0]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } // Build the dynamic box rigid body. for _ in 0..6 { let rigid_body = RigidBodyBuilder::new_dynamic() - .translation(1.1, 0.0, 0.0) - .rotation(Vector3::new(0.8, 0.2, 0.1)) + .translation(vector![1.1, 0.0, 0.0]) + .rotation(vector![0.8, 0.2, 0.1]) .can_sleep(false) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(2.0, 0.1, 1.0).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } /* * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(10.0, 10.0, 10.0), Point3::origin()); + testbed.look_at(point![10.0, 10.0, 10.0], Point::origin()); } diff --git a/examples3d/debug_cylinder3.rs b/examples3d/debug_cylinder3.rs index 0b68b62..88908c1 100644 --- a/examples3d/debug_cylinder3.rs +++ b/examples3d/debug_cylinder3.rs @@ -1,6 +1,4 @@ -use na::Point3; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; // This shows a bug when a cylinder is in contact with a very large @@ -21,11 +19,11 @@ pub fn init_world(testbed: &mut Testbed) { let ground_height = 0.1; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, -ground_height, 0.0) + .translation(vector![0.0, -ground_height, 0.0]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * Create the cubes @@ -47,14 +45,16 @@ pub fn init_world(testbed: &mut Testbed) { let z = -centerz + offset; // Build the rigid body. - let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y, z).build(); + let rigid_body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y, z]) + .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cylinder(rad, rad).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(100.0, 100.0, 100.0), Point3::origin()); + testbed.look_at(point![100.0, 100.0, 100.0], Point::origin()); } diff --git a/examples3d/debug_dynamic_collider_add3.rs b/examples3d/debug_dynamic_collider_add3.rs index 6a4589b..f66d8ce 100644 --- a/examples3d/debug_dynamic_collider_add3.rs +++ b/examples3d/debug_dynamic_collider_add3.rs @@ -1,6 +1,4 @@ -use na::{Isometry3, Point3, Vector3}; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -17,30 +15,30 @@ pub fn init_world(testbed: &mut Testbed) { let ground_height = 0.1; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, -ground_height, 0.0) + .translation(vector![0.0, -ground_height, 0.0]) .build(); let ground_handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_height, 0.4) .friction(0.15) // .restitution(0.5) .build(); - colliders.insert(collider, ground_handle, &mut bodies); + colliders.insert_with_parent(collider, ground_handle, &mut bodies); /* * Rolling ball */ let ball_rad = 0.1; let rb = RigidBodyBuilder::new_dynamic() - .translation(0.0, 0.2, 0.0) - .linvel(10.0, 0.0, 0.0) + .translation(vector![0.0, 0.2, 0.0]) + .linvel(vector![10.0, 0.0, 0.0]) .build(); let ball_handle = bodies.insert(rb); let collider = ColliderBuilder::ball(ball_rad).density(100.0).build(); - colliders.insert(collider, ball_handle, &mut bodies); + colliders.insert_with_parent(collider, ball_handle, &mut bodies); - let mut linvel = Vector3::zeros(); - let mut angvel = Vector3::zeros(); - let mut pos = Isometry3::identity(); + let mut linvel = Vector::zeros(); + let mut angvel = Vector::zeros(); + let mut pos = Isometry::identity(); let mut step = 0; let mut extra_colliders = Vec::new(); let snapped_frame = 51; @@ -55,7 +53,7 @@ pub fn init_world(testbed: &mut Testbed) { let new_ball_collider_handle = physics .colliders - .insert(collider, ball_handle, &mut physics.bodies); + .insert_with_parent(collider, ball_handle, &mut physics.bodies); if let Some(graphics) = &mut graphics { graphics.add_collider(new_ball_collider_handle, &physics.colliders); @@ -93,7 +91,7 @@ pub fn init_world(testbed: &mut Testbed) { // Remove then re-add the ground collider. // let ground = physics.bodies.get_mut(ground_handle).unwrap(); - // ground.set_position(Isometry3::translation(0.0, step as f32 * 0.001, 0.0), false); + // ground.set_position(Isometry::translation(0.0, step as f32 * 0.001, 0.0), false); // let coll = physics // .colliders // .remove(ground_collider_handle, &mut physics.bodies, true) @@ -104,7 +102,7 @@ pub fn init_world(testbed: &mut Testbed) { let new_ground_collider_handle = physics .colliders - .insert(coll, ground_handle, &mut physics.bodies); + .insert_with_parent(coll, ground_handle, &mut physics.bodies); if let Some(graphics) = &mut graphics { graphics.add_collider(new_ground_collider_handle, &physics.colliders); @@ -117,5 +115,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(10.0, 10.0, 10.0), Point3::origin()); + testbed.look_at(point![10.0, 10.0, 10.0], Point::origin()); } diff --git a/examples3d/debug_friction3.rs b/examples3d/debug_friction3.rs index 72631a7..7d01986 100644 --- a/examples3d/debug_friction3.rs +++ b/examples3d/debug_friction3.rs @@ -1,6 +1,4 @@ -use na::{Point3, Vector3}; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -22,24 +20,24 @@ pub fn init_world(testbed: &mut Testbed) { let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size) .friction(1.5) .build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); // Build a dynamic box rigid body. let rigid_body = RigidBodyBuilder::new_dynamic() - .translation(0.0, 1.1, 0.0) - .rotation(Vector3::y() * 0.3) + .translation(vector![0.0, 1.1, 0.0]) + .rotation(Vector::y() * 0.3) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(2.0, 1.0, 3.0).friction(1.5).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); let rigid_body = &mut bodies[handle]; - let force = rigid_body.position() * Vector3::z() * 50.0; + let force = rigid_body.position() * Vector::z() * 50.0; rigid_body.set_linvel(force, true); /* * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(100.0, 100.0, 100.0), Point3::origin()); + testbed.look_at(point![100.0, 100.0, 100.0], Point::origin()); } diff --git a/examples3d/debug_infinite_fall3.rs b/examples3d/debug_infinite_fall3.rs index ef41c92..dcf4f12 100644 --- a/examples3d/debug_infinite_fall3.rs +++ b/examples3d/debug_infinite_fall3.rs @@ -1,6 +1,4 @@ -use na::Point3; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -18,33 +16,33 @@ pub fn init_world(testbed: &mut Testbed) { let ground_height = 2.1; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, 4.0, 0.0) + .translation(vector![0.0, 4.0, 0.0]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); let rad = 1.0; // Build the dynamic box rigid body. let rigid_body = RigidBodyBuilder::new_dynamic() - .translation(0.0, 7.0 * rad, 0.0) + .translation(vector![0.0, 7.0 * rad, 0.0]) .can_sleep(false) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::ball(rad).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); let rigid_body = RigidBodyBuilder::new_dynamic() - .translation(0.0, 2.0 * rad, 0.0) + .translation(vector![0.0, 2.0 * rad, 0.0]) .can_sleep(false) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::ball(rad).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * Set up the testbed. */ - testbed.look_at(Point3::new(100.0, -10.0, 100.0), Point3::origin()); + testbed.look_at(point![100.0, -10.0, 100.0], Point::origin()); testbed.set_world(bodies, colliders, joints); } diff --git a/examples3d/debug_prismatic3.rs b/examples3d/debug_prismatic3.rs index 07cf381..f41ef49 100644 --- a/examples3d/debug_prismatic3.rs +++ b/examples3d/debug_prismatic3.rs @@ -1,20 +1,18 @@ -use na::{Point3, Vector3}; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; fn prismatic_repro( bodies: &mut RigidBodySet, colliders: &mut ColliderSet, joints: &mut JointSet, - box_center: Point3, + box_center: Point, ) { let box_rb = bodies.insert( RigidBodyBuilder::new_dynamic() - .translation(box_center.x, box_center.y, box_center.z) + .translation(vector![box_center.x, box_center.y, box_center.z]) .build(), ); - colliders.insert( + colliders.insert_with_parent( ColliderBuilder::cuboid(1.0, 0.25, 1.0).build(), box_rb, bodies, @@ -22,32 +20,32 @@ fn prismatic_repro( let wheel_y = -1.0; let wheel_positions = vec![ - Vector3::new(1.0, wheel_y, -1.0), - Vector3::new(-1.0, wheel_y, -1.0), - Vector3::new(1.0, wheel_y, 1.0), - Vector3::new(-1.0, wheel_y, 1.0), + vector![1.0, wheel_y, -1.0], + vector![-1.0, wheel_y, -1.0], + vector![1.0, wheel_y, 1.0], + vector![-1.0, wheel_y, 1.0], ]; for pos in wheel_positions { let wheel_pos_in_world = box_center + pos; let wheel_rb = bodies.insert( RigidBodyBuilder::new_dynamic() - .translation( + .translation(vector![ wheel_pos_in_world.x, wheel_pos_in_world.y, - wheel_pos_in_world.z, - ) + wheel_pos_in_world.z + ]) .build(), ); - colliders.insert(ColliderBuilder::ball(0.5).build(), wheel_rb, bodies); + colliders.insert_with_parent(ColliderBuilder::ball(0.5).build(), wheel_rb, bodies); let mut prismatic = rapier3d::dynamics::PrismaticJoint::new( - Point3::new(pos.x, pos.y, pos.z), - Vector3::y_axis(), - Vector3::default(), - Point3::new(0.0, 0.0, 0.0), - Vector3::y_axis(), - Vector3::default(), + point![pos.x, pos.y, pos.z], + Vector::y_axis(), + Vector::zeros(), + Point::origin(), + Vector::y_axis(), + Vector::default(), ); prismatic.configure_motor_model(rapier3d::dynamics::SpringModel::VelocityBased); let (stiffness, damping) = (0.05, 0.2); @@ -59,10 +57,10 @@ fn prismatic_repro( // put a small box under one of the wheels let gravel = bodies.insert( RigidBodyBuilder::new_dynamic() - .translation(box_center.x + 1.0, box_center.y - 2.4, -1.0) + .translation(vector![box_center.x + 1.0, box_center.y - 2.4, -1.0]) .build(), ); - colliders.insert( + colliders.insert_with_parent( ColliderBuilder::cuboid(0.5, 0.1, 0.5).build(), gravel, bodies, @@ -84,22 +82,22 @@ pub fn init_world(testbed: &mut Testbed) { let ground_height = 0.1; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, -ground_height, 0.0) + .translation(vector![0.0, -ground_height, 0.0]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); prismatic_repro( &mut bodies, &mut colliders, &mut joints, - Point3::new(0.0, 5.0, 0.0), + point![0.0, 5.0, 0.0], ); /* * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(10.0, 10.0, 10.0), Point3::origin()); + testbed.look_at(point![10.0, 10.0, 10.0], Point::origin()); } diff --git a/examples3d/debug_rollback3.rs b/examples3d/debug_rollback3.rs index 8f1bede..c5e5bde 100644 --- a/examples3d/debug_rollback3.rs +++ b/examples3d/debug_rollback3.rs @@ -1,6 +1,4 @@ -use na::{Isometry3, Point3, Vector3}; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -17,30 +15,30 @@ pub fn init_world(testbed: &mut Testbed) { let ground_height = 0.1; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, -ground_height, 0.0) + .translation(vector![0.0, -ground_height, 0.0]) .build(); let ground_handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_height, 0.4) .friction(0.15) // .restitution(0.5) .build(); - colliders.insert(collider, ground_handle, &mut bodies); + colliders.insert_with_parent(collider, ground_handle, &mut bodies); /* * Rolling ball */ let ball_rad = 0.1; let rb = RigidBodyBuilder::new_dynamic() - .translation(0.0, 0.2, 0.0) - .linvel(10.0, 0.0, 0.0) + .translation(vector![0.0, 0.2, 0.0]) + .linvel(vector![10.0, 0.0, 0.0]) .build(); let ball_handle = bodies.insert(rb); let collider = ColliderBuilder::ball(ball_rad).density(100.0).build(); - colliders.insert(collider, ball_handle, &mut bodies); + colliders.insert_with_parent(collider, ball_handle, &mut bodies); - let mut linvel = Vector3::zeros(); - let mut angvel = Vector3::zeros(); - let mut pos = Isometry3::identity(); + let mut linvel = Vector::zeros(); + let mut angvel = Vector::zeros(); + let mut pos = Isometry::identity(); let mut step = 0; let snapped_frame = 51; @@ -68,5 +66,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(10.0, 10.0, 10.0), Point3::origin()); + testbed.look_at(point![10.0, 10.0, 10.0], Point::origin()); } diff --git a/examples3d/debug_shape_modification3.rs b/examples3d/debug_shape_modification3.rs index bef56fa..6c27288 100644 --- a/examples3d/debug_shape_modification3.rs +++ b/examples3d/debug_shape_modification3.rs @@ -1,6 +1,4 @@ -use na::{Isometry3, Point3, Vector3}; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet, SharedShape}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -17,30 +15,30 @@ pub fn init_world(testbed: &mut Testbed) { let ground_height = 0.1; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, -ground_height, 0.0) + .translation(vector![0.0, -ground_height, 0.0]) .build(); let ground_handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size) .friction(0.15) // .restitution(0.5) .build(); - colliders.insert(collider, ground_handle, &mut bodies); + colliders.insert_with_parent(collider, ground_handle, &mut bodies); /* * Rolling ball */ let ball_rad = 0.1; let rb = RigidBodyBuilder::new_dynamic() - .translation(0.0, 0.2, 0.0) - .linvel(10.0, 0.0, 0.0) + .translation(vector![0.0, 0.2, 0.0]) + .linvel(vector![10.0, 0.0, 0.0]) .build(); let ball_handle = bodies.insert(rb); let collider = ColliderBuilder::ball(ball_rad).density(100.0).build(); - let ball_coll_handle = colliders.insert(collider, ball_handle, &mut bodies); + let ball_coll_handle = colliders.insert_with_parent(collider, ball_handle, &mut bodies); - let mut linvel = Vector3::zeros(); - let mut angvel = Vector3::zeros(); - let mut pos = Isometry3::identity(); + let mut linvel = Vector::zeros(); + let mut angvel = Vector::zeros(); + let mut pos = Isometry::identity(); let mut step = 0; let snapped_frame = 51; @@ -90,7 +88,9 @@ pub fn init_world(testbed: &mut Testbed) { let z = k as f32 * shiftz - centerz + offset; // Build the rigid body. - let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y, z).build(); + let rigid_body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y, z]) + .build(); let handle = bodies.insert(rigid_body); let collider = match j % 5 { @@ -103,7 +103,7 @@ pub fn init_world(testbed: &mut Testbed) { _ => ColliderBuilder::capsule_y(rad, rad).build(), }; - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } } @@ -114,5 +114,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(10.0, 10.0, 10.0), Point3::origin()); + testbed.look_at(point![10.0, 10.0, 10.0], Point::origin()); } diff --git a/examples3d/debug_triangle3.rs b/examples3d/debug_triangle3.rs index 341f396..0c40882 100644 --- a/examples3d/debug_triangle3.rs +++ b/examples3d/debug_triangle3.rs @@ -1,6 +1,4 @@ -use na::Point3; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -13,31 +11,31 @@ pub fn init_world(testbed: &mut Testbed) { // Triangle ground. let vtx = [ - Point3::new(-10.0, 0.0, -10.0), - Point3::new(10.0, 0.0, -10.0), - Point3::new(0.0, 0.0, 10.0), + point![-10.0, 0.0, -10.0], + point![10.0, 0.0, -10.0], + point![0.0, 0.0, 10.0], ]; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, 0.0, 0.0) + .translation(vector![0.0, 0.0, 0.0]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::triangle(vtx[0], vtx[1], vtx[2]).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); // Dynamic box rigid body. let rigid_body = RigidBodyBuilder::new_dynamic() - .translation(1.1, 0.01, 0.0) + .translation(vector![1.1, 0.01, 0.0]) // .rotation(Vector3::new(0.8, 0.2, 0.1)) .can_sleep(false) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(20.0, 0.1, 1.0).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(10.0, 10.0, 10.0), Point3::origin()); + testbed.look_at(point![10.0, 10.0, 10.0], Point::origin()); } diff --git a/examples3d/debug_trimesh3.rs b/examples3d/debug_trimesh3.rs index 5a8ed4b..d21d0d3 100644 --- a/examples3d/debug_trimesh3.rs +++ b/examples3d/debug_trimesh3.rs @@ -1,6 +1,4 @@ -use na::Point3; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -14,14 +12,14 @@ pub fn init_world(testbed: &mut Testbed) { // Triangle ground. let width = 0.5; let vtx = vec![ - Point3::new(-width, 0.0, -width), - Point3::new(width, 0.0, -width), - Point3::new(width, 0.0, width), - Point3::new(-width, 0.0, width), - Point3::new(-width, -width, -width), - Point3::new(width, -width, -width), - Point3::new(width, -width, width), - Point3::new(-width, -width, width), + point![-width, 0.0, -width], + point![width, 0.0, -width], + point![width, 0.0, width], + point![-width, 0.0, width], + point![-width, -width, -width], + point![width, -width, -width], + point![width, -width, width], + point![-width, -width, width], ]; let idx = vec![ [0, 2, 1], @@ -40,25 +38,25 @@ pub fn init_world(testbed: &mut Testbed) { // Dynamic box rigid body. let rigid_body = RigidBodyBuilder::new_dynamic() - .translation(0.0, 35.0, 0.0) + .translation(vector![0.0, 35.0, 0.0]) // .rotation(Vector3::new(0.8, 0.2, 0.1)) .can_sleep(false) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(1.0, 2.0, 1.0).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, 0.0, 0.0) + .translation(vector![0.0, 0.0, 0.0]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::trimesh(vtx, idx).build(); - colliders.insert(collider, handle, &mut bodies); - testbed.set_initial_body_color(handle, Point3::new(0.3, 0.3, 0.3)); + colliders.insert_with_parent(collider, handle, &mut bodies); + testbed.set_initial_body_color(handle, [0.3, 0.3, 0.3]); /* * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(10.0, 10.0, 10.0), Point3::origin()); + testbed.look_at(point![10.0, 10.0, 10.0], Point::origin()); } diff --git a/examples3d/domino3.rs b/examples3d/domino3.rs index b619da5..7e9143f 100644 --- a/examples3d/domino3.rs +++ b/examples3d/domino3.rs @@ -1,6 +1,4 @@ -use na::{Point3, Translation3, UnitQuaternion, Vector3}; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -18,11 +16,11 @@ pub fn init_world(testbed: &mut Testbed) { let ground_height = 0.1; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, -ground_height, 0.0) + .translation(vector![0.0, -ground_height, 0.0]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * Create the cubes @@ -31,7 +29,7 @@ pub fn init_world(testbed: &mut Testbed) { let width = 1.0; let thickness = 0.1; - let colors = [Point3::new(0.7, 0.5, 0.9), Point3::new(0.6, 1.0, 0.6)]; + let colors = [[0.7, 0.5, 0.9], [0.6, 1.0, 0.6]]; let mut curr_angle = 0.0; let mut curr_rad = 10.0; @@ -50,16 +48,16 @@ pub fn init_world(testbed: &mut Testbed) { let tilt = if nudged || i == num - 1 { 0.2 } else { 0.0 }; if skip == 0 { - let rot = UnitQuaternion::new(Vector3::y() * curr_angle); - let tilt = UnitQuaternion::new(rot * Vector3::z() * tilt); + let rot = Rotation::new(Vector::y() * curr_angle); + let tilt = Rotation::new(rot * Vector::z() * tilt); let position = - Translation3::new(x * curr_rad, width * 2.0 + ground_height, z * curr_rad) + Translation::new(x * curr_rad, width * 2.0 + ground_height, z * curr_rad) * tilt * rot; let rigid_body = RigidBodyBuilder::new_dynamic().position(position).build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(thickness, width * 2.0, width).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); testbed.set_initial_body_color(handle, colors[i % 2]); } else { skip -= 1; @@ -76,5 +74,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(100.0, 100.0, 100.0), Point3::origin()); + testbed.look_at(point![100.0, 100.0, 100.0], Point::origin()); } diff --git a/examples3d/fountain3.rs b/examples3d/fountain3.rs index 0d228c7..788d05d 100644 --- a/examples3d/fountain3.rs +++ b/examples3d/fountain3.rs @@ -1,6 +1,4 @@ -use na::Point3; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; const MAX_NUMBER_OF_BODIES: usize = 400; @@ -18,16 +16,16 @@ pub fn init_world(testbed: &mut Testbed) { let ground_height = 2.1; // 16.0; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, -ground_height, 0.0) + .translation(vector![0.0, -ground_height, 0.0]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); // Callback that will be executed on the main loop to handle proximities. testbed.add_callback(move |mut graphics, physics, _, run_state| { let rigid_body = RigidBodyBuilder::new_dynamic() - .translation(0.0, 10.0, 0.0) + .translation(vector![0.0, 10.0, 0.0]) .build(); let handle = physics.bodies.insert(rigid_body); let collider = match run_state.timestep_id % 3 { @@ -38,7 +36,7 @@ pub fn init_world(testbed: &mut Testbed) { physics .colliders - .insert(collider, handle, &mut physics.bodies); + .insert_with_parent(collider, handle, &mut physics.bodies); if let Some(graphics) = &mut graphics { graphics.add_body(handle, &physics.bodies, &physics.colliders); @@ -83,5 +81,5 @@ pub fn init_world(testbed: &mut Testbed) { // .physics_state_mut() // .integration_parameters // .velocity_based_erp = 0.2; - testbed.look_at(Point3::new(-30.0, 4.0, -30.0), Point3::new(0.0, 1.0, 0.0)); + testbed.look_at(point![-30.0, 4.0, -30.0], point![0.0, 1.0, 0.0]); } diff --git a/examples3d/harness_capsules3.rs b/examples3d/harness_capsules3.rs index 4632811..e2f19d5 100644 --- a/examples3d/harness_capsules3.rs +++ b/examples3d/harness_capsules3.rs @@ -1,7 +1,4 @@ -extern crate nalgebra as na; - -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::harness::Harness; pub fn init_world(harness: &mut Harness) { @@ -19,11 +16,11 @@ pub fn init_world(harness: &mut Harness) { let ground_height = 0.1; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, -ground_height, 0.0) + .translation(vector![0.0, -ground_height, 0.0]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * Create the cubes @@ -47,10 +44,12 @@ pub fn init_world(harness: &mut Harness) { let z = k as f32 * shift - centerz + offset; // Build the rigid body. - let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y, z).build(); + let rigid_body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y, z]) + .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::capsule_y(rad, rad).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } } diff --git a/examples3d/heightfield3.rs b/examples3d/heightfield3.rs index 414ffdd..7f5979a 100644 --- a/examples3d/heightfield3.rs +++ b/examples3d/heightfield3.rs @@ -1,6 +1,5 @@ -use na::{ComplexField, DMatrix, Isometry3, Point3, Vector3}; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet, SharedShape}; +use na::ComplexField; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -14,7 +13,7 @@ pub fn init_world(testbed: &mut Testbed) { /* * Ground */ - let ground_size = Vector3::new(100.0, 1.0, 100.0); + let ground_size = Vector::new(100.0, 1.0, 100.0); let nsubdivs = 20; let heights = DMatrix::from_fn(nsubdivs + 1, nsubdivs + 1, |i, j| { @@ -34,7 +33,7 @@ pub fn init_world(testbed: &mut Testbed) { let rigid_body = RigidBodyBuilder::new_static().build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::heightfield(heights, ground_size).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * Create the cubes @@ -55,7 +54,9 @@ pub fn init_world(testbed: &mut Testbed) { let z = k as f32 * shift - centerz; // Build the rigid body. - let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y, z).build(); + let rigid_body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y, z]) + .build(); let handle = bodies.insert(rigid_body); let collider = match j % 6 { @@ -69,15 +70,15 @@ pub fn init_world(testbed: &mut Testbed) { _ => { let shapes = vec![ ( - Isometry3::identity(), + Isometry::identity(), SharedShape::cuboid(rad, rad / 2.0, rad / 2.0), ), ( - Isometry3::translation(rad, 0.0, 0.0), + Isometry::translation(rad, 0.0, 0.0), SharedShape::cuboid(rad / 2.0, rad, rad / 2.0), ), ( - Isometry3::translation(-rad, 0.0, 0.0), + Isometry::translation(-rad, 0.0, 0.0), SharedShape::cuboid(rad / 2.0, rad, rad / 2.0), ), ]; @@ -86,7 +87,7 @@ pub fn init_world(testbed: &mut Testbed) { } }; - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } } } @@ -95,5 +96,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(100.0, 100.0, 100.0), Point3::origin()); + testbed.look_at(point![100.0, 100.0, 100.0], Point::origin()); } diff --git a/examples3d/joints3.rs b/examples3d/joints3.rs index c7f8a1c..e22f293 100644 --- a/examples3d/joints3.rs +++ b/examples3d/joints3.rs @@ -1,49 +1,44 @@ -use na::{Isometry3, Point3, Unit, UnitQuaternion, Vector3}; -use rapier3d::dynamics::{ - BallJoint, FixedJoint, JointSet, PrismaticJoint, RevoluteJoint, RigidBodyBuilder, - RigidBodyHandle, RigidBodySet, RigidBodyType, -}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; fn create_prismatic_joints( bodies: &mut RigidBodySet, colliders: &mut ColliderSet, joints: &mut JointSet, - origin: Point3, + origin: Point, num: usize, ) { let rad = 0.4; let shift = 2.0; let ground = RigidBodyBuilder::new_static() - .translation(origin.x, origin.y, origin.z) + .translation(vector![origin.x, origin.y, origin.z]) .build(); let mut curr_parent = bodies.insert(ground); let collider = ColliderBuilder::cuboid(rad, rad, rad).build(); - colliders.insert(collider, curr_parent, bodies); + colliders.insert_with_parent(collider, curr_parent, bodies); for i in 0..num { let z = origin.z + (i + 1) as f32 * shift; let rigid_body = RigidBodyBuilder::new_dynamic() - .translation(origin.x, origin.y, z) + .translation(vector![origin.x, origin.y, z]) .build(); let curr_child = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(rad, rad, rad).build(); - colliders.insert(collider, curr_child, bodies); + colliders.insert_with_parent(collider, curr_child, bodies); let axis = if i % 2 == 0 { - Unit::new_normalize(Vector3::new(1.0, 1.0, 0.0)) + UnitVector::new_normalize(vector![1.0, 1.0, 0.0]) } else { - Unit::new_normalize(Vector3::new(-1.0, 1.0, 0.0)) + UnitVector::new_normalize(vector![-1.0, 1.0, 0.0]) }; - let z = Vector3::z(); + let z = Vector::z(); let mut prism = PrismaticJoint::new( - Point3::new(0.0, 0.0, 0.0), + point![0.0, 0.0, 0.0], axis, z, - Point3::new(0.0, 0.0, -shift), + point![0.0, 0.0, -shift], axis, z, ); @@ -61,40 +56,40 @@ fn create_actuated_prismatic_joints( bodies: &mut RigidBodySet, colliders: &mut ColliderSet, joints: &mut JointSet, - origin: Point3, + origin: Point, num: usize, ) { let rad = 0.4; let shift = 2.0; let ground = RigidBodyBuilder::new_static() - .translation(origin.x, origin.y, origin.z) + .translation(vector![origin.x, origin.y, origin.z]) .build(); let mut curr_parent = bodies.insert(ground); let collider = ColliderBuilder::cuboid(rad, rad, rad).build(); - colliders.insert(collider, curr_parent, bodies); + colliders.insert_with_parent(collider, curr_parent, bodies); for i in 0..num { let z = origin.z + (i + 1) as f32 * shift; let rigid_body = RigidBodyBuilder::new_dynamic() - .translation(origin.x, origin.y, z) + .translation(vector![origin.x, origin.y, z]) .build(); let curr_child = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(rad, rad, rad).build(); - colliders.insert(collider, curr_child, bodies); + colliders.insert_with_parent(collider, curr_child, bodies); let axis = if i % 2 == 0 { - Unit::new_normalize(Vector3::new(1.0, 1.0, 0.0)) + UnitVector::new_normalize(vector![1.0, 1.0, 0.0]) } else { - Unit::new_normalize(Vector3::new(-1.0, 1.0, 0.0)) + UnitVector::new_normalize(vector![-1.0, 1.0, 0.0]) }; - let z = Vector3::z(); + let z = Vector::z(); let mut prism = PrismaticJoint::new( - Point3::new(0.0, 0.0, 0.0), + point![0.0, 0.0, 0.0], axis, z, - Point3::new(0.0, 0.0, -shift), + point![0.0, 0.0, -shift], axis, z, ); @@ -128,27 +123,27 @@ fn create_revolute_joints( bodies: &mut RigidBodySet, colliders: &mut ColliderSet, joints: &mut JointSet, - origin: Point3, + origin: Point, num: usize, ) { let rad = 0.4; let shift = 2.0; let ground = RigidBodyBuilder::new_static() - .translation(origin.x, origin.y, 0.0) + .translation(vector![origin.x, origin.y, 0.0]) .build(); let mut curr_parent = bodies.insert(ground); let collider = ColliderBuilder::cuboid(rad, rad, rad).build(); - colliders.insert(collider, curr_parent, bodies); + colliders.insert_with_parent(collider, curr_parent, bodies); for i in 0..num { // Create four bodies. let z = origin.z + i as f32 * shift * 2.0 + shift; let positions = [ - Isometry3::translation(origin.x, origin.y, z), - Isometry3::translation(origin.x + shift, origin.y, z), - Isometry3::translation(origin.x + shift, origin.y, z + shift), - Isometry3::translation(origin.x, origin.y, z + shift), + Isometry::translation(origin.x, origin.y, z), + Isometry::translation(origin.x + shift, origin.y, z), + Isometry::translation(origin.x + shift, origin.y, z + shift), + Isometry::translation(origin.x, origin.y, z + shift), ]; let mut handles = [curr_parent; 4]; @@ -158,19 +153,19 @@ fn create_revolute_joints( .build(); handles[k] = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(rad, rad, rad).build(); - colliders.insert(collider, handles[k], bodies); + colliders.insert_with_parent(collider, handles[k], bodies); } // Setup four joints. - let o = Point3::origin(); - let x = Vector3::x_axis(); - let z = Vector3::z_axis(); + let o = Point::origin(); + let x = Vector::x_axis(); + let z = Vector::z_axis(); let revs = [ - RevoluteJoint::new(o, z, Point3::new(0.0, 0.0, -shift), z), - RevoluteJoint::new(o, x, Point3::new(-shift, 0.0, 0.0), x), - RevoluteJoint::new(o, z, Point3::new(0.0, 0.0, -shift), z), - RevoluteJoint::new(o, x, Point3::new(shift, 0.0, 0.0), x), + RevoluteJoint::new(o, z, point![0.0, 0.0, -shift], z), + RevoluteJoint::new(o, x, point![-shift, 0.0, 0.0], x), + RevoluteJoint::new(o, z, point![0.0, 0.0, -shift], z), + RevoluteJoint::new(o, x, point![shift, 0.0, 0.0], x), ]; joints.insert(bodies, curr_parent, handles[0], revs[0]); @@ -186,7 +181,7 @@ fn create_fixed_joints( bodies: &mut RigidBodySet, colliders: &mut ColliderSet, joints: &mut JointSet, - origin: Point3, + origin: Point, num: usize, ) { let rad = 0.4; @@ -209,18 +204,22 @@ fn create_fixed_joints( }; let rigid_body = RigidBodyBuilder::new(status) - .translation(origin.x + fk * shift, origin.y, origin.z + fi * shift) + .translation(vector![ + origin.x + fk * shift, + origin.y, + origin.z + fi * shift + ]) .build(); let child_handle = bodies.insert(rigid_body); let collider = ColliderBuilder::ball(rad).build(); - colliders.insert(collider, child_handle, bodies); + colliders.insert_with_parent(collider, child_handle, bodies); // Vertical joint. if i > 0 { let parent_handle = *body_handles.last().unwrap(); let joint = FixedJoint::new( - Isometry3::identity(), - Isometry3::translation(0.0, 0.0, -shift), + Isometry::identity(), + Isometry::translation(0.0, 0.0, -shift), ); joints.insert(bodies, parent_handle, child_handle, joint); } @@ -230,8 +229,8 @@ fn create_fixed_joints( let parent_index = body_handles.len() - num; let parent_handle = body_handles[parent_index]; let joint = FixedJoint::new( - Isometry3::identity(), - Isometry3::translation(-shift, 0.0, 0.0), + Isometry::identity(), + Isometry::translation(-shift, 0.0, 0.0), ); joints.insert(bodies, parent_handle, child_handle, joint); } @@ -264,16 +263,16 @@ fn create_ball_joints( }; let rigid_body = RigidBodyBuilder::new(status) - .translation(fk * shift, 0.0, fi * shift * 2.0) + .translation(vector![fk * shift, 0.0, fi * shift * 2.0]) .build(); let child_handle = bodies.insert(rigid_body); let collider = ColliderBuilder::capsule_z(rad * 1.25, rad).build(); - colliders.insert(collider, child_handle, bodies); + colliders.insert_with_parent(collider, child_handle, bodies); // Vertical joint. if i > 0 { let parent_handle = *body_handles.last().unwrap(); - let joint = BallJoint::new(Point3::origin(), Point3::new(0.0, 0.0, -shift * 2.0)); + let joint = BallJoint::new(Point::origin(), point![0.0, 0.0, -shift * 2.0]); joints.insert(bodies, parent_handle, child_handle, joint); } @@ -281,7 +280,7 @@ fn create_ball_joints( if k > 0 { let parent_index = body_handles.len() - num; let parent_handle = body_handles[parent_index]; - let joint = BallJoint::new(Point3::origin(), Point3::new(-shift, 0.0, 0.0)); + let joint = BallJoint::new(Point::origin(), point![-shift, 0.0, 0.0]); joints.insert(bodies, parent_handle, child_handle, joint); } @@ -294,7 +293,7 @@ fn create_actuated_revolute_joints( bodies: &mut RigidBodySet, colliders: &mut ColliderSet, joints: &mut JointSet, - origin: Point3, + origin: Point, num: usize, ) { let rad = 0.4; @@ -302,10 +301,10 @@ fn create_actuated_revolute_joints( // We will reuse this base configuration for all the joints here. let joint_template = RevoluteJoint::new( - Point3::origin(), - Vector3::z_axis(), - Point3::new(0.0, 0.0, -shift), - Vector3::z_axis(), + Point::origin(), + Vector::z_axis(), + point![0.0, 0.0, -shift], + Vector::z_axis(), ); let mut parent_handle = RigidBodyHandle::invalid(); @@ -325,13 +324,13 @@ fn create_actuated_revolute_joints( let shifty = (i >= 1) as u32 as f32 * -2.0; let rigid_body = RigidBodyBuilder::new(status) - .translation(origin.x, origin.y + shifty, origin.z + fi * shift) + .translation(vector![origin.x, origin.y + shifty, origin.z + fi * shift]) // .rotation(Vector3::new(0.0, fi * 1.1, 0.0)) .build(); let child_handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(rad * 2.0, rad * 6.0 / (fi + 1.0), rad).build(); - colliders.insert(collider, child_handle, bodies); + colliders.insert_with_parent(collider, child_handle, bodies); if i > 0 { let mut joint = joint_template.clone(); @@ -360,14 +359,14 @@ fn create_actuated_ball_joints( bodies: &mut RigidBodySet, colliders: &mut ColliderSet, joints: &mut JointSet, - origin: Point3, + origin: Point, num: usize, ) { let rad = 0.4; let shift = 2.0; // We will reuse this base configuration for all the joints here. - let joint_template = BallJoint::new(Point3::new(0.0, 0.0, shift), Point3::origin()); + let joint_template = BallJoint::new(point![0.0, 0.0, shift], Point::origin()); let mut parent_handle = RigidBodyHandle::invalid(); @@ -384,24 +383,24 @@ fn create_actuated_ball_joints( }; let rigid_body = RigidBodyBuilder::new(status) - .translation(origin.x, origin.y, origin.z + fi * shift) + .translation(vector![origin.x, origin.y, origin.z + fi * shift]) // .rotation(Vector3::new(0.0, fi * 1.1, 0.0)) .build(); let child_handle = bodies.insert(rigid_body); let collider = ColliderBuilder::capsule_y(rad * 2.0 / (fi + 1.0), rad).build(); - colliders.insert(collider, child_handle, bodies); + colliders.insert_with_parent(collider, child_handle, bodies); if i > 0 { let mut joint = joint_template.clone(); if i == 1 { - joint.configure_motor_velocity(Vector3::new(0.0, 0.5, -2.0), 0.1); + joint.configure_motor_velocity(vector![0.0, 0.5, -2.0], 0.1); } else if i == num - 1 { let stiffness = 0.2; let damping = 1.0; joint.configure_motor_position( - UnitQuaternion::new(Vector3::new(0.0, 1.0, 3.14 / 2.0)), + Rotation::new(vector![0.0, 1.0, 3.14 / 2.0]), stiffness, damping, ); @@ -426,42 +425,42 @@ pub fn init_world(testbed: &mut Testbed) { &mut bodies, &mut colliders, &mut joints, - Point3::new(20.0, 5.0, 0.0), + point![20.0, 5.0, 0.0], 4, ); create_actuated_prismatic_joints( &mut bodies, &mut colliders, &mut joints, - Point3::new(25.0, 5.0, 0.0), + point![25.0, 5.0, 0.0], 4, ); create_revolute_joints( &mut bodies, &mut colliders, &mut joints, - Point3::new(20.0, 0.0, 0.0), + point![20.0, 0.0, 0.0], 3, ); create_fixed_joints( &mut bodies, &mut colliders, &mut joints, - Point3::new(0.0, 10.0, 0.0), + point![0.0, 10.0, 0.0], 10, ); create_actuated_revolute_joints( &mut bodies, &mut colliders, &mut joints, - Point3::new(20.0, 10.0, 0.0), + point![20.0, 10.0, 0.0], 6, ); create_actuated_ball_joints( &mut bodies, &mut colliders, &mut joints, - Point3::new(13.0, 10.0, 0.0), + point![13.0, 10.0, 0.0], 3, ); create_ball_joints(&mut bodies, &mut colliders, &mut joints, 15); @@ -470,5 +469,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(15.0, 5.0, 42.0), Point3::new(13.0, 1.0, 1.0)); + testbed.look_at(point![15.0, 5.0, 42.0], point![13.0, 1.0, 1.0]); } diff --git a/examples3d/keva3.rs b/examples3d/keva3.rs index 9e6807a..38a0432 100644 --- a/examples3d/keva3.rs +++ b/examples3d/keva3.rs @@ -1,14 +1,12 @@ -use na::{Point3, Vector3}; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; pub fn build_block( testbed: &mut Testbed, bodies: &mut RigidBodySet, colliders: &mut ColliderSet, - half_extents: Vector3, - shift: Vector3, + half_extents: Vector, + shift: Vector, mut numx: usize, numy: usize, mut numz: usize, @@ -17,8 +15,8 @@ pub fn build_block( let block_width = 2.0 * half_extents.z * numx as f32; let block_height = 2.0 * half_extents.y * numy as f32; let spacing = (half_extents.z * numx as f32 - half_extents.x) / (numz as f32 - 1.0); - let mut color0 = Point3::new(0.7, 0.5, 0.9); - let mut color1 = Point3::new(0.6, 1.0, 0.6); + let mut color0 = [0.7, 0.5, 0.9]; + let mut color1 = [0.6, 1.0, 0.6]; for i in 0..numy { std::mem::swap(&mut numx, &mut numz); @@ -41,15 +39,15 @@ pub fn build_block( // Build the rigid body. let rigid_body = RigidBodyBuilder::new_dynamic() - .translation( + .translation(vector![ x + dim.x + shift.x, y + dim.y + shift.y, - z + dim.z + shift.z, - ) + z + dim.z + shift.z + ]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(dim.x, dim.y, dim.z).build(); - colliders.insert(collider, handle, bodies); + colliders.insert_with_parent(collider, handle, bodies); testbed.set_initial_body_color(handle, color0); std::mem::swap(&mut color0, &mut color1); @@ -64,15 +62,15 @@ pub fn build_block( for j in 0..(block_width / (dim.z as f32 * 2.0)) as usize { // Build the rigid body. let rigid_body = RigidBodyBuilder::new_dynamic() - .translation( + .translation(vector![ i as f32 * dim.x * 2.0 + dim.x + shift.x, dim.y + shift.y + block_height, - j as f32 * dim.z * 2.0 + dim.z + shift.z, - ) + j as f32 * dim.z * 2.0 + dim.z + shift.z + ]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(dim.x, dim.y, dim.z).build(); - colliders.insert(collider, handle, bodies); + colliders.insert_with_parent(collider, handle, bodies); testbed.set_initial_body_color(handle, color0); std::mem::swap(&mut color0, &mut color1); } @@ -94,16 +92,16 @@ pub fn init_world(testbed: &mut Testbed) { let ground_height = 0.1; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, -ground_height, 0.0) + .translation(vector![0.0, -ground_height, 0.0]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * Create the cubes */ - let half_extents = Vector3::new(0.02, 0.1, 0.4) / 2.0 * 10.0; + let half_extents = vector![0.02, 0.1, 0.4] / 2.0 * 10.0; let mut block_height = 0.0; // These should only be set to odd values otherwise // the blocks won't align in the nicest way. @@ -120,7 +118,7 @@ pub fn init_world(testbed: &mut Testbed) { &mut bodies, &mut colliders, half_extents, - Vector3::new(-block_width / 2.0, block_height, -block_width / 2.0), + vector![-block_width / 2.0, block_height, -block_width / 2.0], numx, numy, numz, @@ -135,5 +133,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(100.0, 100.0, 100.0), Point3::origin()); + testbed.look_at(point![100.0, 100.0, 100.0], Point::origin()); } diff --git a/examples3d/locked_rotations3.rs b/examples3d/locked_rotations3.rs index 9748c17..95dfae1 100644 --- a/examples3d/locked_rotations3.rs +++ b/examples3d/locked_rotations3.rs @@ -1,6 +1,4 @@ -use na::{Point3, Vector3}; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; // This shows a bug when a cylinder is in contact with a very large @@ -21,41 +19,41 @@ pub fn init_world(testbed: &mut Testbed) { let ground_height = 0.1; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, -ground_height, 0.0) + .translation(vector![0.0, -ground_height, 0.0]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * A rectangle that only rotates along the `x` axis. */ let rigid_body = RigidBodyBuilder::new_dynamic() - .translation(0.0, 3.0, 0.0) + .translation(vector![0.0, 3.0, 0.0]) .lock_translations() .restrict_rotations(true, false, false) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(0.2, 0.6, 2.0).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * A tilted capsule that cannot rotate. */ let rigid_body = RigidBodyBuilder::new_dynamic() - .translation(0.0, 5.0, 0.0) - .rotation(Vector3::x() * 1.0) + .translation(vector![0.0, 5.0, 0.0]) + .rotation(Vector::x() * 1.0) .lock_rotations() .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::capsule_y(0.6, 0.4).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); let collider = ColliderBuilder::capsule_x(0.6, 0.4).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(10.0, 3.0, 0.0), Point3::new(0.0, 3.0, 0.0)); + testbed.look_at(point![10.0, 3.0, 0.0], point![0.0, 3.0, 0.0]); } diff --git a/examples3d/one_way_platforms3.rs b/examples3d/one_way_platforms3.rs index 7933f78..3802563 100644 --- a/examples3d/one_way_platforms3.rs +++ b/examples3d/one_way_platforms3.rs @@ -1,7 +1,4 @@ -use na::{Point3, Vector3}; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderHandle, ColliderSet}; -use rapier3d::pipeline::{ContactModificationContext, PhysicsHooks, PhysicsHooksFlags}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; struct OneWayPlatformHook { @@ -10,10 +7,6 @@ struct OneWayPlatformHook { } impl PhysicsHooks for OneWayPlatformHook { - fn active_hooks(&self) -> PhysicsHooksFlags { - PhysicsHooksFlags::MODIFY_SOLVER_CONTACTS - } - fn modify_solver_contacts( &self, context: &mut ContactModificationContext, @@ -30,20 +23,20 @@ impl PhysicsHooks for OneWayPlatformHook { // - If context.collider2 == self.platform1 then the allowed normal is -y. // - If context.collider1 == self.platform2 then its allowed normal +y needs to be flipped to -y. // - If context.collider2 == self.platform2 then the allowed normal -y needs to be flipped to +y. - let mut allowed_local_n1 = Vector3::zeros(); + let mut allowed_local_n1 = Vector::zeros(); if context.collider1 == self.platform1 { - allowed_local_n1 = Vector3::y(); + allowed_local_n1 = Vector::y(); } else if context.collider2 == self.platform1 { // Flip the allowed direction. - allowed_local_n1 = -Vector3::y(); + allowed_local_n1 = -Vector::y(); } if context.collider1 == self.platform2 { - allowed_local_n1 = -Vector3::y(); + allowed_local_n1 = -Vector::y(); } else if context.collider2 == self.platform2 { // Flip the allowed direction. - allowed_local_n1 = Vector3::y(); + allowed_local_n1 = Vector::y(); } // Call the helper function that simulates one-way platforms. @@ -78,15 +71,15 @@ pub fn init_world(testbed: &mut Testbed) { let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(9.0, 0.5, 25.0) - .translation(0.0, 2.0, 30.0) - .modify_solver_contacts(true) + .translation(vector![0.0, 2.0, 30.0]) + .active_hooks(ActiveHooks::MODIFY_SOLVER_CONTACTS) .build(); - let platform1 = colliders.insert(collider, handle, &mut bodies); + let platform1 = colliders.insert_with_parent(collider, handle, &mut bodies); let collider = ColliderBuilder::cuboid(9.0, 0.5, 25.0) - .translation(0.0, -2.0, -30.0) - .modify_solver_contacts(true) + .translation(vector![0.0, -2.0, -30.0]) + .active_hooks(ActiveHooks::MODIFY_SOLVER_CONTACTS) .build(); - let platform2 = colliders.insert(collider, handle, &mut bodies); + let platform2 = colliders.insert_with_parent(collider, handle, &mut bodies); /* * Setup the one-way platform hook. @@ -105,12 +98,12 @@ pub fn init_world(testbed: &mut Testbed) { // Spawn a new cube. let collider = ColliderBuilder::cuboid(1.0, 2.0, 1.5).build(); let body = RigidBodyBuilder::new_dynamic() - .translation(0.0, 6.0, 20.0) + .translation(vector![0.0, 6.0, 20.0]) .build(); let handle = physics.bodies.insert(body); physics .colliders - .insert(collider, handle, &mut physics.bodies); + .insert_with_parent(collider, handle, &mut physics.bodies); if let Some(graphics) = graphics { graphics.add_body(handle, &physics.bodies, &physics.colliders); @@ -134,8 +127,8 @@ pub fn init_world(testbed: &mut Testbed) { bodies, colliders, joints, - Vector3::new(0.0, -9.81, 0.0), + vector![0.0, -9.81, 0.0], physics_hooks, ); - testbed.look_at(Point3::new(-100.0, 0.0, 0.0), Point3::origin()); + testbed.look_at(point![-100.0, 0.0, 0.0], Point::origin()); } diff --git a/examples3d/platform3.rs b/examples3d/platform3.rs index 786ddbf..6b3c234 100644 --- a/examples3d/platform3.rs +++ b/examples3d/platform3.rs @@ -1,6 +1,4 @@ -use na::Point3; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -18,11 +16,11 @@ pub fn init_world(testbed: &mut Testbed) { let ground_height = 0.1; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, -ground_height, 0.0) + .translation(vector![0.0, -ground_height, 0.0]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * Create the boxes @@ -43,23 +41,35 @@ pub fn init_world(testbed: &mut Testbed) { let z = k as f32 * shift - centerz; // Build the rigid body. - let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y, z).build(); + let rigid_body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y, z]) + .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(rad, rad, rad).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } } } /* - * Setup a kinematic rigid body. + * Setup a velocity-based kinematic rigid body. */ - let platform_body = RigidBodyBuilder::new_kinematic() - .translation(0.0, 1.5 + 0.8, -10.0 * rad) + let platform_body = RigidBodyBuilder::new_kinematic_velocity_based() + .translation(vector![0.0, 1.5 + 0.8, -10.0 * rad]) .build(); - let platform_handle = bodies.insert(platform_body); + let velocity_based_platform_handle = bodies.insert(platform_body); let collider = ColliderBuilder::cuboid(rad * 10.0, rad, rad * 10.0).build(); - colliders.insert(collider, platform_handle, &mut bodies); + colliders.insert_with_parent(collider, velocity_based_platform_handle, &mut bodies); + + /* + * Setup a position-based kinematic rigid body. + */ + let platform_body = RigidBodyBuilder::new_kinematic_position_based() + .translation(vector![0.0, 2.0 + 1.5 + 0.8, -10.0 * rad]) + .build(); + let position_based_platform_handle = bodies.insert(platform_body); + let collider = ColliderBuilder::cuboid(rad * 10.0, rad, rad * 10.0).build(); + colliders.insert_with_parent(collider, position_based_platform_handle, &mut bodies); /* * Setup a callback to control the platform. @@ -71,21 +81,22 @@ pub fn init_world(testbed: &mut Testbed) { return; } - if let Some(platform) = physics.bodies.get_mut(platform_handle) { - let mut next_pos = *platform.position(); + let velocity = vector![ + 0.0, + (run_state.time * 5.0).sin(), + run_state.time.sin() * 5.0 + ]; - let dt = 0.016; - next_pos.translation.vector.y += (run_state.time * 5.0).sin() * dt; - next_pos.translation.vector.z += run_state.time.sin() * 5.0 * dt; + // Update the velocity-based kinematic body by setting its velocity. + if let Some(platform) = physics.bodies.get_mut(velocity_based_platform_handle) { + platform.set_linvel(velocity, true); + } - if next_pos.translation.vector.z >= rad * 10.0 { - next_pos.translation.vector.z -= dt; - } - if next_pos.translation.vector.z <= -rad * 10.0 { - next_pos.translation.vector.z += dt; - } - - platform.set_next_kinematic_position(next_pos); + // Update the position-based kinematic body by setting its next position. + if let Some(platform) = physics.bodies.get_mut(position_based_platform_handle) { + let mut next_tra = *platform.translation(); + next_tra += velocity * physics.integration_parameters.dt; + platform.set_next_kinematic_translation(next_tra); } }); @@ -93,5 +104,5 @@ pub fn init_world(testbed: &mut Testbed) { * Run the simulation. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(-10.0, 5.0, -10.0), Point3::origin()); + testbed.look_at(point![-10.0, 5.0, -10.0], Point::origin()); } diff --git a/examples3d/primitives3.rs b/examples3d/primitives3.rs index afa5dfd..db9143b 100644 --- a/examples3d/primitives3.rs +++ b/examples3d/primitives3.rs @@ -1,6 +1,4 @@ -use na::Point3; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -18,11 +16,11 @@ pub fn init_world(testbed: &mut Testbed) { let ground_height = 2.1; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, -ground_height, 0.0) + .translation(vector![0.0, -ground_height, 0.0]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * Create the primitives @@ -47,7 +45,9 @@ pub fn init_world(testbed: &mut Testbed) { let z = k as f32 * shiftz - centerz + offset; // Build the rigid body. - let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y, z).build(); + let rigid_body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y, z]) + .build(); let handle = bodies.insert(rigid_body); let collider = match j % 5 { @@ -60,7 +60,7 @@ pub fn init_world(testbed: &mut Testbed) { _ => ColliderBuilder::capsule_y(rad, rad).build(), }; - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } } @@ -71,5 +71,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(100.0, 100.0, 100.0), Point3::origin()); + testbed.look_at(point![100.0, 100.0, 100.0], Point::origin()); } diff --git a/examples3d/restitution3.rs b/examples3d/restitution3.rs index 8fa3275..4c08742 100644 --- a/examples3d/restitution3.rs +++ b/examples3d/restitution3.rs @@ -1,6 +1,4 @@ -use na::Point3; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -18,13 +16,13 @@ pub fn init_world(testbed: &mut Testbed) { let ground_height = 1.0; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, -ground_height, 0.0) + .translation(vector![0.0, -ground_height, 0.0]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_height, 2.0) .restitution(1.0) .build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); let num = 10; let rad = 0.5; @@ -33,13 +31,13 @@ pub fn init_world(testbed: &mut Testbed) { for i in 0..=num { let x = (i as f32) - num as f32 / 2.0; let rigid_body = RigidBodyBuilder::new_dynamic() - .translation(x * 2.0, 10.0 * (j as f32 + 1.0), 0.0) + .translation(vector![x * 2.0, 10.0 * (j as f32 + 1.0), 0.0]) .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::ball(rad) .restitution((i as f32) / (num as f32)) .build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } } @@ -47,5 +45,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(0.0, 3.0, 30.0), Point3::new(0.0, 3.0, 0.0)); + testbed.look_at(point![0.0, 3.0, 30.0], point![0.0, 3.0, 0.0]); } diff --git a/examples3d/sensor3.rs b/examples3d/sensor3.rs index e55bf72..0e2b489 100644 --- a/examples3d/sensor3.rs +++ b/examples3d/sensor3.rs @@ -1,6 +1,4 @@ -use na::Point3; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -18,11 +16,11 @@ pub fn init_world(testbed: &mut Testbed) { let ground_height = 0.1; let rigid_body = RigidBodyBuilder::new_static() - .translation(0.0, -ground_height, 0.0) + .translation(vector![0.0, -ground_height, 0.0]) .build(); let ground_handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size).build(); - colliders.insert(collider, ground_handle, &mut bodies); + colliders.insert_with_parent(collider, ground_handle, &mut bodies); /* * Create some boxes. @@ -41,12 +39,14 @@ pub fn init_world(testbed: &mut Testbed) { let z = k as f32 * shift - centerz; // Build the rigid body. - let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y, z).build(); + let rigid_body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y, z]) + .build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::cuboid(rad, rad, rad).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); - testbed.set_initial_body_color(handle, Point3::new(0.5, 0.5, 1.0)); + testbed.set_initial_body_color(handle, [0.5, 0.5, 1.0]); } } @@ -56,33 +56,37 @@ pub fn init_world(testbed: &mut Testbed) { // Rigid body so that the sensor can move. let sensor = RigidBodyBuilder::new_dynamic() - .translation(0.0, 5.0, 0.0) + .translation(vector![0.0, 5.0, 0.0]) .build(); let sensor_handle = bodies.insert(sensor); // Solid cube attached to the sensor which // other colliders can touch. let collider = ColliderBuilder::cuboid(rad, rad, rad).build(); - colliders.insert(collider, sensor_handle, &mut bodies); + colliders.insert_with_parent(collider, sensor_handle, &mut bodies); // We create a collider desc without density because we don't // want it to contribute to the rigid body mass. - let sensor_collider = ColliderBuilder::ball(rad * 5.0).sensor(true).build(); - colliders.insert(sensor_collider, sensor_handle, &mut bodies); + let sensor_collider = ColliderBuilder::ball(rad * 5.0) + .density(0.0) + .sensor(true) + .active_events(ActiveEvents::INTERSECTION_EVENTS) + .build(); + colliders.insert_with_parent(sensor_collider, sensor_handle, &mut bodies); - testbed.set_initial_body_color(sensor_handle, Point3::new(0.5, 1.0, 1.0)); + testbed.set_initial_body_color(sensor_handle, [0.5, 1.0, 1.0]); // Callback that will be executed on the main loop to handle proximities. testbed.add_callback(move |mut graphics, physics, events, _| { while let Ok(prox) = events.intersection_events.try_recv() { let color = if prox.intersecting { - Point3::new(1.0, 1.0, 0.0) + [1.0, 1.0, 0.0] } else { - Point3::new(0.5, 0.5, 1.0) + [0.5, 0.5, 1.0] }; - let parent_handle1 = physics.colliders.get(prox.collider1).unwrap().parent(); - let parent_handle2 = physics.colliders.get(prox.collider2).unwrap().parent(); + let parent_handle1 = physics.colliders[prox.collider1].parent().unwrap(); + let parent_handle2 = physics.colliders[prox.collider2].parent().unwrap(); if let Some(graphics) = &mut graphics { if parent_handle1 != ground_handle && parent_handle1 != sensor_handle { @@ -99,5 +103,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(-6.0, 4.0, -6.0), Point3::new(0.0, 1.0, 0.0)); + testbed.look_at(point![-6.0, 4.0, -6.0], point![0.0, 1.0, 0.0]); } diff --git a/examples3d/trimesh3.rs b/examples3d/trimesh3.rs index 2a4bd24..23e4090 100644 --- a/examples3d/trimesh3.rs +++ b/examples3d/trimesh3.rs @@ -1,6 +1,5 @@ -use na::{ComplexField, DMatrix, Isometry3, Point3, Vector3}; -use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; -use rapier3d::geometry::{ColliderBuilder, ColliderSet, HeightField, SharedShape}; +use na::ComplexField; +use rapier3d::prelude::*; use rapier_testbed3d::Testbed; pub fn init_world(testbed: &mut Testbed) { @@ -14,7 +13,7 @@ pub fn init_world(testbed: &mut Testbed) { /* * Ground */ - let ground_size = Vector3::new(100.0, 1.0, 100.0); + let ground_size = vector![100.0, 1.0, 100.0]; let nsubdivs = 20; let heights = DMatrix::from_fn(nsubdivs + 1, nsubdivs + 1, |i, j| { @@ -39,7 +38,7 @@ pub fn init_world(testbed: &mut Testbed) { let rigid_body = RigidBodyBuilder::new_static().build(); let handle = bodies.insert(rigid_body); let collider = ColliderBuilder::trimesh(vertices, indices).build(); - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); /* * Create the cubes @@ -60,7 +59,9 @@ pub fn init_world(testbed: &mut Testbed) { let z = k as f32 * shift - centerz; // Build the rigid body. - let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y, z).build(); + let rigid_body = RigidBodyBuilder::new_dynamic() + .translation(vector![x, y, z]) + .build(); let handle = bodies.insert(rigid_body); let collider = match j % 6 { @@ -74,15 +75,15 @@ pub fn init_world(testbed: &mut Testbed) { _ => { let shapes = vec![ ( - Isometry3::identity(), + Isometry::identity(), SharedShape::cuboid(rad, rad / 2.0, rad / 2.0), ), ( - Isometry3::translation(rad, 0.0, 0.0), + Isometry::translation(rad, 0.0, 0.0), SharedShape::cuboid(rad / 2.0, rad, rad / 2.0), ), ( - Isometry3::translation(-rad, 0.0, 0.0), + Isometry::translation(-rad, 0.0, 0.0), SharedShape::cuboid(rad / 2.0, rad, rad / 2.0), ), ]; @@ -91,7 +92,7 @@ pub fn init_world(testbed: &mut Testbed) { } }; - colliders.insert(collider, handle, &mut bodies); + colliders.insert_with_parent(collider, handle, &mut bodies); } } } @@ -100,5 +101,5 @@ pub fn init_world(testbed: &mut Testbed) { * Set up the testbed. */ testbed.set_world(bodies, colliders, joints); - testbed.look_at(Point3::new(100.0, 100.0, 100.0), Point3::origin()); + testbed.look_at(point![100.0, 100.0, 100.0], Point::origin()); } diff --git a/publish.sh b/publish.sh new file mode 100755 index 0000000..9431d3e --- /dev/null +++ b/publish.sh @@ -0,0 +1,35 @@ +#! /bin/bash + +tmp=$(mktemp -d) + +echo "$tmp" + +cp -r src "$tmp"/. +cp -r LICENSE README.md "$tmp"/. + +### Publish the 2D version. +sed 's#\.\./\.\./src#src#g' build/rapier2d/Cargo.toml > "$tmp"/Cargo.toml +currdir=$(pwd) +cd "$tmp" && cargo publish +cd "$currdir" || exit + + +### Publish the 3D version. +sed 's#\.\./\.\./src#src#g' build/rapier3d/Cargo.toml > "$tmp"/Cargo.toml +cp -r LICENSE README.md "$tmp"/. +cd "$tmp" && cargo publish +cd "$currdir" || exit + +### Publish the 2D f64 version. +sed 's#\.\./\.\./src#src#g' build/rapier2d-f64/Cargo.toml > "$tmp"/Cargo.toml +currdir=$(pwd) +cd "$tmp" && cargo publish +cd "$currdir" || exit + + +### Publish the 3D f64 version. +sed 's#\.\./\.\./src#src#g' build/rapier3d-f64/Cargo.toml > "$tmp"/Cargo.toml +cp -r LICENSE README.md "$tmp"/. +cd "$tmp" && cargo publish + +rm -rf "$tmp" diff --git a/src/data/coarena.rs b/src/data/coarena.rs index cd64910..ac6e43f 100644 --- a/src/data/coarena.rs +++ b/src/data/coarena.rs @@ -13,6 +13,14 @@ impl Coarena { Self { data: Vec::new() } } + /// Gets a specific element from the coarena without specifying its generation number. + /// + /// It is strongly encouraged to use `Coarena::get` instead of this method because this method + /// can suffer from the ABA problem. + pub fn get_unknown_gen(&self, index: u32) -> Option<&T> { + self.data.get(index as usize).map(|(_, t)| t) + } + /// Gets a specific element from the coarena, if it exists. pub fn get(&self, index: Index) -> Option<&T> { let (i, g) = index.into_raw_parts(); diff --git a/src/dynamics/ccd/ccd_solver.rs b/src/dynamics/ccd/ccd_solver.rs index b348283..7e95f08 100644 --- a/src/dynamics/ccd/ccd_solver.rs +++ b/src/dynamics/ccd/ccd_solver.rs @@ -10,6 +10,7 @@ use crate::geometry::{ use crate::math::Real; use crate::parry::utils::SortedPair; use crate::pipeline::{EventHandler, QueryPipeline, QueryPipelineMode}; +use crate::prelude::{ActiveEvents, ColliderFlags}; use parry::query::{DefaultQueryDispatcher, QueryDispatcher}; use parry::utils::hashmap::HashMap; use std::collections::BinaryHeap; @@ -66,7 +67,7 @@ impl CCDSolver { &RigidBodyCcd, &RigidBodyMassProps, ) = bodies.index_bundle(handle.0); - let local_com = &mprops.mass_properties.local_com; + let local_com = &mprops.local_mprops.local_com; let min_toi = (ccd.ccd_thickness * 0.15 @@ -139,7 +140,8 @@ impl CCDSolver { Colliders: ComponentSetOption + ComponentSet + ComponentSet - + ComponentSet, + + ComponentSet + + ComponentSet, { // Update the query pipeline. self.query_pipeline.update_with_mode( @@ -200,16 +202,21 @@ impl CCDSolver { { let co_parent1: Option<&ColliderParent> = colliders.get(ch1.0); let co_parent2: Option<&ColliderParent> = colliders.get(ch2.0); - let c1: (_, _, _) = colliders.index_bundle(ch1.0); - let c2: (_, _, _) = colliders.index_bundle(ch2.0); + let c1: (_, _, _, &ColliderFlags) = colliders.index_bundle(ch1.0); + let c2: (_, _, _, &ColliderFlags) = colliders.index_bundle(ch2.0); let co_type1: &ColliderType = colliders.index(ch1.0); let co_type2: &ColliderType = colliders.index(ch1.0); let bh1 = co_parent1.map(|p| p.handle); let bh2 = co_parent2.map(|p| p.handle); - if bh1 == bh2 || (co_type1.is_sensor() || co_type2.is_sensor()) { - // Ignore self-intersection and sensors. + // Ignore self-intersection and sensors and apply collision groups filter. + if bh1 == bh2 // Ignore self-intersection. + || (co_type1.is_sensor() || co_type2.is_sensor()) // Ignore sensors. + || !c1.3.collision_groups.test(c2.3.collision_groups) // Apply collision groups. + || !c1.3.solver_groups.test(c2.3.solver_groups) + // Apply solver groups. + { return true; } @@ -225,8 +232,8 @@ impl CCDSolver { self.query_pipeline.query_dispatcher(), *ch1, *ch2, - (c1.0, c1.1, c1.2, co_parent1), - (c2.0, c2.1, c2.2, co_parent2), + (c1.0, c1.1, c1.2, c1.3, co_parent1), + (c2.0, c2.1, c2.2, c2.3, co_parent2), Some((rb_pos1, rb_vels1, rb_mprops1, rb_ccd1)), b2, None, @@ -272,7 +279,9 @@ impl CCDSolver { Colliders: ComponentSetOption + ComponentSet + ComponentSet - + ComponentSet, + + ComponentSet + + ComponentSet + + ComponentSet, { let mut frozen = HashMap::<_, Real>::default(); let mut all_toi = BinaryHeap::new(); @@ -334,14 +343,15 @@ impl CCDSolver { { let co_parent1: Option<&ColliderParent> = colliders.get(ch1.0); let co_parent2: Option<&ColliderParent> = colliders.get(ch2.0); - let c1: (_, _, _) = colliders.index_bundle(ch1.0); - let c2: (_, _, _) = colliders.index_bundle(ch2.0); + let c1: (_, _, _, &ColliderFlags) = colliders.index_bundle(ch1.0); + let c2: (_, _, _, &ColliderFlags) = colliders.index_bundle(ch2.0); let bh1 = co_parent1.map(|p| p.handle); let bh2 = co_parent2.map(|p| p.handle); - if bh1 == bh2 { - // Ignore self-intersection. + // Ignore self-intersections and apply groups filter. + if bh1 == bh2 || !c1.3.collision_groups.test(c2.3.collision_groups) + { return true; } @@ -358,8 +368,8 @@ impl CCDSolver { self.query_pipeline.query_dispatcher(), *ch1, *ch2, - (c1.0, c1.1, c1.2, co_parent1), - (c2.0, c2.1, c2.2, co_parent2), + (c1.0, c1.1, c1.2, c1.3, co_parent1), + (c2.0, c2.1, c2.2, c2.3, co_parent2), b1, b2, None, @@ -398,7 +408,7 @@ impl CCDSolver { // NOTE: all static bodies (and kinematic bodies?) should be considered as "frozen", this // may avoid some resweeps. - let mut intersections_to_check = vec![]; + let mut pseudo_intersections_to_check = vec![]; while let Some(toi) = all_toi.pop() { assert!(toi.toi <= dt); @@ -420,7 +430,7 @@ impl CCDSolver { continue; } - if toi.is_intersection_test { + if toi.is_pseudo_intersection_test { // NOTE: this test is redundant with the previous `if !should_freeze && ...` // but let's keep it to avoid tricky regressions if we end up swapping both // `if` for some reasons in the future. @@ -428,7 +438,7 @@ impl CCDSolver { // This is only an intersection so we don't have to freeze and there is no // need to resweep. However we will need to see if we have to generate // intersection events, so push the TOI for further testing. - intersections_to_check.push(toi); + pseudo_intersections_to_check.push(toi); } continue; } @@ -460,14 +470,14 @@ impl CCDSolver { .colliders_with_aabb_intersecting_aabb(&aabb, |ch2| { let co_parent1: Option<&ColliderParent> = colliders.get(ch1.0); let co_parent2: Option<&ColliderParent> = colliders.get(ch2.0); - let c1: (_, _, _) = colliders.index_bundle(ch1.0); - let c2: (_, _, _) = colliders.index_bundle(ch2.0); + let c1: (_, _, _, &ColliderFlags) = colliders.index_bundle(ch1.0); + let c2: (_, _, _, &ColliderFlags) = colliders.index_bundle(ch2.0); let bh1 = co_parent1.map(|p| p.handle); let bh2 = co_parent2.map(|p| p.handle); - if bh1 == bh2 { - // Ignore self-intersection. + // Ignore self-intersection and apply groups filter. + if bh1 == bh2 || !c1.3.collision_groups.test(c2.3.collision_groups) { return true; } @@ -496,8 +506,8 @@ impl CCDSolver { self.query_pipeline.query_dispatcher(), *ch1, *ch2, - (c1.0, c1.1, c1.2, co_parent1), - (c2.0, c2.1, c2.2, co_parent2), + (c1.0, c1.1, c1.2, c1.3, co_parent1), + (c2.0, c2.1, c2.2, c2.3, co_parent2), b1, b2, frozen1.copied(), @@ -514,7 +524,7 @@ impl CCDSolver { } } - for toi in intersections_to_check { + for toi in pseudo_intersections_to_check { // See if the intersection is still active once the bodies // reach their final positions. // - If the intersection is still active, don't report it yet. It will be @@ -522,10 +532,29 @@ impl CCDSolver { // - If the intersection isn't active anymore, and it wasn't intersecting // before, then we need to generate one interaction-start and one interaction-stop // events because it will never be detected by the narrow-phase because of tunneling. - let (co_pos1, co_shape1): (&ColliderPosition, &ColliderShape) = - colliders.index_bundle(toi.c1.0); - let (co_pos2, co_shape2): (&ColliderPosition, &ColliderShape) = - colliders.index_bundle(toi.c2.0); + let (co_type1, co_pos1, co_shape1, co_flags1): ( + &ColliderType, + &ColliderPosition, + &ColliderShape, + &ColliderFlags, + ) = colliders.index_bundle(toi.c1.0); + let (co_type2, co_pos2, co_shape2, co_flags2): ( + &ColliderType, + &ColliderPosition, + &ColliderShape, + &ColliderFlags, + ) = colliders.index_bundle(toi.c2.0); + + if !co_type1.is_sensor() && !co_type2.is_sensor() { + // TODO: this happens if we found a TOI between two non-sensor + // colliders with mismatching solver_flags. It is not clear + // what we should do in this case: we could report a + // contact started/contact stopped event for example. But in + // that case, what contact pair should be pass to these events? + // For now we just ignore this special case. Let's wait for an actual + // use-case to come up before we determine what we want to do here. + continue; + } let co_next_pos1 = if let Some(b1) = toi.b1 { let co_parent1: &ColliderParent = colliders.get(toi.c1.0).unwrap(); @@ -535,7 +564,7 @@ impl CCDSolver { &RigidBodyMassProps, ) = bodies.index_bundle(b1.0); - let local_com1 = &rb_mprops1.mass_properties.local_com; + let local_com1 = &rb_mprops1.local_mprops.local_com; let frozen1 = frozen.get(&b1); let pos1 = frozen1 .map(|t| rb_vels1.integrate(*t, &rb_pos1.position, local_com1)) @@ -553,7 +582,7 @@ impl CCDSolver { &RigidBodyMassProps, ) = bodies.index_bundle(b2.0); - let local_com2 = &rb_mprops2.mass_properties.local_com; + let local_com2 = &rb_mprops2.local_mprops.local_com; let frozen2 = frozen.get(&b2); let pos2 = frozen2 .map(|t| rb_vels2.integrate(*t, &rb_pos2.position, local_com2)) @@ -575,7 +604,11 @@ impl CCDSolver { .intersection_test(&next_coll_pos12, co_shape1.as_ref(), co_shape2.as_ref()) .unwrap_or(false); - if !intersect_before && !intersect_after { + if !intersect_before + && !intersect_after + && (co_flags1.active_events | co_flags2.active_events) + .contains(ActiveEvents::INTERSECTION_EVENTS) + { // Emit one intersection-started and one intersection-stopped event. events.handle_intersection_event(IntersectionEvent::new(toi.c1, toi.c2, true)); events.handle_intersection_event(IntersectionEvent::new(toi.c1, toi.c2, false)); diff --git a/src/dynamics/ccd/toi_entry.rs b/src/dynamics/ccd/toi_entry.rs index 4637940..f937979 100644 --- a/src/dynamics/ccd/toi_entry.rs +++ b/src/dynamics/ccd/toi_entry.rs @@ -2,7 +2,7 @@ use crate::dynamics::{ RigidBodyCcd, RigidBodyHandle, RigidBodyMassProps, RigidBodyPosition, RigidBodyVelocity, }; use crate::geometry::{ - ColliderHandle, ColliderParent, ColliderPosition, ColliderShape, ColliderType, + ColliderFlags, ColliderHandle, ColliderParent, ColliderPosition, ColliderShape, ColliderType, }; use crate::math::Real; use parry::query::{NonlinearRigidMotion, QueryDispatcher}; @@ -14,7 +14,9 @@ pub struct TOIEntry { pub b1: Option, pub c2: ColliderHandle, pub b2: Option, - pub is_intersection_test: bool, + // We call this "pseudo" intersection because this also + // includes colliders pairs with mismatching solver_groups. + pub is_pseudo_intersection_test: bool, pub timestamp: usize, } @@ -25,7 +27,7 @@ impl TOIEntry { b1: Option, c2: ColliderHandle, b2: Option, - is_intersection_test: bool, + is_pseudo_intersection_test: bool, timestamp: usize, ) -> Self { Self { @@ -34,7 +36,7 @@ impl TOIEntry { b1, c2, b2, - is_intersection_test, + is_pseudo_intersection_test, timestamp, } } @@ -47,12 +49,14 @@ impl TOIEntry { &ColliderType, &ColliderShape, &ColliderPosition, + &ColliderFlags, Option<&ColliderParent>, ), c2: ( &ColliderType, &ColliderShape, &ColliderPosition, + &ColliderFlags, Option<&ColliderParent>, ), b1: Option<( @@ -78,8 +82,8 @@ impl TOIEntry { return None; } - let (co_type1, co_shape1, co_pos1, co_parent1) = c1; - let (co_type2, co_shape2, co_pos2, co_parent2) = c2; + let (co_type1, co_shape1, co_pos1, co_flags1, co_parent1) = c1; + let (co_type2, co_shape2, co_pos2, co_flags2, co_parent2) = c2; let linvel1 = frozen1.is_none() as u32 as Real * b1.map(|b| b.1.linvel).unwrap_or(na::zero()); @@ -104,7 +108,9 @@ impl TOIEntry { // keep it since more conservatism is good at this stage. let thickness = (co_shape1.0.ccd_thickness() + co_shape2.0.ccd_thickness()) + smallest_contact_dist.max(0.0); - let is_intersection_test = co_type1.is_sensor() || co_type2.is_sensor(); + let is_pseudo_intersection_test = co_type1.is_sensor() + || co_type2.is_sensor() + || !co_flags1.solver_groups.test(co_flags2.solver_groups); if (end_time - start_time) * vel12 < thickness { return None; @@ -135,7 +141,7 @@ impl TOIEntry { // If the TOI search involves two non-sensor colliders then // we don't want to stop the TOI search at the first penetration // because the colliders may be in a separating trajectory. - let stop_at_penetration = is_intersection_test; + let stop_at_penetration = is_pseudo_intersection_test; let res_toi = query_dispatcher .nonlinear_time_of_impact( @@ -157,7 +163,7 @@ impl TOIEntry { co_parent1.map(|p| p.handle), ch2, co_parent2.map(|p| p.handle), - is_intersection_test, + is_pseudo_intersection_test, 0, )) } @@ -173,7 +179,7 @@ impl TOIEntry { if ccd.ccd_active { NonlinearRigidMotion::new( poss.position, - mprops.mass_properties.local_com, + mprops.local_mprops.local_com, vels.linvel, vels.angvel, ) diff --git a/src/dynamics/integration_parameters.rs b/src/dynamics/integration_parameters.rs index e039bfc..4725319 100644 --- a/src/dynamics/integration_parameters.rs +++ b/src/dynamics/integration_parameters.rs @@ -10,7 +10,7 @@ pub struct IntegrationParameters { /// /// When CCD with multiple substeps is enabled, the timestep is subdivided /// into smaller pieces. This timestep subdivision won't generate timestep - /// lengths smaller than `min_dt`. + /// lengths smaller than `min_ccd_dt`. /// /// Setting this to a large value will reduce the opportunity to performing /// CCD substepping, resulting in potentially more time dropped by the @@ -18,17 +18,6 @@ pub struct IntegrationParameters { /// to numerical instabilities. pub min_ccd_dt: Real, - // /// If `true` and if rapier is compiled with the `parallel` feature, this will enable rayon-based multithreading (default: `true`). - // /// - // /// This parameter is ignored if rapier is not compiled with is `parallel` feature. - // /// Refer to rayon's documentation regarding how to configure the number of threads with either - // /// `rayon::ThreadPoolBuilder::new().num_threads(4).build_global().unwrap()` or `ThreadPool::install`. - // /// Note that using only one thread with `multithreading_enabled` set to `true` will result on a slower - // /// simulation than setting `multithreading_enabled` to `false`. - // pub multithreading_enabled: bool, - // /// If `true`, the world's `step` method will stop right after resolving exactly one CCD event (default: `false`). - // /// This allows the user to take action during a timestep, in-between two CCD events. - // pub return_after_ccd_substep: bool, /// The Error Reduction Parameter in `[0, 1]` is the proportion of /// the positional error to be corrected at each time step (default: `0.2`). pub erp: Real, diff --git a/src/dynamics/island_manager.rs b/src/dynamics/island_manager.rs index b79cdb2..34fa3bd 100644 --- a/src/dynamics/island_manager.rs +++ b/src/dynamics/island_manager.rs @@ -229,19 +229,17 @@ impl IslandManager { stack: &mut Vec, ) { for collider_handle in &rb_colliders.0 { - if let Some(contacts) = narrow_phase.contacts_with(*collider_handle) { - for inter in contacts { - for manifold in &inter.2.manifolds { - if !manifold.data.solver_contacts.is_empty() { - let other = crate::utils::select_other( - (inter.0, inter.1), - *collider_handle, - ); - if let Some(other_body) = colliders.get(other.0) { - stack.push(other_body.handle); - } - break; + for inter in narrow_phase.contacts_with(*collider_handle) { + for manifold in &inter.manifolds { + if !manifold.data.solver_contacts.is_empty() { + let other = crate::utils::select_other( + (inter.collider1, inter.collider2), + *collider_handle, + ); + if let Some(other_body) = colliders.get(other.0) { + stack.push(other_body.handle); } + break; } } } diff --git a/src/dynamics/joint/fixed_joint.rs b/src/dynamics/joint/fixed_joint.rs index 2917757..3f87e8d 100644 --- a/src/dynamics/joint/fixed_joint.rs +++ b/src/dynamics/joint/fixed_joint.rs @@ -8,10 +8,10 @@ use crate::math::{Isometry, Real, SpacialVector}; pub struct FixedJoint { /// The frame of reference for the first body affected by this joint, expressed in the local frame /// of the first body. - pub local_anchor1: Isometry, + pub local_frame1: Isometry, /// The frame of reference for the second body affected by this joint, expressed in the local frame /// of the first body. - pub local_anchor2: Isometry, + pub local_frame2: Isometry, /// The impulse applied to the first body affected by this joint. /// /// The impulse applied to the second body affected by this joint is given by `-impulse`. @@ -23,10 +23,10 @@ pub struct FixedJoint { impl FixedJoint { /// Creates a new fixed joint from the frames of reference of both bodies. - pub fn new(local_anchor1: Isometry, local_anchor2: Isometry) -> Self { + pub fn new(local_frame1: Isometry, local_frame2: Isometry) -> Self { Self { - local_anchor1, - local_anchor2, + local_frame1, + local_frame2, impulse: SpacialVector::zeros(), } } diff --git a/src/dynamics/rigid_body.rs b/src/dynamics/rigid_body.rs index 824ec92..63c2221 100644 --- a/src/dynamics/rigid_body.rs +++ b/src/dynamics/rigid_body.rs @@ -4,8 +4,7 @@ use crate::dynamics::{ RigidBodyMassPropsFlags, RigidBodyPosition, RigidBodyType, RigidBodyVelocity, }; use crate::geometry::{ - Collider, ColliderHandle, ColliderMassProperties, ColliderParent, ColliderPosition, - ColliderShape, + Collider, ColliderHandle, ColliderMassProps, ColliderParent, ColliderPosition, ColliderShape, }; use crate::math::{AngVector, Isometry, Point, Real, Rotation, Vector}; use crate::utils::{self, WCross}; @@ -48,7 +47,7 @@ impl RigidBody { rb_ccd: RigidBodyCcd::default(), rb_ids: RigidBodyIds::default(), rb_colliders: RigidBodyColliders::default(), - rb_activation: RigidBodyActivation::new_active(), + rb_activation: RigidBodyActivation::active(), changes: RigidBodyChanges::all(), rb_type: RigidBodyType::Dynamic, rb_dominance: RigidBodyDominance::default(), @@ -112,7 +111,7 @@ impl RigidBody { /// The mass properties of this rigid-body. #[inline] pub fn mass_properties(&self) -> &MassProperties { - &self.rb_mprops.mass_properties + &self.rb_mprops.local_mprops } /// The dominance group of this rigid-body. @@ -124,6 +123,72 @@ impl RigidBody { self.rb_dominance.effective_group(&self.rb_type) } + #[inline] + /// Locks or unlocks all the rotations of this rigid-body. + pub fn lock_rotations(&mut self, locked: bool, wake_up: bool) { + if self.is_dynamic() { + if wake_up { + self.wake_up(true); + } + + self.rb_mprops + .flags + .set(RigidBodyMassPropsFlags::ROTATION_LOCKED_X, locked); + self.rb_mprops + .flags + .set(RigidBodyMassPropsFlags::ROTATION_LOCKED_Y, locked); + self.rb_mprops + .flags + .set(RigidBodyMassPropsFlags::ROTATION_LOCKED_Z, locked); + self.update_world_mass_properties(); + } + } + + #[inline] + /// Locks or unlocks rotations of this rigid-body along each cartesian axes. + pub fn restrict_rotations( + &mut self, + allow_rotations_x: bool, + allow_rotations_y: bool, + allow_rotations_z: bool, + wake_up: bool, + ) { + if self.is_dynamic() { + if wake_up { + self.wake_up(true); + } + + self.rb_mprops.flags.set( + RigidBodyMassPropsFlags::ROTATION_LOCKED_X, + allow_rotations_x, + ); + self.rb_mprops.flags.set( + RigidBodyMassPropsFlags::ROTATION_LOCKED_Y, + allow_rotations_y, + ); + self.rb_mprops.flags.set( + RigidBodyMassPropsFlags::ROTATION_LOCKED_Z, + allow_rotations_z, + ); + self.update_world_mass_properties(); + } + } + + #[inline] + /// Locks or unlocks all the rotations of this rigid-body. + pub fn lock_translations(&mut self, locked: bool, wake_up: bool) { + if self.is_dynamic() { + if wake_up { + self.wake_up(true); + } + + self.rb_mprops + .flags + .set(RigidBodyMassPropsFlags::TRANSLATION_LOCKED, locked); + self.update_world_mass_properties(); + } + } + /// Are the translations of this rigid-body locked? pub fn is_translation_locked(&self) -> bool { self.rb_mprops @@ -190,7 +255,7 @@ impl RigidBody { self.wake_up(true); } - self.rb_mprops.mass_properties = props; + self.rb_mprops.local_mprops = props; self.update_world_mass_properties(); } @@ -210,7 +275,7 @@ impl RigidBody { /// /// A kinematic body can move freely but is not affected by forces. pub fn is_kinematic(&self) -> bool { - self.rb_type == RigidBodyType::Kinematic + self.rb_type.is_kinematic() } /// Is this rigid body static? @@ -224,7 +289,7 @@ impl RigidBody { /// /// Returns zero if this rigid body has an infinite mass. pub fn mass(&self) -> Real { - utils::inv(self.rb_mprops.mass_properties.inv_mass) + utils::inv(self.rb_mprops.local_mprops.inv_mass) } /// The predicted position of this rigid-body. @@ -251,6 +316,16 @@ impl RigidBody { self.rb_forces.gravity_scale = scale; } + /// The dominance group of this rigid-body. + pub fn dominance_group(&self) -> i8 { + self.rb_dominance.0 + } + + /// The dominance group of this rigid-body. + pub fn set_dominance_group(&mut self, dominance: i8) { + self.rb_dominance.0 = dominance + } + /// Adds a collider to this rigid-body. // TODO ECS: we keep this public for now just to simply our experiments on bevy_rapier. pub fn add_collider( @@ -259,7 +334,7 @@ impl RigidBody { co_parent: &ColliderParent, co_pos: &mut ColliderPosition, co_shape: &ColliderShape, - co_mprops: &ColliderMassProperties, + co_mprops: &ColliderMassProps, ) { self.rb_colliders.attach_collider( &mut self.changes, @@ -279,10 +354,11 @@ impl RigidBody { if let Some(i) = self.rb_colliders.0.iter().position(|e| *e == handle) { self.changes.set(RigidBodyChanges::COLLIDERS, true); self.rb_colliders.0.swap_remove(i); + let mass_properties = coll .mass_properties() - .transform_by(coll.position_wrt_parent()); - self.rb_mprops.mass_properties -= mass_properties; + .transform_by(coll.position_wrt_parent().unwrap()); + self.rb_mprops.local_mprops -= mass_properties; self.update_world_mass_properties(); } } @@ -384,6 +460,45 @@ impl RigidBody { &self.rb_pos.position } + /// The translational part of this rigid-body's position. + #[inline] + pub fn translation(&self) -> &Vector { + &self.rb_pos.position.translation.vector + } + + /// Sets the translational part of this rigid-body's position. + #[inline] + pub fn set_translation(&mut self, translation: Vector, wake_up: bool) { + self.changes.insert(RigidBodyChanges::POSITION); + self.rb_pos.position.translation.vector = translation; + self.rb_pos.next_position.translation.vector = translation; + + // TODO: Do we really need to check that the body isn't dynamic? + if wake_up && self.is_dynamic() { + self.wake_up(true) + } + } + + /// The translational part of this rigid-body's position. + #[inline] + pub fn rotation(&self) -> &Rotation { + &self.rb_pos.position.rotation + } + + /// Sets the rotational part of this rigid-body's position. + #[inline] + pub fn set_rotation(&mut self, rotation: AngVector, wake_up: bool) { + self.changes.insert(RigidBodyChanges::POSITION); + let rotation = Rotation::new(rotation); + self.rb_pos.position.rotation = rotation; + self.rb_pos.next_position.rotation = rotation; + + // TODO: Do we really need to check that the body isn't dynamic? + if wake_up && self.is_dynamic() { + self.wake_up(true) + } + } + /// Sets the position and `next_kinematic_position` of this rigid body. /// /// This will teleport the rigid-body to the specified position/orientation, @@ -404,6 +519,20 @@ impl RigidBody { } } + /// If this rigid body is kinematic, sets its future translation after the next timestep integration. + pub fn set_next_kinematic_rotation(&mut self, rotation: AngVector) { + if self.is_kinematic() { + self.rb_pos.next_position.rotation = Rotation::new(rotation); + } + } + + /// If this rigid body is kinematic, sets its future orientation after the next timestep integration. + pub fn set_next_kinematic_translation(&mut self, translation: Vector) { + if self.is_kinematic() { + self.rb_pos.next_position.translation = translation.into(); + } + } + /// If this rigid body is kinematic, sets its future position after the next timestep integration. pub fn set_next_kinematic_position(&mut self, pos: Isometry) { if self.is_kinematic() { @@ -411,6 +540,17 @@ impl RigidBody { } } + /// Predicts the next position of this rigid-body, by integrating its velocity and forces + /// by a time of `dt`. + pub fn predict_position_using_velocity_and_forces(&self, dt: Real) -> Isometry { + self.rb_pos.integrate_forces_and_velocities( + dt, + &self.rb_forces, + &self.rb_vels, + &self.rb_mprops, + ) + } + pub(crate) fn update_world_mass_properties(&mut self) { self.rb_mprops .update_world_mass_properties(&self.rb_pos.position); @@ -551,7 +691,7 @@ impl RigidBody { pub fn gravitational_potential_energy(&self, dt: Real, gravity: Vector) -> Real { let world_com = self .rb_mprops - .mass_properties + .local_mprops .world_com(&self.rb_pos.position) .coords; @@ -608,8 +748,13 @@ impl RigidBodyBuilder { } /// Initializes the builder of a new kinematic rigid body. - pub fn new_kinematic() -> Self { - Self::new(RigidBodyType::Kinematic) + pub fn new_kinematic_velocity_based() -> Self { + Self::new(RigidBodyType::KinematicVelocityBased) + } + + /// Initializes the builder of a new kinematic rigid body. + pub fn new_kinematic_position_based() -> Self { + Self::new(RigidBodyType::KinematicPositionBased) } /// Initializes the builder of a new dynamic rigid body. @@ -618,8 +763,8 @@ impl RigidBodyBuilder { } /// Sets the scale applied to the gravity force affecting the rigid-body to be created. - pub fn gravity_scale(mut self, x: Real) -> Self { - self.gravity_scale = x; + pub fn gravity_scale(mut self, scale_factor: Real) -> Self { + self.gravity_scale = scale_factor; self } @@ -630,19 +775,8 @@ impl RigidBodyBuilder { } /// Sets the initial translation of the rigid-body to be created. - #[cfg(feature = "dim2")] - pub fn translation(mut self, x: Real, y: Real) -> Self { - self.position.translation.x = x; - self.position.translation.y = y; - self - } - - /// Sets the initial translation of the rigid-body to be created. - #[cfg(feature = "dim3")] - pub fn translation(mut self, x: Real, y: Real, z: Real) -> Self { - self.position.translation.x = x; - self.position.translation.y = y; - self.position.translation.z = z; + pub fn translation(mut self, translation: Vector) -> Self { + self.position.translation.vector = translation; self } @@ -811,16 +945,8 @@ impl RigidBodyBuilder { } /// Sets the initial linear velocity of the rigid-body to be created. - #[cfg(feature = "dim2")] - pub fn linvel(mut self, x: Real, y: Real) -> Self { - self.linvel = Vector::new(x, y); - self - } - - /// Sets the initial linear velocity of the rigid-body to be created. - #[cfg(feature = "dim3")] - pub fn linvel(mut self, x: Real, y: Real, z: Real) -> Self { - self.linvel = Vector::new(x, y, z); + pub fn linvel(mut self, linvel: Vector) -> Self { + self.linvel = linvel; self } @@ -857,7 +983,7 @@ impl RigidBodyBuilder { rb.rb_vels.angvel = self.angvel; rb.rb_type = self.rb_type; rb.user_data = self.user_data; - rb.rb_mprops.mass_properties = self.mass_properties; + rb.rb_mprops.local_mprops = self.mass_properties; rb.rb_mprops.flags = self.mprops_flags; rb.rb_damping.linear_damping = self.linear_damping; rb.rb_damping.angular_damping = self.angular_damping; diff --git a/src/dynamics/rigid_body_components.rs b/src/dynamics/rigid_body_components.rs index 2a652f7..ec67b66 100644 --- a/src/dynamics/rigid_body_components.rs +++ b/src/dynamics/rigid_body_components.rs @@ -1,7 +1,7 @@ use crate::data::{ComponentSetMut, ComponentSetOption}; use crate::dynamics::MassProperties; use crate::geometry::{ - ColliderChanges, ColliderHandle, ColliderMassProperties, ColliderParent, ColliderPosition, + ColliderChanges, ColliderHandle, ColliderMassProps, ColliderParent, ColliderPosition, ColliderShape, InteractionGraph, RigidBodyGraphIndex, }; use crate::math::{AngVector, AngularInertia, Isometry, Point, Real, Translation, Vector}; @@ -54,16 +54,23 @@ pub type BodyStatus = RigidBodyType; /// The status of a body, governing the way it is affected by external forces. pub enum RigidBodyType { /// A `RigidBodyType::Dynamic` body can be affected by all external forces. - Dynamic, + Dynamic = 0, /// A `RigidBodyType::Static` body cannot be affected by external forces. - Static, - /// A `RigidBodyType::Kinematic` body cannot be affected by any external forces but can be controlled + Static = 1, + /// A `RigidBodyType::KinematicPositionBased` body cannot be affected by any external forces but can be controlled /// by the user at the position level while keeping realistic one-way interaction with dynamic bodies. /// /// One-way interaction means that a kinematic body can push a dynamic body, but a kinematic body /// cannot be pushed by anything. In other words, the trajectory of a kinematic body can only be /// modified by the user and is independent from any contact or joint it is involved in. - Kinematic, + KinematicPositionBased = 2, + /// A `RigidBodyType::KinematicVelocityBased` body cannot be affected by any external forces but can be controlled + /// by the user at the velocity level while keeping realistic one-way interaction with dynamic bodies. + /// + /// One-way interaction means that a kinematic body can push a dynamic body, but a kinematic body + /// cannot be pushed by anything. In other words, the trajectory of a kinematic body can only be + /// modified by the user and is independent from any contact or joint it is involved in. + KinematicVelocityBased = 3, // Semikinematic, // A kinematic that performs automatic CCD with the static environment to avoid traversing it? // Disabled, } @@ -81,7 +88,8 @@ impl RigidBodyType { /// Is this rigid-body kinematic (i.e. can move but is unaffected by forces)? pub fn is_kinematic(self) -> bool { - self == RigidBodyType::Kinematic + self == RigidBodyType::KinematicPositionBased + || self == RigidBodyType::KinematicVelocityBased } } @@ -166,7 +174,7 @@ impl RigidBodyPosition { mprops: &RigidBodyMassProps, ) -> Isometry { let new_vels = forces.integrate(dt, vels, mprops); - new_vels.integrate(dt, &self.position, &mprops.mass_properties.local_com) + new_vels.integrate(dt, &self.position, &mprops.local_mprops.local_com) } } @@ -208,7 +216,7 @@ pub struct RigidBodyMassProps { /// Flags for locking rotation and translation. pub flags: RigidBodyMassPropsFlags, /// The local mass properties of the rigid-body. - pub mass_properties: MassProperties, + pub local_mprops: MassProperties, /// The world-space center of mass of the rigid-body. pub world_com: Point, /// The inverse mass taking into account translation locking. @@ -222,7 +230,7 @@ impl Default for RigidBodyMassProps { fn default() -> Self { Self { flags: RigidBodyMassPropsFlags::empty(), - mass_properties: MassProperties::zero(), + local_mprops: MassProperties::zero(), world_com: Point::origin(), effective_inv_mass: 0.0, effective_world_inv_inertia_sqrt: AngularInertia::zero(), @@ -239,11 +247,20 @@ impl From for RigidBodyMassProps { } } +impl From for RigidBodyMassProps { + fn from(local_mprops: MassProperties) -> Self { + Self { + local_mprops, + ..Default::default() + } + } +} + impl RigidBodyMassProps { /// The mass of the rigid-body. #[must_use] pub fn mass(&self) -> Real { - crate::utils::inv(self.mass_properties.inv_mass) + crate::utils::inv(self.local_mprops.inv_mass) } /// The effective mass (that takes the potential translation locking into account) of @@ -255,11 +272,10 @@ impl RigidBodyMassProps { /// Update the world-space mass properties of `self`, taking into account the new position. pub fn update_world_mass_properties(&mut self, position: &Isometry) { - self.world_com = self.mass_properties.world_com(&position); - self.effective_inv_mass = self.mass_properties.inv_mass; - self.effective_world_inv_inertia_sqrt = self - .mass_properties - .world_inv_inertia_sqrt(&position.rotation); + self.world_com = self.local_mprops.world_com(&position); + self.effective_inv_mass = self.local_mprops.inv_mass; + self.effective_world_inv_inertia_sqrt = + self.local_mprops.world_inv_inertia_sqrt(&position.rotation); // Take into account translation/rotation locking. if self @@ -665,7 +681,7 @@ impl RigidBodyColliders { co_pos: &mut ColliderPosition, co_parent: &ColliderParent, co_shape: &ColliderShape, - co_mprops: &ColliderMassProperties, + co_mprops: &ColliderMassProps, ) { rb_changes.set( RigidBodyChanges::MODIFIED | RigidBodyChanges::COLLIDERS, @@ -684,7 +700,7 @@ impl RigidBodyColliders { .mass_properties(&**co_shape) .transform_by(&co_parent.pos_wrt_parent); self.0.push(co_handle); - rb_mprops.mass_properties += mass_properties; + rb_mprops.local_mprops += mass_properties; rb_mprops.update_world_mass_properties(&rb_pos.position); } @@ -759,7 +775,7 @@ pub struct RigidBodyActivation { impl Default for RigidBodyActivation { fn default() -> Self { - Self::new_active() + Self::active() } } @@ -770,7 +786,7 @@ impl RigidBodyActivation { } /// Create a new rb_activation status initialised with the default rb_activation threshold and is active. - pub fn new_active() -> Self { + pub fn active() -> Self { RigidBodyActivation { threshold: Self::default_threshold(), energy: Self::default_threshold() * 4.0, @@ -779,7 +795,7 @@ impl RigidBodyActivation { } /// Create a new rb_activation status initialised with the default rb_activation threshold and is inactive. - pub fn new_inactive() -> Self { + pub fn inactive() -> Self { RigidBodyActivation { threshold: Self::default_threshold(), energy: 0.0, @@ -787,6 +803,14 @@ impl RigidBodyActivation { } } + /// Create a new activation status that prevents the rigid-body from sleeping. + pub fn cannot_sleep() -> Self { + RigidBodyActivation { + threshold: -Real::MAX, + ..Self::active() + } + } + /// Returns `true` if the body is not asleep. #[inline] pub fn is_active(&self) -> bool { diff --git a/src/dynamics/solver/island_solver.rs b/src/dynamics/solver/island_solver.rs index 1e65341..0c4c323 100644 --- a/src/dynamics/solver/island_solver.rs +++ b/src/dynamics/solver/island_solver.rs @@ -113,7 +113,7 @@ impl IslandSolver { let mut new_poss = *poss; let new_vels = vels.apply_damping(params.dt, damping); new_poss.next_position = - vels.integrate(params.dt, &poss.position, &mprops.mass_properties.local_com); + vels.integrate(params.dt, &poss.position, &mprops.local_mprops.local_com); bodies.set_internal(handle.0, new_vels); bodies.set_internal(handle.0, new_poss); @@ -140,7 +140,7 @@ impl IslandSolver { .integrate(params.dt, vels, mprops) .apply_damping(params.dt, &damping); new_poss.next_position = - vels.integrate(params.dt, &poss.position, &mprops.mass_properties.local_com); + vels.integrate(params.dt, &poss.position, &mprops.local_mprops.local_com); bodies.set_internal(handle.0, new_vels); bodies.set_internal(handle.0, new_poss); diff --git a/src/dynamics/solver/joint_constraint/ball_position_constraint.rs b/src/dynamics/solver/joint_constraint/ball_position_constraint.rs index 159cc77..0227960 100644 --- a/src/dynamics/solver/joint_constraint/ball_position_constraint.rs +++ b/src/dynamics/solver/joint_constraint/ball_position_constraint.rs @@ -34,8 +34,8 @@ impl BallPositionConstraint { let (mprops2, ids2) = rb2; Self { - local_com1: mprops1.mass_properties.local_com, - local_com2: mprops2.mass_properties.local_com, + local_com1: mprops1.local_mprops.local_com, + local_com2: mprops2.local_mprops.local_com, im1: mprops1.effective_inv_mass, im2: mprops2.effective_inv_mass, ii1: mprops1.effective_world_inv_inertia_sqrt.squared(), @@ -131,7 +131,7 @@ impl BallPositionGroundConstraint { ii2: mprops2.effective_world_inv_inertia_sqrt.squared(), local_anchor2: cparams.local_anchor1, position2: ids2.active_set_offset, - local_com2: mprops2.mass_properties.local_com, + local_com2: mprops2.local_mprops.local_com, } } else { Self { @@ -140,7 +140,7 @@ impl BallPositionGroundConstraint { ii2: mprops2.effective_world_inv_inertia_sqrt.squared(), local_anchor2: cparams.local_anchor2, position2: ids2.active_set_offset, - local_com2: mprops2.mass_properties.local_com, + local_com2: mprops2.local_mprops.local_com, } } } diff --git a/src/dynamics/solver/joint_constraint/ball_position_constraint_wide.rs b/src/dynamics/solver/joint_constraint/ball_position_constraint_wide.rs index 6b00639..ea462ed 100644 --- a/src/dynamics/solver/joint_constraint/ball_position_constraint_wide.rs +++ b/src/dynamics/solver/joint_constraint/ball_position_constraint_wide.rs @@ -40,8 +40,8 @@ impl WBallPositionConstraint { let (mprops1, ids1) = rbs1; let (mprops2, ids2) = rbs2; - let local_com1 = Point::from(gather![|ii| mprops1[ii].mass_properties.local_com]); - let local_com2 = Point::from(gather![|ii| mprops2[ii].mass_properties.local_com]); + let local_com1 = Point::from(gather![|ii| mprops1[ii].local_mprops.local_com]); + let local_com2 = Point::from(gather![|ii| mprops2[ii].local_mprops.local_com]); let im1 = SimdReal::from(gather![|ii| mprops1[ii].effective_inv_mass]); let im2 = SimdReal::from(gather![|ii| mprops2[ii].effective_inv_mass]); let ii1 = AngularInertia::::from(gather![ @@ -169,7 +169,7 @@ impl WBallPositionGroundConstraint { cparams[ii].local_anchor2 }]); let position2 = gather![|ii| ids2[ii].active_set_offset]; - let local_com2 = Point::from(gather![|ii| mprops2[ii].mass_properties.local_com]); + let local_com2 = Point::from(gather![|ii| mprops2[ii].local_mprops.local_com]); Self { anchor1, diff --git a/src/dynamics/solver/joint_constraint/fixed_position_constraint.rs b/src/dynamics/solver/joint_constraint/fixed_position_constraint.rs index 239138f..3ab13f7 100644 --- a/src/dynamics/solver/joint_constraint/fixed_position_constraint.rs +++ b/src/dynamics/solver/joint_constraint/fixed_position_constraint.rs @@ -8,8 +8,8 @@ use crate::utils::WAngularInertia; pub(crate) struct FixedPositionConstraint { position1: usize, position2: usize, - local_anchor1: Isometry, - local_anchor2: Isometry, + local_frame1: Isometry, + local_frame2: Isometry, local_com1: Point, local_com2: Point, im1: Real, @@ -38,16 +38,16 @@ impl FixedPositionConstraint { let ang_inv_lhs = (ii1 + ii2).inverse(); Self { - local_anchor1: cparams.local_anchor1, - local_anchor2: cparams.local_anchor2, + local_frame1: cparams.local_frame1, + local_frame2: cparams.local_frame2, position1: ids1.active_set_offset, position2: ids2.active_set_offset, im1, im2, ii1, ii2, - local_com1: mprops1.mass_properties.local_com, - local_com2: mprops2.mass_properties.local_com, + local_com1: mprops1.local_mprops.local_com, + local_com2: mprops2.local_mprops.local_com, lin_inv_lhs, ang_inv_lhs, } @@ -58,8 +58,8 @@ impl FixedPositionConstraint { let mut position2 = positions[self.position2 as usize]; // Angular correction. - let anchor1 = position1 * self.local_anchor1; - let anchor2 = position2 * self.local_anchor2; + let anchor1 = position1 * self.local_frame1; + let anchor2 = position2 * self.local_frame2; let ang_err = anchor2.rotation * anchor1.rotation.inverse(); #[cfg(feature = "dim3")] let ang_impulse = self @@ -75,8 +75,8 @@ impl FixedPositionConstraint { Rotation::new(self.ii2.transform_vector(-ang_impulse)) * position2.rotation; // Linear correction. - let anchor1 = position1 * Point::from(self.local_anchor1.translation.vector); - let anchor2 = position2 * Point::from(self.local_anchor2.translation.vector); + let anchor1 = position1 * Point::from(self.local_frame1.translation.vector); + let anchor2 = position2 * Point::from(self.local_frame2.translation.vector); let err = anchor2 - anchor1; let impulse = err * (self.lin_inv_lhs * params.joint_erp); position1.translation.vector += self.im1 * impulse; @@ -91,7 +91,7 @@ impl FixedPositionConstraint { pub(crate) struct FixedPositionGroundConstraint { position2: usize, anchor1: Isometry, - local_anchor2: Isometry, + local_frame2: Isometry, local_com2: Point, im2: Real, ii2: AngularInertia, @@ -109,23 +109,23 @@ impl FixedPositionGroundConstraint { let (mprops2, ids2) = rb2; let anchor1; - let local_anchor2; + let local_frame2; if flipped { - anchor1 = poss1.next_position * cparams.local_anchor2; - local_anchor2 = cparams.local_anchor1; + anchor1 = poss1.next_position * cparams.local_frame2; + local_frame2 = cparams.local_frame1; } else { - anchor1 = poss1.next_position * cparams.local_anchor1; - local_anchor2 = cparams.local_anchor2; + anchor1 = poss1.next_position * cparams.local_frame1; + local_frame2 = cparams.local_frame2; }; Self { anchor1, - local_anchor2, + local_frame2, position2: ids2.active_set_offset, im2: mprops2.effective_inv_mass, ii2: mprops2.effective_world_inv_inertia_sqrt.squared(), - local_com2: mprops2.mass_properties.local_com, + local_com2: mprops2.local_mprops.local_com, impulse: 0.0, } } @@ -134,13 +134,13 @@ impl FixedPositionGroundConstraint { let mut position2 = positions[self.position2 as usize]; // Angular correction. - let anchor2 = position2 * self.local_anchor2; + let anchor2 = position2 * self.local_frame2; let ang_err = anchor2.rotation * self.anchor1.rotation.inverse(); position2.rotation = ang_err.powf(-params.joint_erp) * position2.rotation; // Linear correction. let anchor1 = Point::from(self.anchor1.translation.vector); - let anchor2 = position2 * Point::from(self.local_anchor2.translation.vector); + let anchor2 = position2 * Point::from(self.local_frame2.translation.vector); let err = anchor2 - anchor1; // NOTE: no need to divide by im2 just to multiply right after. let impulse = err * params.joint_erp; diff --git a/src/dynamics/solver/joint_constraint/fixed_velocity_constraint.rs b/src/dynamics/solver/joint_constraint/fixed_velocity_constraint.rs index a0c0739..8bfc1a6 100644 --- a/src/dynamics/solver/joint_constraint/fixed_velocity_constraint.rs +++ b/src/dynamics/solver/joint_constraint/fixed_velocity_constraint.rs @@ -63,8 +63,8 @@ impl FixedVelocityConstraint { let (poss1, vels1, mprops1, ids1) = rb1; let (poss2, vels2, mprops2, ids2) = rb2; - let anchor1 = poss1.position * cparams.local_anchor1; - let anchor2 = poss2.position * cparams.local_anchor2; + let anchor1 = poss1.position * cparams.local_frame1; + let anchor2 = poss2.position * cparams.local_frame2; let im1 = mprops1.effective_inv_mass; let im2 = mprops2.effective_inv_mass; let ii1 = mprops1.effective_world_inv_inertia_sqrt.squared(); @@ -280,13 +280,13 @@ impl FixedVelocityGroundConstraint { let (anchor1, anchor2) = if flipped { ( - poss1.position * cparams.local_anchor2, - poss2.position * cparams.local_anchor1, + poss1.position * cparams.local_frame2, + poss2.position * cparams.local_frame1, ) } else { ( - poss1.position * cparams.local_anchor1, - poss2.position * cparams.local_anchor2, + poss1.position * cparams.local_frame1, + poss2.position * cparams.local_frame2, ) }; diff --git a/src/dynamics/solver/joint_constraint/fixed_velocity_constraint_wide.rs b/src/dynamics/solver/joint_constraint/fixed_velocity_constraint_wide.rs index 84e1fca..0421d49 100644 --- a/src/dynamics/solver/joint_constraint/fixed_velocity_constraint_wide.rs +++ b/src/dynamics/solver/joint_constraint/fixed_velocity_constraint_wide.rs @@ -91,12 +91,12 @@ impl WFixedVelocityConstraint { ]); let mj_lambda2 = gather![|ii| ids2[ii].active_set_offset]; - let local_anchor1 = Isometry::from(gather![|ii| cparams[ii].local_anchor1]); - let local_anchor2 = Isometry::from(gather![|ii| cparams[ii].local_anchor2]); + let local_frame1 = Isometry::from(gather![|ii| cparams[ii].local_frame1]); + let local_frame2 = Isometry::from(gather![|ii| cparams[ii].local_frame2]); let impulse = SpacialVector::from(gather![|ii| cparams[ii].impulse]); - let anchor1 = position1 * local_anchor1; - let anchor2 = position2 * local_anchor2; + let anchor1 = position1 * local_frame1; + let anchor2 = position2 * local_frame2; let ii1 = ii1_sqrt.squared(); let ii2 = ii2_sqrt.squared(); let r1 = anchor1.translation.vector - world_com1.coords; @@ -363,20 +363,20 @@ impl WFixedVelocityGroundConstraint { ]); let mj_lambda2 = gather![|ii| ids2[ii].active_set_offset]; - let local_anchor1 = Isometry::from(gather![|ii| if flipped[ii] { - cparams[ii].local_anchor2 + let local_frame1 = Isometry::from(gather![|ii| if flipped[ii] { + cparams[ii].local_frame2 } else { - cparams[ii].local_anchor1 + cparams[ii].local_frame1 }]); - let local_anchor2 = Isometry::from(gather![|ii| if flipped[ii] { - cparams[ii].local_anchor1 + let local_frame2 = Isometry::from(gather![|ii| if flipped[ii] { + cparams[ii].local_frame1 } else { - cparams[ii].local_anchor2 + cparams[ii].local_frame2 }]); let impulse = SpacialVector::from(gather![|ii| cparams[ii].impulse]); - let anchor1 = position1 * local_anchor1; - let anchor2 = position2 * local_anchor2; + let anchor1 = position1 * local_frame1; + let anchor2 = position2 * local_frame2; let ii2 = ii2_sqrt.squared(); let r1 = anchor1.translation.vector - world_com1.coords; let r2 = anchor2.translation.vector - world_com2.coords; diff --git a/src/dynamics/solver/joint_constraint/generic_position_constraint.rs b/src/dynamics/solver/joint_constraint/generic_position_constraint.rs index 76901b1..a7b5ea0 100644 --- a/src/dynamics/solver/joint_constraint/generic_position_constraint.rs +++ b/src/dynamics/solver/joint_constraint/generic_position_constraint.rs @@ -41,8 +41,8 @@ impl GenericPositionConstraint { im2, ii1, ii2, - local_com1: rb1.mass_properties.local_com, - local_com2: rb2.mass_properties.local_com, + local_com1: rb1.local_mprops.local_com, + local_com2: rb2.local_mprops.local_com, joint: *joint, } } @@ -215,7 +215,7 @@ impl GenericPositionGroundConstraint { position2: rb2.active_set_offset, im2: rb2.effective_inv_mass, ii2: rb2.effective_world_inv_inertia_sqrt.squared(), - local_com2: rb2.mass_properties.local_com, + local_com2: rb2.local_mprops.local_com, joint: *joint, } } diff --git a/src/dynamics/solver/joint_constraint/revolute_position_constraint.rs b/src/dynamics/solver/joint_constraint/revolute_position_constraint.rs index 1b3e23a..731d0e2 100644 --- a/src/dynamics/solver/joint_constraint/revolute_position_constraint.rs +++ b/src/dynamics/solver/joint_constraint/revolute_position_constraint.rs @@ -51,8 +51,8 @@ impl RevolutePositionConstraint { ii1, ii2, ang_inv_lhs, - local_com1: mprops1.mass_properties.local_com, - local_com2: mprops2.mass_properties.local_com, + local_com1: mprops1.local_mprops.local_com, + local_com2: mprops2.local_mprops.local_com, local_anchor1: cparams.local_anchor1, local_anchor2: cparams.local_anchor2, local_axis1: cparams.local_axis1, @@ -183,7 +183,7 @@ impl RevolutePositionGroundConstraint { local_anchor2, im2: mprops2.effective_inv_mass, ii2: mprops2.effective_world_inv_inertia_sqrt.squared(), - local_com2: mprops2.mass_properties.local_com, + local_com2: mprops2.local_mprops.local_com, axis1, local_axis2, position2: ids2.active_set_offset, diff --git a/src/dynamics/solver/parallel_island_solver.rs b/src/dynamics/solver/parallel_island_solver.rs index 9d565c1..e12e7af 100644 --- a/src/dynamics/solver/parallel_island_solver.rs +++ b/src/dynamics/solver/parallel_island_solver.rs @@ -392,7 +392,7 @@ impl ParallelIslandSolver { let new_rb_vels = new_rb_vels.apply_damping(params.dt, rb_damping); new_rb_pos.next_position = - new_rb_vels.integrate(params.dt, &rb_pos.position, &rb_mprops.mass_properties.local_com); + new_rb_vels.integrate(params.dt, &rb_pos.position, &rb_mprops.local_mprops.local_com); bodies.set_internal(handle.0, new_rb_vels); bodies.set_internal(handle.0, new_rb_pos); diff --git a/src/geometry/broad_phase_multi_sap/broad_phase.rs b/src/geometry/broad_phase_multi_sap/broad_phase.rs index 4b35e53..63f1a55 100644 --- a/src/geometry/broad_phase_multi_sap/broad_phase.rs +++ b/src/geometry/broad_phase_multi_sap/broad_phase.rs @@ -598,7 +598,7 @@ mod test { let rb = RigidBodyBuilder::new_dynamic().build(); let co = ColliderBuilder::ball(0.5).build(); let hrb = bodies.insert(rb); - let coh = colliders.insert(co, hrb, &mut bodies); + let coh = colliders.insert_with_parent(co, hrb, &mut bodies); let mut events = Vec::new(); broad_phase.update(0.0, &mut colliders, &[coh], &[], &mut events); @@ -610,7 +610,7 @@ mod test { let rb = RigidBodyBuilder::new_dynamic().build(); let co = ColliderBuilder::ball(0.5).build(); let hrb = bodies.insert(rb); - let coh = colliders.insert(co, hrb, &mut bodies); + let coh = colliders.insert_with_parent(co, hrb, &mut bodies); // Make sure the proxy handles is recycled properly. broad_phase.update(0.0, &mut colliders, &[coh], &[], &mut events); diff --git a/src/geometry/collider.rs b/src/geometry/collider.rs index 08295c1..0101a09 100644 --- a/src/geometry/collider.rs +++ b/src/geometry/collider.rs @@ -1,11 +1,12 @@ use crate::dynamics::{CoefficientCombineRule, MassProperties, RigidBodyHandle}; use crate::geometry::{ - ColliderBroadPhaseData, ColliderChanges, ColliderGroups, ColliderMassProperties, - ColliderMaterial, ColliderParent, ColliderPosition, ColliderShape, ColliderType, - InteractionGroups, SharedShape, SolverFlags, + ActiveCollisionTypes, ColliderBroadPhaseData, ColliderChanges, ColliderFlags, + ColliderMassProps, ColliderMaterial, ColliderParent, ColliderPosition, ColliderShape, + ColliderType, InteractionGroups, SharedShape, }; use crate::math::{AngVector, Isometry, Point, Real, Rotation, Vector, DIM}; use crate::parry::transformation::vhacd::VHACDParameters; +use crate::pipeline::{ActiveEvents, ActiveHooks}; use na::Unit; use parry::bounding_volume::AABB; use parry::shape::Shape; @@ -18,12 +19,12 @@ use parry::shape::Shape; pub struct Collider { pub(crate) co_type: ColliderType, pub(crate) co_shape: ColliderShape, - pub(crate) co_mprops: ColliderMassProperties, + pub(crate) co_mprops: ColliderMassProps, pub(crate) co_changes: ColliderChanges, - pub(crate) co_parent: ColliderParent, + pub(crate) co_parent: Option, pub(crate) co_pos: ColliderPosition, pub(crate) co_material: ColliderMaterial, - pub(crate) co_groups: ColliderGroups, + pub(crate) co_flags: ColliderFlags, pub(crate) co_bf_data: ColliderBroadPhaseData, /// User-defined data associated to this rigid-body. pub user_data: u128, @@ -31,14 +32,13 @@ pub struct Collider { impl Collider { pub(crate) fn reset_internal_references(&mut self) { - self.co_parent.handle = RigidBodyHandle::invalid(); self.co_bf_data.proxy_index = crate::INVALID_U32; self.co_changes = ColliderChanges::all(); } /// The rigid body this collider is attached to. - pub fn parent(&self) -> RigidBodyHandle { - self.co_parent.handle + pub fn parent(&self) -> Option { + self.co_parent.map(|parent| parent.handle) } /// Is this collider a sensor? @@ -46,6 +46,46 @@ impl Collider { self.co_type.is_sensor() } + /// The physics hooks enabled for this collider. + pub fn active_hooks(&self) -> ActiveHooks { + self.co_flags.active_hooks + } + + /// Sets the physics hooks enabled for this collider. + pub fn set_active_hooks(&mut self, active_hooks: ActiveHooks) { + self.co_flags.active_hooks = active_hooks; + } + + /// The events enabled for this collider. + pub fn active_events(&self) -> ActiveEvents { + self.co_flags.active_events + } + + /// Sets the events enabled for this collider. + pub fn set_active_events(&mut self, active_events: ActiveEvents) { + self.co_flags.active_events = active_events; + } + + /// The collision types enabled for this collider. + pub fn active_collision_types(&self) -> ActiveCollisionTypes { + self.co_flags.active_collision_types + } + + /// Sets the collision types enabled for this collider. + pub fn set_active_collision_types(&mut self, active_collision_types: ActiveCollisionTypes) { + self.co_flags.active_collision_types = active_collision_types; + } + + /// The friction coefficient of this collider. + pub fn friction(&self) -> Real { + self.co_material.friction + } + + /// Sets the friction coefficient of this collider. + pub fn set_friction(&mut self, coefficient: Real) { + self.co_material.friction = coefficient + } + /// The combine rule used by this collider to combine its friction /// coefficient with the friction coefficient of the other collider it /// is in contact with. @@ -60,6 +100,16 @@ impl Collider { self.co_material.friction_combine_rule = rule; } + /// The restitution coefficient of this collider. + pub fn restitution(&self) -> Real { + self.co_material.restitution + } + + /// Sets the restitution coefficient of this collider. + pub fn set_restitution(&mut self, coefficient: Real) { + self.co_material.restitution = coefficient + } + /// The combine rule used by this collider to combine its restitution /// coefficient with the restitution coefficient of the other collider it /// is in contact with. @@ -86,15 +136,22 @@ impl Collider { } } - #[doc(hidden)] - pub fn set_position_debug(&mut self, position: Isometry) { - self.co_pos.0 = position; + /// Sets the translational part of this collider's position. + pub fn set_translation(&mut self, translation: Vector) { + self.co_changes.insert(ColliderChanges::POSITION); + self.co_pos.0.translation.vector = translation; } - /// The position of this collider expressed in the local-space of the rigid-body it is attached to. - #[deprecated(note = "use `.position_wrt_parent()` instead.")] - pub fn delta(&self) -> &Isometry { - &self.co_parent.pos_wrt_parent + /// Sets the rotational part of this collider's position. + pub fn set_rotation(&mut self, rotation: AngVector) { + self.co_changes.insert(ColliderChanges::POSITION); + self.co_pos.0.rotation = Rotation::new(rotation); + } + + /// Sets the position of this collider. + pub fn set_position(&mut self, position: Isometry) { + self.co_changes.insert(ColliderChanges::POSITION); + self.co_pos.0 = position; } /// The world-space position of this collider. @@ -102,40 +159,56 @@ impl Collider { &self.co_pos } + /// The translational part of this rigid-body's position. + pub fn translation(&self) -> &Vector { + &self.co_pos.0.translation.vector + } + + /// The rotational part of this rigid-body's position. + pub fn rotation(&self) -> &Rotation { + &self.co_pos.0.rotation + } + /// The position of this collider wrt the body it is attached to. - pub fn position_wrt_parent(&self) -> &Isometry { - &self.co_parent.pos_wrt_parent + pub fn position_wrt_parent(&self) -> Option<&Isometry> { + self.co_parent.as_ref().map(|p| &p.pos_wrt_parent) } /// Sets the position of this collider wrt. its parent rigid-body. - pub fn set_position_wrt_parent(&mut self, position: Isometry) { + /// + /// Panics if the collider is not attached to a rigid-body. + pub fn set_position_wrt_parent(&mut self, pos_wrt_parent: Isometry) { self.co_changes.insert(ColliderChanges::PARENT); - self.co_parent.pos_wrt_parent = position; + let co_parent = self + .co_parent + .as_mut() + .expect("This collider has no parent."); + co_parent.pos_wrt_parent = pos_wrt_parent; } /// The collision groups used by this collider. pub fn collision_groups(&self) -> InteractionGroups { - self.co_groups.collision_groups + self.co_flags.collision_groups } /// Sets the collision groups of this collider. pub fn set_collision_groups(&mut self, groups: InteractionGroups) { - if self.co_groups.collision_groups != groups { + if self.co_flags.collision_groups != groups { self.co_changes.insert(ColliderChanges::GROUPS); - self.co_groups.collision_groups = groups; + self.co_flags.collision_groups = groups; } } /// The solver groups used by this collider. pub fn solver_groups(&self) -> InteractionGroups { - self.co_groups.solver_groups + self.co_flags.solver_groups } /// Sets the solver groups of this collider. pub fn set_solver_groups(&mut self, groups: InteractionGroups) { - if self.co_groups.solver_groups != groups { + if self.co_flags.solver_groups != groups { self.co_changes.insert(ColliderChanges::GROUPS); - self.co_groups.solver_groups = groups; + self.co_flags.solver_groups = groups; } } @@ -147,8 +220,8 @@ impl Collider { /// The density of this collider, if set. pub fn density(&self) -> Option { match &self.co_mprops { - ColliderMassProperties::Density(density) => Some(*density), - ColliderMassProperties::MassProperties(_) => None, + ColliderMassProps::Density(density) => Some(*density), + ColliderMassProps::MassProperties(_) => None, } } @@ -188,8 +261,8 @@ impl Collider { /// Compute the local-space mass properties of this collider. pub fn mass_properties(&self) -> MassProperties { match &self.co_mprops { - ColliderMassProperties::Density(density) => self.co_shape.mass_properties(*density), - ColliderMassProperties::MassProperties(mass_properties) => **mass_properties, + ColliderMassProps::Density(density) => self.co_shape.mass_properties(*density), + ColliderMassProps::MassProperties(mass_properties) => **mass_properties, } } } @@ -213,13 +286,16 @@ pub struct ColliderBuilder { pub restitution: Real, /// The rule used to combine two restitution coefficients. pub restitution_combine_rule: CoefficientCombineRule, - /// The position of this collider relative to the local frame of the rigid-body it is attached to. - pub pos_wrt_parent: Isometry, + /// The position of this collider. + pub position: Isometry, /// Is this collider a sensor? pub is_sensor: bool, - /// Do we have to always call the contact modifier - /// on this collider? - pub modify_solver_contacts: bool, + /// Contact pairs enabled for this collider. + pub active_collision_types: ActiveCollisionTypes, + /// Physics hooks enabled for this collider. + pub active_hooks: ActiveHooks, + /// Events enabled for this collider. + pub active_events: ActiveEvents, /// The user-data of the collider being built. pub user_data: u128, /// The collision groups for the collider being built. @@ -237,14 +313,16 @@ impl ColliderBuilder { mass_properties: None, friction: Self::default_friction(), restitution: 0.0, - pos_wrt_parent: Isometry::identity(), + position: Isometry::identity(), is_sensor: false, user_data: 0, collision_groups: InteractionGroups::all(), solver_groups: InteractionGroups::all(), friction_combine_rule: CoefficientCombineRule::Average, restitution_combine_rule: CoefficientCombineRule::Average, - modify_solver_contacts: false, + active_collision_types: ActiveCollisionTypes::default(), + active_hooks: ActiveHooks::empty(), + active_events: ActiveEvents::empty(), } } @@ -489,6 +567,11 @@ impl ColliderBuilder { 0.5 } + /// The default density used by the collider builder. + pub fn default_density() -> Real { + 1.0 + } + /// Sets an arbitrary user-defined 128-bit integer associated to the colliders built by this builder. pub fn user_data(mut self, data: u128) -> Self { self.user_data = data; @@ -522,10 +605,21 @@ impl ColliderBuilder { self } - /// If set to `true` then the physics hooks will always run to modify - /// contacts involving this collider. - pub fn modify_solver_contacts(mut self, modify_solver_contacts: bool) -> Self { - self.modify_solver_contacts = modify_solver_contacts; + /// The set of physics hooks enabled for this collider. + pub fn active_hooks(mut self, active_hooks: ActiveHooks) -> Self { + self.active_hooks = active_hooks; + self + } + + /// The set of events enabled for this collider. + pub fn active_events(mut self, active_events: ActiveEvents) -> Self { + self.active_events = active_events; + self + } + + /// The set of active collision types for this collider. + pub fn active_collision_types(mut self, active_collision_types: ActiveCollisionTypes) -> Self { + self.active_collision_types = active_collision_types; self } @@ -571,71 +665,61 @@ impl ColliderBuilder { self } - /// Sets the initial translation of the collider to be created, - /// relative to the rigid-body it is attached to. - #[cfg(feature = "dim2")] - pub fn translation(mut self, x: Real, y: Real) -> Self { - self.pos_wrt_parent.translation.x = x; - self.pos_wrt_parent.translation.y = y; + /// Sets the initial translation of the collider to be created. + /// + /// If the collider will be attached to a rigid-body, this sets the translation relative to the + /// rigid-body it will be attached to. + pub fn translation(mut self, translation: Vector) -> Self { + self.position.translation.vector = translation; self } - /// Sets the initial translation of the collider to be created, - /// relative to the rigid-body it is attached to. - #[cfg(feature = "dim3")] - pub fn translation(mut self, x: Real, y: Real, z: Real) -> Self { - self.pos_wrt_parent.translation.x = x; - self.pos_wrt_parent.translation.y = y; - self.pos_wrt_parent.translation.z = z; - self - } - - /// Sets the initial orientation of the collider to be created, - /// relative to the rigid-body it is attached to. + /// Sets the initial orientation of the collider to be created. + /// + /// If the collider will be attached to a rigid-body, this sets the orientation relative to the + /// rigid-body it will be attached to. pub fn rotation(mut self, angle: AngVector) -> Self { - self.pos_wrt_parent.rotation = Rotation::new(angle); + self.position.rotation = Rotation::new(angle); self } - /// Sets the initial position (translation and orientation) of the collider to be created, - /// relative to the rigid-body it is attached to. - pub fn position_wrt_parent(mut self, pos: Isometry) -> Self { - self.pos_wrt_parent = pos; - self - } - - /// Sets the initial position (translation and orientation) of the collider to be created, - /// relative to the rigid-body it is attached to. - #[deprecated(note = "Use `.position_wrt_parent` instead.")] + /// Sets the initial position (translation and orientation) of the collider to be created. + /// + /// If the collider will be attached to a rigid-body, this sets the position relative + /// to the rigid-body it will be attached to. pub fn position(mut self, pos: Isometry) -> Self { - self.pos_wrt_parent = pos; + self.position = pos; + self + } + + /// Sets the initial position (translation and orientation) of the collider to be created, + /// relative to the rigid-body it is attached to. + #[deprecated(note = "Use `.position` instead.")] + pub fn position_wrt_parent(mut self, pos: Isometry) -> Self { + self.position = pos; self } /// Set the position of this collider in the local-space of the rigid-body it is attached to. - #[deprecated(note = "Use `.position_wrt_parent` instead.")] + #[deprecated(note = "Use `.position` instead.")] pub fn delta(mut self, delta: Isometry) -> Self { - self.pos_wrt_parent = delta; + self.position = delta; self } /// Builds a new collider attached to the given rigid-body. pub fn build(&self) -> Collider { - let (co_changes, co_pos, co_bf_data, co_shape, co_type, co_groups, co_material, co_mprops) = + let (co_changes, co_pos, co_bf_data, co_shape, co_type, co_material, co_flags, co_mprops) = self.components(); - let co_parent = ColliderParent { - pos_wrt_parent: co_pos.0, - handle: RigidBodyHandle::invalid(), - }; Collider { co_shape, co_mprops, co_material, - co_parent, + co_parent: None, co_changes, co_pos, co_bf_data, - co_groups, + co_flags, co_type, user_data: self.user_data, } @@ -650,24 +734,18 @@ impl ColliderBuilder { ColliderBroadPhaseData, ColliderShape, ColliderType, - ColliderGroups, ColliderMaterial, - ColliderMassProperties, + ColliderFlags, + ColliderMassProps, ) { let mass_info = if let Some(mp) = self.mass_properties { - ColliderMassProperties::MassProperties(Box::new(mp)) + ColliderMassProps::MassProperties(Box::new(mp)) } else { - let default_density = if self.is_sensor { 0.0 } else { 1.0 }; + let default_density = Self::default_density(); let density = self.density.unwrap_or(default_density); - ColliderMassProperties::Density(density) + ColliderMassProps::Density(density) }; - let mut solver_flags = SolverFlags::default(); - solver_flags.set( - SolverFlags::MODIFY_SOLVER_CONTACTS, - self.modify_solver_contacts, - ); - let co_shape = self.shape.clone(); let co_mprops = mass_info; let co_material = ColliderMaterial { @@ -675,15 +753,17 @@ impl ColliderBuilder { restitution: self.restitution, friction_combine_rule: self.friction_combine_rule, restitution_combine_rule: self.restitution_combine_rule, - solver_flags, }; - let co_changes = ColliderChanges::all(); - let co_pos = ColliderPosition(self.pos_wrt_parent); - let co_bf_data = ColliderBroadPhaseData::default(); - let co_groups = ColliderGroups { + let co_flags = ColliderFlags { collision_groups: self.collision_groups, solver_groups: self.solver_groups, + active_collision_types: self.active_collision_types, + active_hooks: self.active_hooks, + active_events: self.active_events, }; + let co_changes = ColliderChanges::all(); + let co_pos = ColliderPosition(self.position); + let co_bf_data = ColliderBroadPhaseData::default(); let co_type = if self.is_sensor { ColliderType::Sensor } else { @@ -696,8 +776,8 @@ impl ColliderBuilder { co_bf_data, co_shape, co_type, - co_groups, co_material, + co_flags, co_mprops, ) } diff --git a/src/geometry/collider_components.rs b/src/geometry/collider_components.rs index a02c706..111f527 100644 --- a/src/geometry/collider_components.rs +++ b/src/geometry/collider_components.rs @@ -1,7 +1,8 @@ -use crate::dynamics::{CoefficientCombineRule, MassProperties, RigidBodyHandle}; -use crate::geometry::{InteractionGroups, SAPProxyIndex, Shape, SharedShape, SolverFlags}; +use crate::dynamics::{CoefficientCombineRule, MassProperties, RigidBodyHandle, RigidBodyType}; +use crate::geometry::{InteractionGroups, SAPProxyIndex, Shape, SharedShape}; use crate::math::{Isometry, Real}; use crate::parry::partitioning::IndexedData; +use crate::pipeline::{ActiveEvents, ActiveHooks}; use std::ops::Deref; /// The unique identifier of a collider added to a collider set. @@ -117,7 +118,7 @@ pub type ColliderShape = SharedShape; #[derive(Clone)] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] /// The mass-properties of a collider. -pub enum ColliderMassProperties { +pub enum ColliderMassProps { /// The collider is given a density. /// /// Its actual `MassProperties` are computed automatically with @@ -127,13 +128,19 @@ pub enum ColliderMassProperties { MassProperties(Box), } -impl Default for ColliderMassProperties { +impl Default for ColliderMassProps { fn default() -> Self { - ColliderMassProperties::Density(1.0) + ColliderMassProps::Density(1.0) } } -impl ColliderMassProperties { +impl From for ColliderMassProps { + fn from(mprops: MassProperties) -> Self { + ColliderMassProps::MassProperties(Box::new(mprops)) + } +} + +impl ColliderMassProps { /// The mass-properties of this collider. /// /// If `self` is the `Density` variant, then this computes the mass-properties based @@ -201,27 +208,6 @@ where } } -#[derive(Copy, Clone, Debug)] -#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] -/// The groups of this collider, for filtering contact and solver pairs. -pub struct ColliderGroups { - /// The groups controlling the pairs of colliders that can interact (generate - /// interaction events or contacts). - pub collision_groups: InteractionGroups, - /// The groups controlling the pairs of collider that have their contact - /// points taken into account for force computation. - pub solver_groups: InteractionGroups, -} - -impl Default for ColliderGroups { - fn default() -> Self { - Self { - collision_groups: InteractionGroups::default(), - solver_groups: InteractionGroups::default(), - } - } -} - #[derive(Copy, Clone, Debug)] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] /// The constraints solver-related properties of this collider (friction, restitution, etc.) @@ -241,9 +227,6 @@ pub struct ColliderMaterial { pub friction_combine_rule: CoefficientCombineRule, /// The rule applied to combine the restitution coefficients of two colliders. pub restitution_combine_rule: CoefficientCombineRule, - /// The solver flags attached to this collider in order to customize the way the - /// constraints solver will work with contacts involving this collider. - pub solver_flags: SolverFlags, } impl ColliderMaterial { @@ -264,7 +247,133 @@ impl Default for ColliderMaterial { restitution: 0.0, friction_combine_rule: CoefficientCombineRule::default(), restitution_combine_rule: CoefficientCombineRule::default(), - solver_flags: SolverFlags::default(), + } + } +} + +bitflags::bitflags! { + #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] + /// Flags affecting whether or not collision-detection happens between two colliders + /// depending on the type of rigid-bodies they are attached to. + pub struct ActiveCollisionTypes: u16 { + /// Enable collision-detection between a collider attached to a dynamic body + /// and another collider attached to a dynamic body. + const DYNAMIC_DYNAMIC = 0b0000_0000_0000_0001; + /// Enable collision-detection between a collider attached to a dynamic body + /// and another collider attached to a kinematic body. + const DYNAMIC_KINEMATIC = 0b0000_0000_0000_1100; + /// Enable collision-detection between a collider attached to a dynamic body + /// and another collider attached to a static body (or not attached to any body). + const DYNAMIC_STATIC = 0b0000_0000_0000_0010; + /// Enable collision-detection between a collider attached to a kinematic body + /// and another collider attached to a kinematic body. + const KINEMATIC_KINEMATIC = 0b1100_1100_0000_0000; + + /// Enable collision-detection between a collider attached to a kinematic body + /// and another collider attached to a static body (or not attached to any body). + const KINEMATIC_STATIC = 0b0010_0010_0000_0000; + + /// Enable collision-detection between a collider attached to a static body (or + /// not attached to any body) and another collider attached to a static body (or + /// not attached to any body). + const STATIC_STATIC = 0b0000_0000_0010_0000; + } +} + +impl ActiveCollisionTypes { + /// Test whether contact should be computed between two rigid-bodies with the given types. + pub fn test(self, rb_type1: RigidBodyType, rb_type2: RigidBodyType) -> bool { + // NOTE: This test is quite complicated so here is an explanation. + // First, we associate the following bit masks: + // - DYNAMIC = 0001 + // - STATIC = 0010 + // - KINEMATIC = 1100 + // These are equal to the bits indexed by `RigidBodyType as u32`. + // The bit masks defined by ActiveCollisionTypes are defined is such a way + // that the first part of the variant name (e.g. DYNAMIC_*) indicates which + // groups of four bits should be considered: + // - DYNAMIC_* = the first group of four bits. + // - STATIC_* = the second group of four bits. + // - KINEMATIC_* = the third and fourth groups of four bits. + // The second part of the variant name (e.g. *_DYNAMIC) indicates the value + // of the aforementioned groups of four bits. + // For example, DYNAMIC_STATIC means that the first group of four bits (because + // of DYNAMIC_*) must have the value 0010 (because of *_STATIC). That gives + // us 0b0000_0000_0000_0010 for the DYNAMIC_STATIC_VARIANT. + // + // The KINEMATIC_* is special because it occupies two groups of four bits. This is + // because it combines both KinematicPositionBased and KinematicVelocityBased. + // + // Now that we have a way of building these bit masks, let's see how we use them. + // Given a pair of rigid-body types, the first rigid-body type is used to select + // the group of four bits we want to test (the selection is done by to the + // `>> (rb_type1 as u32 * 4) & 0b0000_1111`) and the second rigid-body type is + // used to form the bit mask we test this group of four bits against. + // In other word, the selection of the group of four bits tells us "for this type + // of rigid-body I can have collision with rigid-body types with these bit representation". + // Then the `(1 << rb_type2)` gives us the bit-representation of the rigid-body type, + // which needs to be checked. + // + // Because that test must be symmetric, we perform two similar tests by swapping + // rb_type1 and rb_type2. + ((self.bits >> (rb_type1 as u32 * 4)) & 0b0000_1111) & (1 << rb_type2 as u32) != 0 + || ((self.bits >> (rb_type2 as u32 * 4)) & 0b0000_1111) & (1 << rb_type1 as u32) != 0 + } +} + +impl Default for ActiveCollisionTypes { + fn default() -> Self { + ActiveCollisionTypes::DYNAMIC_DYNAMIC + | ActiveCollisionTypes::DYNAMIC_KINEMATIC + | ActiveCollisionTypes::DYNAMIC_STATIC + } +} + +#[derive(Copy, Clone, Debug)] +#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] +/// A set of flags for controlling collision/intersection filtering, modification, and events. +pub struct ColliderFlags { + /// Controls whether collision-detection happens between two colliders depending on + /// the type of the rigid-bodies they are attached to. + pub active_collision_types: ActiveCollisionTypes, + /// The groups controlling the pairs of colliders that can interact (generate + /// interaction events or contacts). + pub collision_groups: InteractionGroups, + /// The groups controlling the pairs of collider that have their contact + /// points taken into account for force computation. + pub solver_groups: InteractionGroups, + /// The physics hooks enabled for contact pairs and intersection pairs involving this collider. + pub active_hooks: ActiveHooks, + /// The events enabled for this collider. + pub active_events: ActiveEvents, +} + +impl Default for ColliderFlags { + fn default() -> Self { + Self { + active_collision_types: ActiveCollisionTypes::default(), + collision_groups: InteractionGroups::all(), + solver_groups: InteractionGroups::all(), + active_hooks: ActiveHooks::empty(), + active_events: ActiveEvents::empty(), + } + } +} + +impl From for ColliderFlags { + fn from(active_hooks: ActiveHooks) -> Self { + Self { + active_hooks, + ..Default::default() + } + } +} + +impl From for ColliderFlags { + fn from(active_events: ActiveEvents) -> Self { + Self { + active_events, + ..Default::default() } } } diff --git a/src/geometry/collider_set.rs b/src/geometry/collider_set.rs index 14eb54c..9584015 100644 --- a/src/geometry/collider_set.rs +++ b/src/geometry/collider_set.rs @@ -2,7 +2,7 @@ use crate::data::arena::Arena; use crate::data::{ComponentSet, ComponentSetMut, ComponentSetOption}; use crate::dynamics::{IslandManager, RigidBodyHandle, RigidBodySet}; use crate::geometry::{ - Collider, ColliderBroadPhaseData, ColliderGroups, ColliderMassProperties, ColliderMaterial, + Collider, ColliderBroadPhaseData, ColliderFlags, ColliderMassProps, ColliderMaterial, ColliderParent, ColliderPosition, ColliderShape, ColliderType, }; use crate::geometry::{ColliderChanges, ColliderHandle}; @@ -59,14 +59,21 @@ macro_rules! impl_field_component_set( impl_field_component_set!(ColliderType, co_type); impl_field_component_set!(ColliderShape, co_shape); -impl_field_component_set!(ColliderMassProperties, co_mprops); +impl_field_component_set!(ColliderMassProps, co_mprops); impl_field_component_set!(ColliderChanges, co_changes); -impl_field_component_set!(ColliderParent, co_parent); impl_field_component_set!(ColliderPosition, co_pos); impl_field_component_set!(ColliderMaterial, co_material); -impl_field_component_set!(ColliderGroups, co_groups); +impl_field_component_set!(ColliderFlags, co_flags); impl_field_component_set!(ColliderBroadPhaseData, co_bf_data); +impl ComponentSetOption for ColliderSet { + #[inline(always)] + fn get(&self, handle: crate::data::Index) -> Option<&ColliderParent> { + self.get(ColliderHandle(handle)) + .and_then(|b| b.co_parent.as_ref()) + } +} + impl ColliderSet { /// Create a new empty set of colliders. pub fn new() -> Self { @@ -122,16 +129,35 @@ impl ColliderSet { } /// Inserts a new collider to this set and retrieve its handle. - pub fn insert( + pub fn insert(&mut self, mut coll: Collider) -> ColliderHandle { + // Make sure the internal links are reset, they may not be + // if this rigid-body was obtained by cloning another one. + coll.reset_internal_references(); + coll.co_parent = None; + let handle = ColliderHandle(self.colliders.insert(coll)); + self.modified_colliders.push(handle); + handle + } + + /// Inserts a new collider to this set, attach it to the given rigid-body, and retrieve its handle. + pub fn insert_with_parent( &mut self, mut coll: Collider, parent_handle: RigidBodyHandle, bodies: &mut RigidBodySet, ) -> ColliderHandle { // Make sure the internal links are reset, they may not be - // if this rigid-body was obtained by cloning another one. + // if this collider was obtained by cloning another one. coll.reset_internal_references(); - coll.co_parent.handle = parent_handle; + + if let Some(prev_parent) = &mut coll.co_parent { + prev_parent.handle = parent_handle; + } else { + coll.co_parent = Some(ColliderParent { + handle: parent_handle, + pos_wrt_parent: coll.co_pos.0, + }); + } // NOTE: we use `get_mut` instead of `get_mut_internal` so that the // modification flag is updated properly. @@ -144,7 +170,7 @@ impl ColliderSet { let coll = self.colliders.get_mut(handle.0).unwrap(); parent.add_collider( handle, - &mut coll.co_parent, + coll.co_parent.as_mut().unwrap(), &mut coll.co_pos, &coll.co_shape, &coll.co_mprops, @@ -170,13 +196,15 @@ impl ColliderSet { */ // NOTE: we use `get_mut_internal_with_modification_tracking` instead of `get_mut_internal` so that the // modification flag is updated properly. - if let Some(parent) = - bodies.get_mut_internal_with_modification_tracking(collider.co_parent.handle) - { - parent.remove_collider_internal(handle, &collider); + if let Some(co_parent) = &collider.co_parent { + if let Some(parent) = + bodies.get_mut_internal_with_modification_tracking(co_parent.handle) + { + parent.remove_collider_internal(handle, &collider); - if wake_up { - islands.wake_up(bodies, collider.co_parent.handle, true); + if wake_up { + islands.wake_up(bodies, co_parent.handle, true); + } } } diff --git a/src/geometry/contact_pair.rs b/src/geometry/contact_pair.rs index 5a568fa..f4e7834 100644 --- a/src/geometry/contact_pair.rs +++ b/src/geometry/contact_pair.rs @@ -1,5 +1,5 @@ use crate::dynamics::RigidBodyHandle; -use crate::geometry::{ColliderPair, Contact, ContactManifold}; +use crate::geometry::{ColliderHandle, Contact, ContactManifold}; use crate::math::{Point, Real, Vector}; use parry::query::ContactManifoldsWorkspace; @@ -10,9 +10,6 @@ bitflags::bitflags! { /// The constraint solver will take this contact manifold into /// account for force computation. const COMPUTE_IMPULSES = 0b001; - /// The user-defined physics hooks will be used to - /// modify the solver contacts of this contact manifold. - const MODIFY_SOLVER_CONTACTS = 0b010; } } @@ -56,8 +53,10 @@ impl Default for ContactData { #[derive(Clone)] /// The description of all the contacts between a pair of colliders. pub struct ContactPair { - /// The pair of colliders involved. - pub pair: ColliderPair, + /// The first collider involved in the contact pair. + pub collider1: ColliderHandle, + /// The second collider involved in the contact pair. + pub collider2: ColliderHandle, /// The set of contact manifolds between the two colliders. /// /// All contact manifold contain themselves contact points between the colliders. @@ -68,9 +67,10 @@ pub struct ContactPair { } impl ContactPair { - pub(crate) fn new(pair: ColliderPair) -> Self { + pub(crate) fn new(collider1: ColliderHandle, collider2: ColliderHandle) -> Self { Self { - pair, + collider1, + collider2, has_any_active_contact: false, manifolds: Vec::new(), workspace: None, diff --git a/src/geometry/interaction_groups.rs b/src/geometry/interaction_groups.rs index 37b7586..b2961d9 100644 --- a/src/geometry/interaction_groups.rs +++ b/src/geometry/interaction_groups.rs @@ -1,56 +1,66 @@ -#[repr(transparent)] -#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] -#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] /// Pairwise filtering using bit masks. /// -/// This filtering method is based on two 16-bit values: -/// - The interaction groups (the 16 left-most bits of `self.0`). -/// - The interaction mask (the 16 right-most bits of `self.0`). +/// This filtering method is based on two 32-bit values: +/// - The interaction groups memberships. +/// - The interaction groups filter. /// /// An interaction is allowed between two filters `a` and `b` when two conditions /// are met simultaneously: -/// - The interaction groups of `a` has at least one bit set to `1` in common with the interaction mask of `b`. -/// - The interaction groups of `b` has at least one bit set to `1` in common with the interaction mask of `a`. +/// - The groups membership of `a` has at least one bit set to `1` in common with the groups filter of `b`. +/// - The groups membership of `b` has at least one bit set to `1` in common with the groups filter of `a`. /// /// In other words, interactions are allowed between two filter iff. the following condition is met: /// ```ignore -/// ((self.0 >> 16) & rhs.0) != 0 && ((rhs.0 >> 16) & self.0) != 0 +/// (self.memberships & rhs.filter) != 0 && (rhs.memberships & self.filter) != 0 /// ``` -pub struct InteractionGroups(pub u32); +#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] +#[repr(C)] +pub struct InteractionGroups { + /// Groups memberships. + pub memberships: u32, + /// Groups filter. + pub filter: u32, +} impl InteractionGroups { /// Initializes with the given interaction groups and interaction mask. - pub const fn new(groups: u16, masks: u16) -> Self { - Self::none().with_groups(groups).with_mask(masks) + pub const fn new(memberships: u32, filter: u32) -> Self { + Self { + memberships, + filter, + } } /// Allow interaction with everything. pub const fn all() -> Self { - Self(u32::MAX) + Self::new(u32::MAX, u32::MAX) } /// Prevent all interactions. pub const fn none() -> Self { - Self(0) + Self::new(0, 0) } /// Sets the group this filter is part of. - pub const fn with_groups(self, groups: u16) -> Self { - Self((self.0 & 0x0000ffff) | ((groups as u32) << 16)) + pub const fn with_memberships(mut self, memberships: u32) -> Self { + self.memberships = memberships; + self } /// Sets the interaction mask of this filter. - pub const fn with_mask(self, mask: u16) -> Self { - Self((self.0 & 0xffff0000) | (mask as u32)) + pub const fn with_filter(mut self, filter: u32) -> Self { + self.filter = filter; + self } - /// Check if interactions should be allowed based on the interaction groups and mask. + /// Check if interactions should be allowed based on the interaction memberships and filter. /// - /// An interaction is allowed iff. the groups of `self` contain at least one bit set to 1 in common - /// with the mask of `rhs`, and vice-versa. + /// An interaction is allowed iff. the memberships of `self` contain at least one bit set to 1 in common + /// with the filter of `rhs`, and vice-versa. #[inline] pub const fn test(self, rhs: Self) -> bool { - ((self.0 >> 16) & rhs.0) != 0 && ((rhs.0 >> 16) & self.0) != 0 + (self.memberships & rhs.filter) != 0 && (rhs.memberships & self.filter) != 0 } } diff --git a/src/geometry/narrow_phase.rs b/src/geometry/narrow_phase.rs index 57504f5..185cf0c 100644 --- a/src/geometry/narrow_phase.rs +++ b/src/geometry/narrow_phase.rs @@ -7,15 +7,17 @@ use crate::dynamics::{ IslandManager, RigidBodyActivation, RigidBodyDominance, RigidBodyIds, RigidBodyType, }; use crate::geometry::{ - BroadPhasePairEvent, ColliderChanges, ColliderGraphIndex, ColliderGroups, ColliderHandle, - ColliderMaterial, ColliderPair, ColliderParent, ColliderPosition, ColliderShape, ColliderType, - ContactData, ContactEvent, ContactManifold, ContactManifoldData, ContactPair, InteractionGraph, + BroadPhasePairEvent, ColliderChanges, ColliderGraphIndex, ColliderHandle, ColliderMaterial, + ColliderPair, ColliderParent, ColliderPosition, ColliderShape, ColliderType, ContactData, + ContactEvent, ContactManifold, ContactManifoldData, ContactPair, InteractionGraph, IntersectionEvent, SolverContact, SolverFlags, }; use crate::math::{Real, Vector}; use crate::pipeline::{ - ContactModificationContext, EventHandler, PairFilterContext, PhysicsHooks, PhysicsHooksFlags, + ActiveEvents, ActiveHooks, ContactModificationContext, EventHandler, PairFilterContext, + PhysicsHooks, }; +use crate::prelude::ColliderFlags; use parry::query::{DefaultQueryDispatcher, PersistentQueryDispatcher}; use parry::utils::IsometryOpt; use std::collections::HashMap; @@ -98,25 +100,80 @@ impl NarrowPhase { } /// All the contacts involving the given collider. - pub fn contacts_with( + /// + /// It is strongly recommended to use the [`NarrowPhase::contacts_with`] method instead. This + /// method can be used if the generation number of the collider handle isn't known. + pub fn contacts_with_unknown_gen(&self, collider: u32) -> impl Iterator { + self.graph_indices + .get_unknown_gen(collider) + .map(|id| id.contact_graph_index) + .into_iter() + .flat_map(move |id| self.contact_graph.interactions_with(id)) + .map(|pair| pair.2) + } + + /// All the contacts involving the given collider. + pub fn contacts_with<'a>( &self, collider: ColliderHandle, - ) -> Option> { - let id = self.graph_indices.get(collider.0)?; - Some(self.contact_graph.interactions_with(id.contact_graph_index)) + ) -> impl Iterator { + self.graph_indices + .get(collider.0) + .map(|id| id.contact_graph_index) + .into_iter() + .flat_map(move |id| self.contact_graph.interactions_with(id)) + .map(|pair| pair.2) + } + + /// All the intersections involving the given collider. + /// + /// It is strongly recommended to use the [`NarrowPhase::intersections_with`] method instead. + /// This method can be used if the generation number of the collider handle isn't known. + pub fn intersections_with_unknown_gen( + &self, + collider: u32, + ) -> impl Iterator + '_ { + self.graph_indices + .get_unknown_gen(collider) + .map(|id| id.intersection_graph_index) + .into_iter() + .flat_map(move |id| { + self.intersection_graph + .interactions_with(id) + .map(|e| (e.0, e.1, *e.2)) + }) } /// All the intersections involving the given collider. pub fn intersections_with( &self, collider: ColliderHandle, - ) -> Option + '_> { - let id = self.graph_indices.get(collider.0)?; - Some( - self.intersection_graph - .interactions_with(id.intersection_graph_index) - .map(|e| (e.0, e.1, *e.2)), - ) + ) -> impl Iterator + '_ { + self.graph_indices + .get(collider.0) + .map(|id| id.intersection_graph_index) + .into_iter() + .flat_map(move |id| { + self.intersection_graph + .interactions_with(id) + .map(|e| (e.0, e.1, *e.2)) + }) + } + + /// The contact pair involving two specific colliders. + /// + /// It is strongly recommended to use the [`NarrowPhase::contact_pair`] method instead. This + /// method can be used if the generation number of the collider handle isn't known. + /// + /// If this returns `None`, there is no contact between the two colliders. + /// If this returns `Some`, then there may be a contact between the two colliders. Check the + /// result [`ContactPair::has_any_active_collider`] method to see if there is an actual contact. + pub fn contact_pair_unknown_gen(&self, collider1: u32, collider2: u32) -> Option<&ContactPair> { + let id1 = self.graph_indices.get_unknown_gen(collider1)?; + let id2 = self.graph_indices.get_unknown_gen(collider2)?; + self.contact_graph + .interaction_pair(id1.contact_graph_index, id2.contact_graph_index) + .map(|c| c.2) } /// The contact pair involving two specific colliders. @@ -136,6 +193,21 @@ impl NarrowPhase { .map(|c| c.2) } + /// The intersection pair involving two specific colliders. + /// + /// It is strongly recommended to use the [`NarrowPhase::intersection_pair`] method instead. This + /// method can be used if the generation number of the collider handle isn't known. + /// + /// If this returns `None` or `Some(false)`, then there is no intersection between the two colliders. + /// If this returns `Some(true)`, then there may be an intersection between the two colliders. + pub fn intersection_pair_unknown_gen(&self, collider1: u32, collider2: u32) -> Option { + let id1 = self.graph_indices.get_unknown_gen(collider1)?; + let id2 = self.graph_indices.get_unknown_gen(collider2)?; + self.intersection_graph + .interaction_pair(id1.intersection_graph_index, id2.intersection_graph_index) + .map(|c| *c.2) + } + /// The intersection pair involving two specific colliders. /// /// If this returns `None` or `Some(false)`, then there is no intersection between the two colliders. @@ -185,8 +257,9 @@ impl NarrowPhase { + ComponentSet + ComponentSetMut, Colliders: ComponentSet - + ComponentSetOption - + ComponentSet, + + ComponentSet + + ComponentSet + + ComponentSetOption, { // TODO: avoid these hash-maps. // They are necessary to handle the swap-remove done internally @@ -281,8 +354,9 @@ impl NarrowPhase { + ComponentSet + ComponentSetMut, Colliders: ComponentSet - + ComponentSetOption - + ComponentSet, + + ComponentSet + + ComponentSet + + ComponentSetOption, { let mut pairs_to_remove = vec![]; @@ -397,7 +471,9 @@ impl NarrowPhase { Bodies: ComponentSetMut + ComponentSet + ComponentSetMut, - Colliders: ComponentSet + ComponentSetOption, + Colliders: ComponentSet + + ComponentSet + + ComponentSetOption, { let co_type1: Option<&ColliderType> = colliders.get(pair.collider1.0); let co_type2: Option<&ColliderType> = colliders.get(pair.collider2.0); @@ -419,9 +495,16 @@ impl NarrowPhase { // Emit an intersection lost event if we had an intersection before removing the edge. if Some(true) == was_intersecting { - let prox_event = - IntersectionEvent::new(pair.collider1, pair.collider2, false); - events.handle_intersection_event(prox_event) + let co_flag1: &ColliderFlags = colliders.index(pair.collider1.0); + let co_flag2: &ColliderFlags = colliders.index(pair.collider2.0); + + if (co_flag1.active_events | co_flag2.active_events) + .contains(ActiveEvents::INTERSECTION_EVENTS) + { + let prox_event = + IntersectionEvent::new(pair.collider1, pair.collider2, false); + events.handle_intersection_event(prox_event) + } } } else { let contact_pair = self @@ -447,10 +530,17 @@ impl NarrowPhase { } } - events.handle_contact_event(ContactEvent::Stopped( - pair.collider1, - pair.collider2, - )) + let co_flag1: &ColliderFlags = colliders.index(pair.collider1.0); + let co_flag2: &ColliderFlags = colliders.index(pair.collider2.0); + + if (co_flag1.active_events | co_flag2.active_events) + .contains(ActiveEvents::CONTACT_EVENTS) + { + events.handle_contact_event( + ContactEvent::Stopped(pair.collider1, pair.collider2), + &ctct, + ) + } } } } @@ -527,7 +617,7 @@ impl NarrowPhase { .find_edge(gid1.contact_graph_index, gid2.contact_graph_index) .is_none() { - let interaction = ContactPair::new(*pair); + let interaction = ContactPair::new(pair.collider1, pair.collider2); let _ = self.contact_graph.add_edge( gid1.contact_graph_index, gid2.contact_graph_index, @@ -547,9 +637,11 @@ impl NarrowPhase { events: &dyn EventHandler, ) where Bodies: ComponentSetMut - + ComponentSet - + ComponentSetMut, - Colliders: ComponentSet + ComponentSetOption, + + ComponentSetMut + + ComponentSet, + Colliders: ComponentSet + + ComponentSet + + ComponentSetOption, { for event in broad_phase_events { match event { @@ -583,9 +675,10 @@ impl NarrowPhase { + ComponentSet, Colliders: ComponentSet + ComponentSetOption - + ComponentSet + ComponentSet - + ComponentSet, + + ComponentSet + + ComponentSet + + ComponentSet, { if modified_colliders.is_empty() { return; @@ -593,7 +686,6 @@ impl NarrowPhase { let nodes = &self.intersection_graph.graph.nodes; let query_dispatcher = &*self.query_dispatcher; - let active_hooks = hooks.active_hooks(); // TODO: don't iterate on all the edges. par_iter_mut!(&mut self.intersection_graph.graph.edges).for_each(|edge| { @@ -601,19 +693,19 @@ impl NarrowPhase { let handle2 = nodes[edge.target().index()].weight; let co_parent1: Option<&ColliderParent> = colliders.get(handle1.0); - let (co_changes1, co_groups1, co_shape1, co_pos1): ( + let (co_changes1, co_shape1, co_pos1, co_flags1): ( &ColliderChanges, - &ColliderGroups, &ColliderShape, &ColliderPosition, + &ColliderFlags, ) = colliders.index_bundle(handle1.0); let co_parent2: Option<&ColliderParent> = colliders.get(handle2.0); - let (co_changes2, co_groups2, co_shape2, co_pos2): ( + let (co_changes2, co_shape2, co_pos2, co_flags2): ( &ColliderChanges, - &ColliderGroups, &ColliderShape, &ColliderPosition, + &ColliderFlags, ) = colliders.index_bundle(handle2.0); if !co_changes1.needs_narrow_phase_update() && !co_changes2.needs_narrow_phase_update() @@ -623,48 +715,40 @@ impl NarrowPhase { } // TODO: avoid lookup into bodies. - let (mut sleeping1, mut status1) = (true, RigidBodyType::Static); - let (mut sleeping2, mut status2) = (true, RigidBodyType::Static); + let mut rb_type1 = RigidBodyType::Static; + let mut rb_type2 = RigidBodyType::Static; if let Some(co_parent1) = co_parent1 { - let (rb_type1, rb_activation1): (&RigidBodyType, &RigidBodyActivation) = - bodies.index_bundle(co_parent1.handle.0); - status1 = *rb_type1; - sleeping1 = rb_activation1.sleeping; + rb_type1 = *bodies.index(co_parent1.handle.0); } if let Some(co_parent2) = co_parent2 { - let (rb_type2, rb_activation2): (&RigidBodyType, &RigidBodyActivation) = - bodies.index_bundle(co_parent2.handle.0); - status2 = *rb_type2; - sleeping2 = rb_activation2.sleeping; + rb_type2 = *bodies.index(co_parent2.handle.0); } - if (sleeping1 && status2.is_static()) - || (sleeping2 && status1.is_static()) - || (sleeping1 && sleeping2) + // Filter based on the rigid-body types. + if !co_flags1.active_collision_types.test(rb_type1, rb_type2) + && !co_flags2.active_collision_types.test(rb_type1, rb_type2) { - // No need to update this intersection because nothing moved. return; } - if !co_groups1 - .collision_groups - .test(co_groups2.collision_groups) - { - // The intersection is not allowed. + // Filter based on collision groups. + if !co_flags1.collision_groups.test(co_flags2.collision_groups) { return; } - if !active_hooks.contains(PhysicsHooksFlags::FILTER_INTERSECTION_PAIR) - && !status1.is_dynamic() - && !status2.is_dynamic() + let active_hooks = co_flags1.active_hooks | co_flags2.active_hooks; + let active_events = co_flags1.active_events | co_flags2.active_events; + + // Filter based on rigid-body types. + if !co_flags1.active_collision_types.test(rb_type1, rb_type2) + && !co_flags2.active_collision_types.test(rb_type1, rb_type2) { - // Default filtering rule: no intersection between two non-dynamic bodies. return; } - if active_hooks.contains(PhysicsHooksFlags::FILTER_INTERSECTION_PAIR) { + if active_hooks.contains(ActiveHooks::FILTER_INTERSECTION_PAIR) { let context = PairFilterContext { bodies, colliders, @@ -685,7 +769,9 @@ impl NarrowPhase { if let Ok(intersection) = query_dispatcher.intersection_test(&pos12, &**co_shape1, &**co_shape2) { - if intersection != edge.weight { + if active_events.contains(ActiveEvents::INTERSECTION_EVENTS) + && intersection != edge.weight + { edge.weight = intersection; events.handle_intersection_event(IntersectionEvent::new( handle1, @@ -711,39 +797,38 @@ impl NarrowPhase { + ComponentSet, Colliders: ComponentSet + ComponentSetOption - + ComponentSet + ComponentSet + ComponentSet - + ComponentSet, + + ComponentSet + + ComponentSet, { if modified_colliders.is_empty() { return; } let query_dispatcher = &*self.query_dispatcher; - let active_hooks = hooks.active_hooks(); // TODO: don't iterate on all the edges. par_iter_mut!(&mut self.contact_graph.graph.edges).for_each(|edge| { let pair = &mut edge.weight; - let co_parent1: Option<&ColliderParent> = colliders.get(pair.pair.collider1.0); - let (co_changes1, co_groups1, co_shape1, co_pos1, co_material1): ( + let co_parent1: Option<&ColliderParent> = colliders.get(pair.collider1.0); + let (co_changes1, co_shape1, co_pos1, co_material1, co_flags1): ( &ColliderChanges, - &ColliderGroups, &ColliderShape, &ColliderPosition, &ColliderMaterial, - ) = colliders.index_bundle(pair.pair.collider1.0); + &ColliderFlags, + ) = colliders.index_bundle(pair.collider1.0); - let co_parent2: Option<&ColliderParent> = colliders.get(pair.pair.collider2.0); - let (co_changes2, co_groups2, co_shape2, co_pos2, co_material2): ( + let co_parent2: Option<&ColliderParent> = colliders.get(pair.collider2.0); + let (co_changes2, co_shape2, co_pos2, co_material2, co_flags2): ( &ColliderChanges, - &ColliderGroups, &ColliderShape, &ColliderPosition, &ColliderMaterial, - ) = colliders.index_bundle(pair.pair.collider2.0); + &ColliderFlags, + ) = colliders.index_bundle(pair.collider2.0); if !co_changes1.needs_narrow_phase_update() && !co_changes2.needs_narrow_phase_update() { @@ -752,56 +837,40 @@ impl NarrowPhase { } // TODO: avoid lookup into bodies. - let (mut sleeping1, mut status1) = (true, RigidBodyType::Static); - let (mut sleeping2, mut status2) = (true, RigidBodyType::Static); + let mut rb_type1 = RigidBodyType::Static; + let mut rb_type2 = RigidBodyType::Static; if let Some(co_parent1) = co_parent1 { - let (rb_type1, rb_activation1): (&RigidBodyType, &RigidBodyActivation) = - bodies.index_bundle(co_parent1.handle.0); - status1 = *rb_type1; - sleeping1 = rb_activation1.sleeping; + rb_type1 = *bodies.index(co_parent1.handle.0); } if let Some(co_parent2) = co_parent2 { - let (rb_type2, rb_activation2): (&RigidBodyType, &RigidBodyActivation) = - bodies.index_bundle(co_parent2.handle.0); - status2 = *rb_type2; - sleeping2 = rb_activation2.sleeping; + rb_type2 = *bodies.index(co_parent2.handle.0); } - if (sleeping1 && status2.is_static()) - || (sleeping2 && status1.is_static()) - || (sleeping1 && sleeping2) + // Filter based on the rigid-body types. + if !co_flags1.active_collision_types.test(rb_type1, rb_type2) + && !co_flags2.active_collision_types.test(rb_type1, rb_type2) { - // No need to update this intersection because nothing moved. return; } - if !co_groups1 - .collision_groups - .test(co_groups2.collision_groups) - { - // The collision is not allowed. + // Filter based on collision groups. + if !co_flags1.collision_groups.test(co_flags2.collision_groups) { return; } - if !active_hooks.contains(PhysicsHooksFlags::FILTER_CONTACT_PAIR) - && !status1.is_dynamic() - && !status2.is_dynamic() - { - // Default filtering rule: no contact between two non-dynamic bodies. - return; - } + let active_hooks = co_flags1.active_hooks | co_flags2.active_hooks; + let active_events = co_flags1.active_events | co_flags2.active_events; - let mut solver_flags = if active_hooks.contains(PhysicsHooksFlags::FILTER_CONTACT_PAIR) - { + let mut solver_flags = if active_hooks.contains(ActiveHooks::FILTER_CONTACT_PAIRS) { let context = PairFilterContext { bodies, colliders, rigid_body1: co_parent1.map(|p| p.handle), rigid_body2: co_parent2.map(|p| p.handle), - collider1: pair.pair.collider1, - collider2: pair.pair.collider2, + collider1: pair.collider1, + collider2: pair.collider2, }; if let Some(solver_flags) = hooks.filter_contact_pair(&context) { @@ -811,10 +880,10 @@ impl NarrowPhase { return; } } else { - co_material1.solver_flags | co_material2.solver_flags + SolverFlags::default() }; - if !co_groups1.solver_groups.test(co_groups2.solver_groups) { + if !co_flags1.solver_groups.test(co_flags2.solver_groups) { solver_flags.remove(SolverFlags::COMPUTE_IMPULSES); } @@ -865,7 +934,7 @@ impl NarrowPhase { manifold.data.rigid_body2 = co_parent2.map(|p| p.handle); manifold.data.solver_flags = solver_flags; manifold.data.relative_dominance = - dominance1.effective_group(&status1) - dominance2.effective_group(&status2); + dominance1.effective_group(&rb_type1) - dominance2.effective_group(&rb_type2); manifold.data.normal = world_pos1 * manifold.local_n1; // Generate solver contacts. @@ -896,12 +965,7 @@ impl NarrowPhase { } // Apply the user-defined contact modification. - if active_hooks.contains(PhysicsHooksFlags::MODIFY_SOLVER_CONTACTS) - && manifold - .data - .solver_flags - .contains(SolverFlags::MODIFY_SOLVER_CONTACTS) - { + if active_hooks.contains(ActiveHooks::MODIFY_SOLVER_CONTACTS) { let mut modifiable_solver_contacts = std::mem::replace(&mut manifold.data.solver_contacts, Vec::new()); let mut modifiable_user_data = manifold.data.user_data; @@ -912,8 +976,8 @@ impl NarrowPhase { colliders, rigid_body1: co_parent1.map(|p| p.handle), rigid_body2: co_parent2.map(|p| p.handle), - collider1: pair.pair.collider1, - collider2: pair.pair.collider2, + collider1: pair.collider1, + collider2: pair.collider2, manifold, solver_contacts: &mut modifiable_solver_contacts, normal: &mut modifiable_normal, @@ -929,16 +993,18 @@ impl NarrowPhase { } if has_any_active_contact != pair.has_any_active_contact { - if has_any_active_contact { - events.handle_contact_event(ContactEvent::Started( - pair.pair.collider1, - pair.pair.collider2, - )); - } else { - events.handle_contact_event(ContactEvent::Stopped( - pair.pair.collider1, - pair.pair.collider2, - )); + if active_events.contains(ActiveEvents::CONTACT_EVENTS) { + if has_any_active_contact { + events.handle_contact_event( + ContactEvent::Started(pair.collider1, pair.collider2), + pair, + ); + } else { + events.handle_contact_event( + ContactEvent::Stopped(pair.collider1, pair.collider2), + pair, + ); + } } pair.has_any_active_contact = has_any_active_contact; @@ -972,7 +1038,7 @@ impl NarrowPhase { .contains(SolverFlags::COMPUTE_IMPULSES) && manifold.data.num_active_contacts() != 0 { - let (active_island_id1, status1, sleeping1) = + let (active_island_id1, rb_type1, sleeping1) = if let Some(handle1) = manifold.data.rigid_body1 { let data: (&RigidBodyIds, &RigidBodyType, &RigidBodyActivation) = bodies.index_bundle(handle1.0); @@ -981,7 +1047,7 @@ impl NarrowPhase { (0, RigidBodyType::Static, true) }; - let (active_island_id2, status2, sleeping2) = + let (active_island_id2, rb_type2, sleeping2) = if let Some(handle2) = manifold.data.rigid_body2 { let data: (&RigidBodyIds, &RigidBodyType, &RigidBodyActivation) = bodies.index_bundle(handle2.0); @@ -990,11 +1056,11 @@ impl NarrowPhase { (0, RigidBodyType::Static, true) }; - if (status1.is_dynamic() || status2.is_dynamic()) - && (!status1.is_dynamic() || !sleeping1) - && (!status2.is_dynamic() || !sleeping2) + if (rb_type1.is_dynamic() || rb_type2.is_dynamic()) + && (!rb_type1.is_dynamic() || !sleeping1) + && (!rb_type2.is_dynamic() || !sleeping2) { - let island_index = if !status1.is_dynamic() { + let island_index = if !rb_type1.is_dynamic() { active_island_id2 } else { active_island_id1 diff --git a/src/lib.rs b/src/lib.rs index 79abaa5..1f32608 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -149,3 +149,12 @@ pub mod math { #[cfg(feature = "dim3")] pub const MAX_MANIFOLD_POINTS: usize = 4; } + +/// Prelude containing the common types defined by Rapier. +pub mod prelude { + pub use crate::dynamics::*; + pub use crate::geometry::*; + pub use crate::math::*; + pub use crate::pipeline::*; + pub use na::{point, vector, DMatrix, DVector}; +} diff --git a/src/pipeline/collision_pipeline.rs b/src/pipeline/collision_pipeline.rs index 455e75d..d789da7 100644 --- a/src/pipeline/collision_pipeline.rs +++ b/src/pipeline/collision_pipeline.rs @@ -6,7 +6,7 @@ use crate::dynamics::{ RigidBodyIds, RigidBodyPosition, RigidBodyType, RigidBodyVelocity, }; use crate::geometry::{ - BroadPhase, BroadPhasePairEvent, ColliderBroadPhaseData, ColliderChanges, ColliderGroups, + BroadPhase, BroadPhasePairEvent, ColliderBroadPhaseData, ColliderChanges, ColliderFlags, ColliderHandle, ColliderMaterial, ColliderPair, ColliderParent, ColliderPosition, ColliderShape, ColliderType, NarrowPhase, }; @@ -65,8 +65,8 @@ impl CollisionPipeline { + ComponentSet + ComponentSetOption + ComponentSet - + ComponentSet - + ComponentSet, + + ComponentSet + + ComponentSet, { // Update broad-phase. self.broad_phase_events.clear(); @@ -172,8 +172,8 @@ impl CollisionPipeline { + ComponentSet + ComponentSetOption + ComponentSet - + ComponentSet - + ComponentSet, + + ComponentSet + + ComponentSet, { super::user_changes::handle_user_changes_to_colliders( bodies, diff --git a/src/pipeline/event_handler.rs b/src/pipeline/event_handler.rs index 9d7b17a..c54acc2 100644 --- a/src/pipeline/event_handler.rs +++ b/src/pipeline/event_handler.rs @@ -1,6 +1,23 @@ -use crate::geometry::{ContactEvent, IntersectionEvent}; +use crate::geometry::{ContactEvent, ContactPair, IntersectionEvent}; use crossbeam::channel::Sender; +bitflags::bitflags! { + #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] + /// Flags affecting the events generated for this collider. + pub struct ActiveEvents: u32 { + /// If set, Rapier will call `EventHandler::handle_intersection_event` whenever relevant for this collider. + const INTERSECTION_EVENTS = 0b0001; + /// If set, Rapier will call `PhysicsHooks::handle_contact_event` whenever relevant for this collider. + const CONTACT_EVENTS = 0b0010; + } +} + +impl Default for ActiveEvents { + fn default() -> Self { + ActiveEvents::empty() + } +} + /// Trait implemented by structures responsible for handling events generated by the physics engine. /// /// Implementors of this trait will typically collect these events for future processing. @@ -13,12 +30,12 @@ pub trait EventHandler: Send + Sync { /// /// A contact event is emitted when two collider start or stop touching, independently from the /// number of contact points involved. - fn handle_contact_event(&self, event: ContactEvent); + fn handle_contact_event(&self, event: ContactEvent, contact_pair: &ContactPair); } impl EventHandler for () { fn handle_intersection_event(&self, _event: IntersectionEvent) {} - fn handle_contact_event(&self, _event: ContactEvent) {} + fn handle_contact_event(&self, _event: ContactEvent, _contact_pair: &ContactPair) {} } /// A physics event handler that collects events into a crossbeam channel. @@ -45,7 +62,7 @@ impl EventHandler for ChannelEventCollector { let _ = self.intersection_event_sender.send(event); } - fn handle_contact_event(&self, event: ContactEvent) { + fn handle_contact_event(&self, event: ContactEvent, _: &ContactPair) { let _ = self.contact_event_sender.send(event); } } diff --git a/src/pipeline/mod.rs b/src/pipeline/mod.rs index ad288d6..2c0393e 100644 --- a/src/pipeline/mod.rs +++ b/src/pipeline/mod.rs @@ -1,10 +1,8 @@ //! Structure for combining the various physics components to perform an actual simulation. pub use collision_pipeline::CollisionPipeline; -pub use event_handler::{ChannelEventCollector, EventHandler}; -pub use physics_hooks::{ - ContactModificationContext, PairFilterContext, PhysicsHooks, PhysicsHooksFlags, -}; +pub use event_handler::{ActiveEvents, ChannelEventCollector, EventHandler}; +pub use physics_hooks::{ActiveHooks, ContactModificationContext, PairFilterContext, PhysicsHooks}; pub use physics_pipeline::PhysicsPipeline; pub use query_pipeline::{QueryPipeline, QueryPipelineMode}; diff --git a/src/pipeline/physics_hooks.rs b/src/pipeline/physics_hooks.rs index c4ef245..68a05d1 100644 --- a/src/pipeline/physics_hooks.rs +++ b/src/pipeline/physics_hooks.rs @@ -118,30 +118,54 @@ impl<'a, Bodies, Colliders> ContactModificationContext<'a, Bodies, Colliders> { bitflags::bitflags! { #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] /// Flags affecting the behavior of the constraints solver for a given contact manifold. - pub struct PhysicsHooksFlags: u32 { + pub struct ActiveHooks: u32 { /// If set, Rapier will call `PhysicsHooks::filter_contact_pair` whenever relevant. - const FILTER_CONTACT_PAIR = 0b0001; + const FILTER_CONTACT_PAIRS = 0b0001; /// If set, Rapier will call `PhysicsHooks::filter_intersection_pair` whenever relevant. const FILTER_INTERSECTION_PAIR = 0b0010; /// If set, Rapier will call `PhysicsHooks::modify_solver_contact` whenever relevant. const MODIFY_SOLVER_CONTACTS = 0b0100; } } -impl Default for PhysicsHooksFlags { +impl Default for ActiveHooks { fn default() -> Self { - PhysicsHooksFlags::empty() + ActiveHooks::empty() + } +} + +// TODO: right now, the wasm version don't have the Send+Sync bounds. +// This is because these bounds are very difficult to fulfill if we want to +// call JS closures. Also, parallelism cannot be enabled for wasm targets, so +// not having Send+Sync isn't a problem. +/// User-defined functions called by the physics engines during one timestep in order to customize its behavior. +#[cfg(target_arch = "wasm32")] +pub trait PhysicsHooks { + /// Applies the contact pair filter. + fn filter_contact_pair( + &self, + _context: &PairFilterContext, + ) -> Option { + None + } + + /// Applies the intersection pair filter. + fn filter_intersection_pair(&self, _context: &PairFilterContext) -> bool { + false + } + + /// Modifies the set of contacts seen by the constraints solver. + fn modify_solver_contacts(&self, _context: &mut ContactModificationContext) { } } /// User-defined functions called by the physics engines during one timestep in order to customize its behavior. +#[cfg(not(target_arch = "wasm32"))] pub trait PhysicsHooks: Send + Sync { - /// The sets of hooks that must be taken into account. - fn active_hooks(&self) -> PhysicsHooksFlags; - /// Applies the contact pair filter. /// - /// Note that this method will only be called if `self.active_hooks()` - /// contains the `PhysicsHooksFlags::FILTER_CONTACT_PAIR` flags. + /// Note that this method will only be called if at least one of the colliders + /// involved in the contact contains the `ActiveHooks::FILTER_CONTACT_PAIRS` flags + /// in its physics hooks flags. /// /// User-defined filter for potential contact pairs detected by the broad-phase. /// This can be used to apply custom logic in order to decide whether two colliders @@ -165,13 +189,14 @@ pub trait PhysicsHooks: Send + Sync { &self, _context: &PairFilterContext, ) -> Option { - None + Some(SolverFlags::COMPUTE_IMPULSES) } /// Applies the intersection pair filter. /// - /// Note that this method will only be called if `self.active_hooks()` - /// contains the `PhysicsHooksFlags::FILTER_INTERSECTION_PAIR` flags. + /// Note that this method will only be called if at least one of the colliders + /// involved in the contact contains the `ActiveHooks::FILTER_INTERSECTION_PAIR` flags + /// in its physics hooks flags. /// /// User-defined filter for potential intersection pairs detected by the broad-phase. /// @@ -188,13 +213,14 @@ pub trait PhysicsHooks: Send + Sync { /// If this return `true` then the narrow-phase will compute intersection /// information for this pair. fn filter_intersection_pair(&self, _context: &PairFilterContext) -> bool { - false + true } /// Modifies the set of contacts seen by the constraints solver. /// - /// Note that this method will only be called if `self.active_hooks()` - /// contains the `PhysicsHooksFlags::MODIFY_SOLVER_CONTACTS` flags. + /// Note that this method will only be called if at least one of the colliders + /// involved in the contact contains the `ActiveHooks::MODIFY_SOLVER_CONTACTS` flags + /// in its physics hooks flags. /// /// By default, the content of `solver_contacts` is computed from `manifold.points`. /// This method will be called on each contact manifold which have the flag `SolverFlags::modify_solver_contacts` set. @@ -220,16 +246,15 @@ pub trait PhysicsHooks: Send + Sync { } impl PhysicsHooks for () { - fn active_hooks(&self) -> PhysicsHooksFlags { - PhysicsHooksFlags::empty() - } - - fn filter_contact_pair(&self, _: &PairFilterContext) -> Option { - None + fn filter_contact_pair( + &self, + _context: &PairFilterContext, + ) -> Option { + Some(SolverFlags::default()) } fn filter_intersection_pair(&self, _: &PairFilterContext) -> bool { - false + true } fn modify_solver_contacts(&self, _: &mut ContactModificationContext) {} diff --git a/src/pipeline/physics_pipeline.rs b/src/pipeline/physics_pipeline.rs index 2f2a95d..a83240e 100644 --- a/src/pipeline/physics_pipeline.rs +++ b/src/pipeline/physics_pipeline.rs @@ -13,7 +13,7 @@ use crate::dynamics::{ #[cfg(feature = "parallel")] use crate::dynamics::{JointGraphEdge, ParallelIslandSolver as IslandSolver}; use crate::geometry::{ - BroadPhase, BroadPhasePairEvent, ColliderBroadPhaseData, ColliderChanges, ColliderGroups, + BroadPhase, BroadPhasePairEvent, ColliderBroadPhaseData, ColliderChanges, ColliderFlags, ColliderHandle, ColliderMaterial, ColliderPair, ColliderParent, ColliderPosition, ColliderShape, ColliderType, ContactManifoldIndex, NarrowPhase, }; @@ -103,8 +103,8 @@ impl PhysicsPipeline { + ComponentSet + ComponentSetOption + ComponentSet - + ComponentSet - + ComponentSet, + + ComponentSet + + ComponentSet, { self.counters.stages.collision_detection_time.resume(); self.counters.cd.broad_phase_time.resume(); @@ -365,7 +365,8 @@ impl PhysicsPipeline { Colliders: ComponentSetOption + ComponentSet + ComponentSet - + ComponentSet, + + ComponentSet + + ComponentSet, { self.counters.ccd.toi_computation_time.start(); // Handle CCD @@ -428,7 +429,10 @@ impl PhysicsPipeline { islands: &IslandManager, bodies: &mut Bodies, ) where - Bodies: ComponentSetMut + ComponentSet, + Bodies: ComponentSetMut + + ComponentSetMut + + ComponentSet + + ComponentSet, { // Update kinematic bodies velocities. // TODO: what is the best place for this? It should at least be @@ -436,9 +440,31 @@ impl PhysicsPipeline { // there to determine if this kinematic body should wake-up dynamic // bodies it is touching. for handle in islands.active_kinematic_bodies() { - let ppos: &RigidBodyPosition = bodies.index(handle.0); - let new_vel = ppos.interpolate_velocity(integration_parameters.inv_dt()); - bodies.set_internal(handle.0, new_vel); + let (rb_type, rb_pos, rb_vel, rb_mprops): ( + &RigidBodyType, + &RigidBodyPosition, + &RigidBodyVelocity, + &RigidBodyMassProps, + ) = bodies.index_bundle(handle.0); + + match rb_type { + RigidBodyType::KinematicPositionBased => { + let rb_pos: &RigidBodyPosition = bodies.index(handle.0); + let new_vel = rb_pos.interpolate_velocity(integration_parameters.inv_dt()); + bodies.set_internal(handle.0, new_vel); + } + RigidBodyType::KinematicVelocityBased => { + let new_pos = rb_vel.integrate( + integration_parameters.dt, + &rb_pos.position, + // NOTE: we don't use the `world_com` here because it is not + // really updated for kinematic bodies. + &(rb_pos.position * rb_mprops.local_mprops.local_com), + ); + bodies.set_internal(handle.0, RigidBodyPosition::from(new_pos)); + } + _ => {} + } } } @@ -519,8 +545,8 @@ impl PhysicsPipeline { + ComponentSet + ComponentSetOption + ComponentSet - + ComponentSet - + ComponentSet, + + ComponentSet + + ComponentSet, { self.counters.reset(); self.counters.step_started(); @@ -719,12 +745,12 @@ mod test { let rb = RigidBodyBuilder::new_static().build(); let h1 = bodies.insert(rb.clone()); let co = ColliderBuilder::ball(10.0).build(); - colliders.insert(co.clone(), h1, &mut bodies); + colliders.insert_with_parent(co.clone(), h1, &mut bodies); // The same but with a kinematic body. - let rb = RigidBodyBuilder::new_kinematic().build(); + let rb = RigidBodyBuilder::new_kinematic_position_based().build(); let h2 = bodies.insert(rb.clone()); - colliders.insert(co, h2, &mut bodies); + colliders.insert_with_parent(co, h2, &mut bodies); pipeline.step( &Vector::zeros(), @@ -760,7 +786,7 @@ mod test { let h2 = bodies.insert(rb.clone()); // The same but with a kinematic body. - let rb = RigidBodyBuilder::new_kinematic().build(); + let rb = RigidBodyBuilder::new_kinematic_position_based().build(); let h3 = bodies.insert(rb.clone()); // The same but with a static body. @@ -838,7 +864,7 @@ mod test { let body = RigidBodyBuilder::new_dynamic().build(); let b_handle = bodies.insert(body); let collider = ColliderBuilder::ball(1.0).build(); - let c_handle = colliders.insert(collider, b_handle, &mut bodies); + let c_handle = colliders.insert_with_parent(collider, b_handle, &mut bodies); colliders.remove(c_handle, &mut islands, &mut bodies, true); bodies.remove(b_handle, &mut islands, &mut colliders, &mut joints); diff --git a/src/pipeline/query_pipeline.rs b/src/pipeline/query_pipeline.rs index 31bf3a4..733d767 100644 --- a/src/pipeline/query_pipeline.rs +++ b/src/pipeline/query_pipeline.rs @@ -4,7 +4,7 @@ use crate::dynamics::{ RigidBodyVelocity, }; use crate::geometry::{ - ColliderGroups, ColliderHandle, ColliderParent, ColliderPosition, ColliderShape, + ColliderFlags, ColliderHandle, ColliderParent, ColliderPosition, ColliderShape, InteractionGroups, PointProjection, Ray, RayIntersection, AABB, QBVH, }; use crate::math::{Isometry, Point, Real, Vector}; @@ -67,7 +67,7 @@ impl<'a, Colliders> TypedSimdCompositeShape for QueryPipelineAsCompositeShape<'a where // TODO ECS: make everything optional but the shape? Colliders: - ComponentSet + ComponentSet + ComponentSet, + ComponentSet + ComponentSet + ComponentSet, { type PartShape = dyn Shape; type PartId = ColliderHandle; @@ -77,10 +77,10 @@ where shape_id: Self::PartId, mut f: impl FnMut(Option<&Isometry>, &Self::PartShape), ) { - let co_groups: Option<&ColliderGroups> = self.colliders.get(shape_id.0); + let co_flags: Option<&ColliderFlags> = self.colliders.get(shape_id.0); - if let Some(co_groups) = co_groups { - if co_groups.collision_groups.test(self.query_groups) + if let Some(co_flags) = co_flags { + if co_flags.collision_groups.test(self.query_groups) && self.filter.map(|f| f(shape_id)).unwrap_or(true) { let (co_pos, co_shape): (&ColliderPosition, &ColliderShape) = @@ -384,7 +384,7 @@ impl QueryPipeline { filter: Option<&dyn Fn(ColliderHandle) -> bool>, ) -> Option<(ColliderHandle, Real)> where - Colliders: ComponentSet + Colliders: ComponentSet + ComponentSet + ComponentSet, { @@ -420,7 +420,7 @@ impl QueryPipeline { filter: Option<&dyn Fn(ColliderHandle) -> bool>, ) -> Option<(ColliderHandle, RayIntersection)> where - Colliders: ComponentSet + Colliders: ComponentSet + ComponentSet + ComponentSet, { @@ -463,16 +463,16 @@ impl QueryPipeline { filter: Option<&dyn Fn(ColliderHandle) -> bool>, mut callback: impl FnMut(ColliderHandle, RayIntersection) -> bool, ) where - Colliders: ComponentSet + Colliders: ComponentSet + ComponentSet + ComponentSet, { let mut leaf_callback = &mut |handle: &ColliderHandle| { let co_shape: Option<&ColliderShape> = colliders.get(handle.0); if let Some(co_shape) = co_shape { - let (co_groups, co_pos): (&ColliderGroups, &ColliderPosition) = + let (co_flags, co_pos): (&ColliderFlags, &ColliderPosition) = colliders.index_bundle(handle.0); - if co_groups.collision_groups.test(query_groups) + if co_flags.collision_groups.test(query_groups) && filter.map(|f| f(*handle)).unwrap_or(true) { if let Some(hit) = co_shape.cast_ray_and_get_normal(co_pos, ray, max_toi, solid) @@ -509,7 +509,7 @@ impl QueryPipeline { filter: Option<&dyn Fn(ColliderHandle) -> bool>, ) -> Option where - Colliders: ComponentSet + Colliders: ComponentSet + ComponentSet + ComponentSet, { @@ -550,7 +550,7 @@ impl QueryPipeline { filter: Option<&dyn Fn(ColliderHandle) -> bool>, ) -> Option<(ColliderHandle, PointProjection)> where - Colliders: ComponentSet + Colliders: ComponentSet + ComponentSet + ComponentSet, { @@ -583,7 +583,7 @@ impl QueryPipeline { filter: Option<&dyn Fn(ColliderHandle) -> bool>, mut callback: impl FnMut(ColliderHandle) -> bool, ) where - Colliders: ComponentSet + Colliders: ComponentSet + ComponentSet + ComponentSet, { @@ -591,10 +591,10 @@ impl QueryPipeline { let co_shape: Option<&ColliderShape> = colliders.get(handle.0); if let Some(co_shape) = co_shape { - let (co_groups, co_pos): (&ColliderGroups, &ColliderPosition) = + let (co_flags, co_pos): (&ColliderFlags, &ColliderPosition) = colliders.index_bundle(handle.0); - if co_groups.collision_groups.test(query_groups) + if co_flags.collision_groups.test(query_groups) && filter.map(|f| f(*handle)).unwrap_or(true) && co_shape.contains_point(co_pos, point) { @@ -635,7 +635,7 @@ impl QueryPipeline { filter: Option<&dyn Fn(ColliderHandle) -> bool>, ) -> Option<(ColliderHandle, PointProjection, FeatureId)> where - Colliders: ComponentSet + Colliders: ComponentSet + ComponentSet + ComponentSet, { @@ -685,7 +685,7 @@ impl QueryPipeline { filter: Option<&dyn Fn(ColliderHandle) -> bool>, ) -> Option<(ColliderHandle, TOI)> where - Colliders: ComponentSet + Colliders: ComponentSet + ComponentSet + ComponentSet, { @@ -733,7 +733,7 @@ impl QueryPipeline { filter: Option<&dyn Fn(ColliderHandle) -> bool>, ) -> Option<(ColliderHandle, TOI)> where - Colliders: ComponentSet + Colliders: ComponentSet + ComponentSet + ComponentSet, { @@ -774,7 +774,7 @@ impl QueryPipeline { filter: Option<&dyn Fn(ColliderHandle) -> bool>, mut callback: impl FnMut(ColliderHandle) -> bool, ) where - Colliders: ComponentSet + Colliders: ComponentSet + ComponentSet + ComponentSet, { @@ -785,10 +785,10 @@ impl QueryPipeline { let co_shape: Option<&ColliderShape> = colliders.get(handle.0); if let Some(co_shape) = co_shape { - let (co_groups, co_pos): (&ColliderGroups, &ColliderPosition) = + let (co_flags, co_pos): (&ColliderFlags, &ColliderPosition) = colliders.index_bundle(handle.0); - if co_groups.collision_groups.test(query_groups) + if co_flags.collision_groups.test(query_groups) && filter.map(|f| f(*handle)).unwrap_or(true) { let pos12 = inv_shape_pos * co_pos.as_ref(); diff --git a/src/pipeline/user_changes.rs b/src/pipeline/user_changes.rs index 99c5cfe..699361c 100644 --- a/src/pipeline/user_changes.rs +++ b/src/pipeline/user_changes.rs @@ -100,7 +100,8 @@ pub(crate) fn handle_user_changes_to_rigid_bodies( // the active_dynamic_set. changes.set(RigidBodyChanges::SLEEP, true); } - RigidBodyType::Kinematic => { + RigidBodyType::KinematicVelocityBased + | RigidBodyType::KinematicPositionBased => { // Remove from the active dynamic set if it was there. if islands.active_dynamic_set.get(ids.active_set_id) == Some(&handle) { islands.active_dynamic_set.swap_remove(ids.active_set_id); diff --git a/src_testbed/box2d_backend.rs b/src_testbed/box2d_backend.rs index db0f846..f0bffa3 100644 --- a/src_testbed/box2d_backend.rs +++ b/src_testbed/box2d_backend.rs @@ -87,9 +87,11 @@ impl Box2dWorld { fn insert_colliders(&mut self, colliders: &ColliderSet) { for (_, collider) in colliders.iter() { - let b2_body_handle = self.rapier2box2d[&collider.parent()]; - let mut b2_body = self.world.body_mut(b2_body_handle); - Self::create_fixture(&collider, &mut *b2_body); + if let Some(parent) = collider.parent() { + let b2_body_handle = self.rapier2box2d[&parent]; + let mut b2_body = self.world.body_mut(b2_body_handle); + Self::create_fixture(&collider, &mut *b2_body); + } } } @@ -122,8 +124,8 @@ impl Box2dWorld { body_a, body_b, collide_connected: true, - local_anchor_a: na_vec_to_b2_vec(params.local_anchor1.translation.vector), - local_anchor_b: na_vec_to_b2_vec(params.local_anchor2.translation.vector), + local_anchor_a: na_vec_to_b2_vec(params.local_frame1.translation.vector), + local_anchor_b: na_vec_to_b2_vec(params.local_frame2.translation.vector), reference_angle: 0.0, frequency: 0.0, damping_ratio: 0.0, @@ -155,7 +157,14 @@ impl Box2dWorld { } fn create_fixture(collider: &Collider, body: &mut b2::MetaBody) { - let center = na_vec_to_b2_vec(collider.position_wrt_parent().translation.vector); + let center = na_vec_to_b2_vec( + collider + .position_wrt_parent() + .copied() + .unwrap_or(na::one()) + .translation + .vector, + ); let mut fixture_def = b2::FixtureDef::new(); fixture_def.restitution = collider.material().restitution; @@ -230,7 +239,9 @@ impl Box2dWorld { for coll_handle in body.colliders() { let collider = &mut colliders[*coll_handle]; - collider.set_position_debug(pos * collider.position_wrt_parent()); + collider.set_position( + pos * collider.position_wrt_parent().copied().unwrap_or(na::one()), + ); } } } diff --git a/src_testbed/camera.rs b/src_testbed/camera2d.rs similarity index 97% rename from src_testbed/camera.rs rename to src_testbed/camera2d.rs index 529e6c7..81b3263 100644 --- a/src_testbed/camera.rs +++ b/src_testbed/camera2d.rs @@ -1,5 +1,6 @@ // NOTE: this is inspired from the `bevy-orbit-controls` projects but // with some modifications like Panning, and 2D support. +// Most of these modifications have been contributed upstream. use bevy::input::mouse::MouseMotion; use bevy::input::mouse::MouseScrollUnit::{Line, Pixel}; use bevy::input::mouse::MouseWheel; diff --git a/src_testbed/camera3d.rs b/src_testbed/camera3d.rs new file mode 100644 index 0000000..602ef31 --- /dev/null +++ b/src_testbed/camera3d.rs @@ -0,0 +1,121 @@ +// NOTE: this is mostly taken from the `iMplode-nZ/bevy-orbit-controls` projects but +// with some modifications like Panning, and 2D support. +// Most of these modifications have been contributed upstream. + +use bevy::input::mouse::MouseMotion; +use bevy::input::mouse::MouseScrollUnit::{Line, Pixel}; +use bevy::input::mouse::MouseWheel; +use bevy::prelude::*; +use bevy::render::camera::Camera; +use std::ops::RangeInclusive; + +const LINE_TO_PIXEL_RATIO: f32 = 0.1; + +pub struct OrbitCamera { + pub x: f32, + pub y: f32, + pub pitch_range: RangeInclusive, + pub distance: f32, + pub center: Vec3, + pub rotate_sensitivity: f32, + pub pan_sensitivity: f32, + pub zoom_sensitivity: f32, + pub rotate_button: MouseButton, + pub pan_button: MouseButton, + pub enabled: bool, +} + +impl Default for OrbitCamera { + fn default() -> Self { + OrbitCamera { + x: 0.0, + y: std::f32::consts::FRAC_PI_2, + pitch_range: 0.01..=3.13, + distance: 5.0, + center: Vec3::ZERO, + rotate_sensitivity: 1.0, + pan_sensitivity: 1.0, + zoom_sensitivity: 0.8, + rotate_button: MouseButton::Left, + pan_button: MouseButton::Right, + enabled: true, + } + } +} + +pub struct OrbitCameraPlugin; +impl OrbitCameraPlugin { + fn update_transform_system( + mut query: Query<(&OrbitCamera, &mut Transform), (Changed, With)>, + ) { + for (camera, mut transform) in query.iter_mut() { + if camera.enabled { + let rot = Quat::from_axis_angle(Vec3::Y, camera.x) + * Quat::from_axis_angle(-Vec3::X, camera.y); + transform.translation = (rot * Vec3::Y) * camera.distance + camera.center; + transform.look_at(camera.center, Vec3::Y); + } + } + } + + fn mouse_motion_system( + time: Res