diff --git a/examples2d/multibody2.rs b/examples2d/multibody2.rs index 542b83b2c..2f1f13d69 100644 --- a/examples2d/multibody2.rs +++ b/examples2d/multibody2.rs @@ -32,6 +32,7 @@ fn main() { let revo = RevoluteJoint::new(0.0); let geom = ShapeHandle::new(Ball::new(rad)); let inertia = geom.inertia(1.0); + let center_of_mass = geom.center_of_mass(); for j in 0usize..num { /* @@ -43,6 +44,7 @@ fn main() { na::zero(), Vector2::new(-rad * 3.0, 0.0), inertia, + center_of_mass, ); /* @@ -68,6 +70,7 @@ fn main() { Vector2::new(-rad * 3.0, 0.0), na::zero(), inertia, + center_of_mass ); world.add_collider(COLLIDER_MARGIN, geom.clone(), parent, Isometry2::identity()); } diff --git a/examples3d/collision_groups3.rs b/examples3d/collision_groups3.rs index 6f44cff47..7883f6a35 100644 --- a/examples3d/collision_groups3.rs +++ b/examples3d/collision_groups3.rs @@ -3,12 +3,16 @@ extern crate ncollide3d; extern crate nphysics3d; extern crate nphysics_testbed3d; -use na::{Point3, Vector3, Translation3}; -use ncollide3d::shape::{Plane, Cuboid}; +use na::{Isometry3, Point3, Vector3}; +use ncollide3d::world::CollisionGroups; +use ncollide3d::shape::{Cuboid, ShapeHandle}; use nphysics3d::world::World; -use nphysics3d::object::{RigidBody, RigidBodyCollisionGroups}; +use nphysics3d::object::{BodyHandle, Material}; +use nphysics3d::volumetric::Volumetric; use nphysics_testbed3d::Testbed; +const COLLIDER_MARGIN: f32 = 0.01; + fn main() { let mut testbed = Testbed::new_empty(); @@ -22,86 +26,116 @@ fn main() { * Setup groups. */ const GREEN_GROUP_ID: usize = 0; - let mut green_static_group = RigidBodyCollisionGroups::new_static(); - green_static_group.set_membership(&[ GREEN_GROUP_ID ]); - green_static_group.set_whitelist(&[ GREEN_GROUP_ID ]); - - let mut green_dynamic_group = RigidBodyCollisionGroups::new_dynamic(); - green_dynamic_group.set_membership(&[ GREEN_GROUP_ID ]); - green_dynamic_group.set_whitelist(&[ GREEN_GROUP_ID ]); - + let mut green_group = CollisionGroups::new(); + green_group.set_membership(&[GREEN_GROUP_ID]); + green_group.set_whitelist(&[GREEN_GROUP_ID]); const BLUE_GROUP_ID: usize = 1; - let mut blue_static_group = RigidBodyCollisionGroups::new_static(); - blue_static_group.set_membership(&[ BLUE_GROUP_ID ]); - blue_static_group.set_whitelist(&[ BLUE_GROUP_ID ]); - - let mut blue_dynamic_group = RigidBodyCollisionGroups::new_dynamic(); - blue_dynamic_group.set_membership(&[ BLUE_GROUP_ID ]); - blue_dynamic_group.set_whitelist(&[ BLUE_GROUP_ID ]); + let mut blue_group = CollisionGroups::new(); + blue_group.set_membership(&[BLUE_GROUP_ID]); + blue_group.set_whitelist(&[BLUE_GROUP_ID]); /* * A floor that will collide with everything (default behaviour). */ - let geom = Plane::new(Vector3::new(0.0, 1.0, 0.0)); - world.add_rigid_body(RigidBody::new_static(geom, 0.3, 0.6)); + let ground_size = 5.0; + let ground_shape = + ShapeHandle::new(Cuboid::new(Vector3::repeat(ground_size - COLLIDER_MARGIN))); + let ground_pos = Isometry3::new(Vector3::y() * -ground_size, na::zero()); + + world.add_collider( + COLLIDER_MARGIN, + ground_shape, + BodyHandle::ground(), + ground_pos, + Material::default(), + ); /* * A green floor that will collide with the GREEN group only. */ - let geom = Cuboid::new(Vector3::new(10.0, 1.0, 10.0)); - let mut rb = RigidBody::new_static(geom, 0.3, 0.6); + let geom = ShapeHandle::new(Cuboid::new(Vector3::new(1.0, 0.1, 1.0))); + let handle = world.add_collider( + COLLIDER_MARGIN, + geom, + BodyHandle::ground(), + Isometry3::new(Vector3::y() * 1.0, na::zero()), + Material::default(), + ); - rb.set_collision_groups(green_static_group); - rb.append_translation(&Translation3::new(0.0, 10.0, 0.0)); + world + .collision_world_mut() + .set_collision_groups(handle, green_group); - let handle = world.add_rigid_body(rb); - testbed.set_rigid_body_color(&handle, Point3::new(0.0, 1.0, 0.0)); + testbed.set_collider_color(handle, Point3::new(0.0, 1.0, 0.0)); /* * A blue floor that will collide with the BLUE group only. */ - let geom = Cuboid::new(Vector3::new(10.0, 1.0, 10.0)); - let mut rb = RigidBody::new_static(geom, 0.3, 0.6); + let geom = ShapeHandle::new(Cuboid::new(Vector3::new(1.0, 0.1, 1.0))); + let handle = world.add_collider( + COLLIDER_MARGIN, + geom, + BodyHandle::ground(), + Isometry3::new(Vector3::y() * 2.0, na::zero()), + Material::default(), + ); - rb.set_collision_groups(blue_static_group); - rb.append_translation(&Translation3::new(0.0, 20.0, 0.0)); + world + .collision_world_mut() + .set_collision_groups(handle, blue_group); - let handle = world.add_rigid_body(rb); - testbed.set_rigid_body_color(&handle, Point3::new(0.0, 0.0, 1.0)); + testbed.set_collider_color(handle, Point3::new(0.0, 0.0, 1.0)); /* * Create the boxes */ - let num = 8; - let rad = 1.0; - let shift = rad * 2.0; + let num = 8; + let rad = 0.1; + let shift = rad * 2.0; let centerx = shift * (num as f32) / 2.0; - let centery = 25.0; + let centery = 2.5; let centerz = shift * (num as f32) / 2.0; - for k in 0usize .. 4 { - for i in 0usize .. num { - for j in 0usize .. num { + let geom = ShapeHandle::new(Cuboid::new(Vector3::repeat(rad - COLLIDER_MARGIN))); + let inertia = geom.inertia(1.0); + let center_of_mass = geom.center_of_mass(); + + for k in 0usize..4 { + for i in 0usize..num { + for j in 0usize..num { let x = i as f32 * shift - centerx; let z = j as f32 * shift - centerz; let y = k as f32 * shift + centery; - let geom = Cuboid::new(Vector3::new(rad - 0.01, rad - 0.01, rad - 0.01)); - let mut rb = RigidBody::new_dynamic(geom, 1.0, 0.3, 0.5); - - rb.append_translation(&Translation3::new(x, y, z)); + /* + * Create the rigid body. + */ + let pos = Isometry3::new(Vector3::new(x, y, z), na::zero()); + let body_handle = world.add_rigid_body(pos, inertia, center_of_mass); + + /* + * Create the collider. + */ + let collider_handle = world.add_collider( + COLLIDER_MARGIN, + geom.clone(), + body_handle, + Isometry3::identity(), + Material::default(), + ); // Alternate between the GREEN and BLUE groups. if k % 2 == 0 { - rb.set_collision_groups(green_dynamic_group); - let handle = world.add_rigid_body(rb); - testbed.set_rigid_body_color(&handle, Point3::new(0.0, 1.0, 0.0)); - } - else { - rb.set_collision_groups(blue_dynamic_group); - let handle = world.add_rigid_body(rb); - testbed.set_rigid_body_color(&handle, Point3::new(0.0, 0.0, 1.0)); + world + .collision_world_mut() + .set_collision_groups(collider_handle, green_group); + testbed.set_body_color(&world, body_handle, Point3::new(0.0, 1.0, 0.0)); + } else { + world + .collision_world_mut() + .set_collision_groups(collider_handle, blue_group); + testbed.set_body_color(&world, body_handle, Point3::new(0.0, 0.0, 1.0)); } } } @@ -111,6 +145,6 @@ fn main() { * Set up the testbed. */ testbed.set_world(world); - testbed.look_at(Point3::new(-40.0, 40.0, -40.0), Point3::new(0.0, 3.0, 0.0)); + testbed.look_at(Point3::new(-4.0, 4.0, -4.0), Point3::new(0.0, 0.3, 0.0)); testbed.run(); } diff --git a/examples3d/fixed_bug_long_thin_box_one_shot_manifold3.rs b/examples3d/fixed_bug_long_thin_box_one_shot_manifold3.rs index 24fb8f718..0a62065ca 100644 --- a/examples3d/fixed_bug_long_thin_box_one_shot_manifold3.rs +++ b/examples3d/fixed_bug_long_thin_box_one_shot_manifold3.rs @@ -25,12 +25,15 @@ extern crate ncollide3d; extern crate nphysics3d; extern crate nphysics_testbed3d; -use na::{Point3, Vector3, Translation3}; -use ncollide3d::shape::{Plane, Cuboid}; +use na::{Isometry3, Point3, Vector3}; +use ncollide3d::shape::{Cuboid, Plane, ShapeHandle}; use nphysics3d::world::World; -use nphysics3d::object::RigidBody; +use nphysics3d::object::{BodyHandle, Material}; +use nphysics3d::volumetric::Volumetric; use nphysics_testbed3d::Testbed; +const COLLIDER_MARGIN: f32 = 0.01; + fn main() { /* * World @@ -41,24 +44,38 @@ fn main() { /* * Plane */ - let geom = Plane::new(Vector3::new(0.0, 1.0, 0.0)); + let ground_shape = ShapeHandle::new(Plane::new(Vector3::y_axis())); - world.add_rigid_body(RigidBody::new_static(geom, 0.3, 0.6)); + world.add_collider( + COLLIDER_MARGIN, + ground_shape, + BodyHandle::ground(), + Isometry3::identity(), + Material::default(), + ); /* * Create the boxes */ - let rad = 1.0; - let x = rad; - let y = rad + 10.0; - let z = rad; + let rad = 0.1; + let x = rad; + let y = rad + 10.0; + let z = rad; - let geom = Cuboid::new(Vector3::new(rad, rad * 10.0, rad)); - let mut rb = RigidBody::new_dynamic(geom, 1.0, 0.3, 0.5); + let geom = ShapeHandle::new(Cuboid::new(Vector3::new(rad, rad * 10.0, rad))); + let inertia = geom.inertia(1.0); + let center_of_mass = geom.center_of_mass(); - rb.append_translation(&Translation3::new(x, y, z)); + let pos = Isometry3::new(Vector3::new(x, y, z), na::zero()); + let handle = world.add_rigid_body(pos, inertia, center_of_mass); - world.add_rigid_body(rb); + world.add_collider( + COLLIDER_MARGIN, + geom.clone(), + handle, + Isometry3::identity(), + Material::default(), + ); /* * Set up the testbed. diff --git a/examples3d/gravity3.rs b/examples3d/gravity3.rs index f3f2947d1..465faf1ee 100644 --- a/examples3d/gravity3.rs +++ b/examples3d/gravity3.rs @@ -3,12 +3,16 @@ extern crate ncollide3d; extern crate nphysics3d; extern crate nphysics_testbed3d; -use na::{Point3, Vector3, Translation3}; -use ncollide3d::shape::{Ball, Plane}; +use na::{Isometry3, Point3, Vector3}; +use ncollide3d::shape::{Ball, Plane, ShapeHandle}; use nphysics3d::world::World; -use nphysics3d::object::RigidBody; +use nphysics3d::force_generator::ConstantAcceleration; +use nphysics3d::object::{BodyHandle, Material}; +use nphysics3d::volumetric::Volumetric; use nphysics_testbed3d::Testbed; +const COLLIDER_MARGIN: f32 = 0.01; + fn main() { let mut testbed = Testbed::new_empty(); @@ -16,66 +20,94 @@ fn main() { * World */ let mut world = World::new(); - world.set_gravity(Vector3::new(0.0, -9.81, 0.0)); + + // We setup two force generators that will replace the gravity. + let mut up_gravity = ConstantAcceleration::new(Vector3::y() * 9.81, Vector3::zeros()); + let mut down_gravity = ConstantAcceleration::new(Vector3::y() * -9.81, Vector3::zeros()); /* * Planes */ - let geom = Plane::new(Vector3::new(0.0, 1.0, 0.0)); - - world.add_rigid_body(RigidBody::new_static(geom, 0.3, 0.6)); - - let geom = Plane::new(Vector3::new(0.0, -1.0, 0.0)); - let mut rb = RigidBody::new_static(geom, 0.3, 0.6); - - rb.append_translation(&Translation3::new(0.0, 50.0, 0.0)); - - world.add_rigid_body(rb); + let ground_shape = ShapeHandle::new(Plane::new(Vector3::y_axis())); + world.add_collider( + COLLIDER_MARGIN, + ground_shape, + BodyHandle::ground(), + Isometry3::identity(), + Material::default(), + ); + + let ground_shape = ShapeHandle::new(Plane::new(-Vector3::y_axis())); + world.add_collider( + COLLIDER_MARGIN, + ground_shape, + BodyHandle::ground(), + Isometry3::new(Vector3::y() * 20.0, na::zero()), + Material::default(), + ); /* * Create the balls */ - - let num = 1000f64.sqrt() as usize; - let rad = 0.5; - let shift = 2.5 * rad; + let num = 1000f64.sqrt() as usize; + let rad = 0.1; + let shift = 0.25 * rad; let centerx = shift * (num as f32) / 2.0; - let centery = 5.0; + let centery = 0.5; + + let geom = ShapeHandle::new(Ball::new(rad - COLLIDER_MARGIN)); + let inertia = geom.inertia(1.0); + let center_of_mass = geom.center_of_mass(); - for i in 0usize .. num { - for j in 0usize .. 2 { - for k in 0usize .. num { + for i in 0usize..num { + for j in 0usize..2 { + for k in 0usize..num { let x = i as f32 * 2.5 * rad - centerx; - let y = 10.0 + j as f32 * 2.5 * rad + centery; + let y = 1.0 + j as f32 * 2.5 * rad + centery; let z = k as f32 * 2.5 * rad - centerx; - let mut rb = RigidBody::new_dynamic(Ball::new(rad), 1.0, 0.3, 0.6); - - rb.append_translation(&Translation3::new(x, y, z)); - + /* + * Create the rigid body. + */ + let pos = Isometry3::new(Vector3::new(x, y, z), na::zero()); + let handle = world.add_rigid_body(pos, inertia, center_of_mass); + + /* + * Create the collider. + */ + world.add_collider( + COLLIDER_MARGIN, + geom.clone(), + handle, + Isometry3::identity(), + Material::default(), + ); + + /* + * Set artifical gravity. + */ let color; if j == 1 { - // Invert the gravity for the blue balls. - rb.set_lin_acc_scale(Vector3::new(0.0, -1.0, 0.0)); + up_gravity.add_body_part(handle); color = Point3::new(0.0, 0.0, 1.0); - } - else { - // Double the gravity for the green balls. - rb.set_lin_acc_scale(Vector3::new(0.0, 2.0, 0.0)); + } else { + down_gravity.add_body_part(handle); color = Point3::new(0.0, 1.0, 0.0); } - let rb_handle = world.add_rigid_body(rb); - testbed.set_rigid_body_color(&rb_handle, color); + testbed.set_body_color(&world, handle, color); } } } + world.add_force_generator(up_gravity); + world.add_force_generator(down_gravity); + /* * Set up the testbed. */ testbed.set_world(world); - testbed.look_at(Point3::new(-10.0, 50.0, -10.0), Point3::new(0.0, 0.0, 0.0)); + testbed.look_at(Point3::new(-1.0, 5.0, -1.0), Point3::new(0.0, 0.0, 0.0)); testbed.run(); } diff --git a/nphysics_testbed3d/src/engine.rs b/nphysics_testbed3d/src/engine.rs index 76a39d468..ff37705f4 100644 --- a/nphysics_testbed3d/src/engine.rs +++ b/nphysics_testbed3d/src/engine.rs @@ -24,6 +24,7 @@ pub struct GraphicsManager { rand: XorShiftRng, b2sn: HashMap>, b2color: HashMap>, + c2color: HashMap>, arc_ball: ArcBall, first_person: FirstPerson, curr_is_arc_ball: bool, @@ -50,6 +51,7 @@ impl GraphicsManager { rand: rng, b2sn: HashMap::new(), b2color: HashMap::new(), + c2color: HashMap::new(), aabbs: Vec::new(), } } @@ -135,6 +137,11 @@ impl GraphicsManager { } } + pub fn set_collider_color(&mut self, handle: ColliderHandle, color: Point3) { + println!("Registering color: {:?} {}", handle, color); + self.c2color.insert(handle, color); + } + fn body_key(world: &World, handle: BodyHandle) -> BodyHandle { if let Body::Multibody(mb) = world.body(handle) { mb.handle() @@ -147,19 +154,24 @@ impl GraphicsManager { let mut color = Point3::new(0.5, 0.5, 0.5); let collider = world.collider(id).unwrap(); - let body_key = Self::body_key(world, collider.data().body()); - - match self.b2color.get(&body_key) { - Some(c) => color = *c, - None => { - if !collider.data().body().is_ground() { - color = self.rand.gen(); - color *= 1.5; - color.x = color.x.min(1.0); - color.y = color.y.min(1.0); - color.z = color.z.min(1.0); + if let Some(c) = self.c2color.get(&id).cloned() { + color = c + } else { + let body_key = Self::body_key(world, collider.data().body()); + match self.b2color.get(&body_key) { + Some(c) => color = *c, + None => { + if !collider.data().body().is_ground() { + color = self.rand.gen(); + color *= 1.5; + color.x = color.x.min(1.0); + color.y = color.y.min(1.0); + color.z = color.z.min(1.0); + } } } + + self.set_body_color(world, collider.data().body(), color); } self.add_with_color(window, id, world, color) @@ -185,8 +197,6 @@ impl GraphicsManager { let nodes = self.b2sn.entry(key).or_insert(Vec::new()); nodes.append(&mut new_nodes); } - - self.set_body_color(world, collider.data().body(), color); } fn add_shape( diff --git a/nphysics_testbed3d/src/testbed.rs b/nphysics_testbed3d/src/testbed.rs index 8c6f709ff..bde17c09b 100644 --- a/nphysics_testbed3d/src/testbed.rs +++ b/nphysics_testbed3d/src/testbed.rs @@ -17,7 +17,7 @@ use ncollide3d::query::{self, Ray}; use ncollide3d::utils::GenerationalId; use ncollide3d::world::CollisionGroups; use nphysics3d::joint::{ConstraintHandle, MouseConstraint}; -use nphysics3d::object::BodyHandle; +use nphysics3d::object::{BodyHandle, ColliderHandle}; use nphysics3d::world::World; #[derive(PartialEq)] @@ -131,6 +131,12 @@ impl Testbed { .set_body_color(world, body, color); } + pub fn set_collider_color(&mut self, collider: ColliderHandle, color: Point3) { + self.graphics + .borrow_mut() + .set_collider_color(collider, color); + } + // pub fn set_sensor_color(&mut self, sensor: &SensorHandle, color: Point3) { // self.graphics.borrow_mut().set_sensor_color(sensor, color); // } diff --git a/src/force_generator/constant_acceleration.rs b/src/force_generator/constant_acceleration.rs new file mode 100644 index 000000000..71a1e1b9c --- /dev/null +++ b/src/force_generator/constant_acceleration.rs @@ -0,0 +1,62 @@ +use na::Real; + +use solver::IntegrationParameters; +use force_generator::ForceGenerator; +use object::{BodyHandle, BodySet}; +use math::{Velocity, Vector}; + +/// Force generator adding a constant acceleration +/// at the center of mass of a set of body parts. +pub struct ConstantAcceleration { + parts: Vec, + acceleration: Velocity, +} + +impl ConstantAcceleration { + /// Adds a new constant acceleration generator. + /// + /// The acceleration is expressed in world-space. + #[cfg(feature = "dim3")] + pub fn new(linear_acc: Vector, angular_acc: Vector) -> Self { + ConstantAcceleration { + parts: Vec::new(), + acceleration: Velocity::new(linear_acc, angular_acc), + } + } + + /// Adds a new constant acceleration generator. + /// + /// The acceleration is expressed in world-space. + #[cfg(feature = "dim2")] + pub fn new(linear_acc: Vector, angular_acc: N) -> Self { + ConstantAcceleration { + parts: Vec::new(), + acceleration: Velocity::new(linear_acc, angular_acc), + } + } + + pub fn add_body_part(&mut self, body: BodyHandle) { + self.parts.push(body) + } +} + +impl ForceGenerator for ConstantAcceleration { + fn apply(&mut self, _: &IntegrationParameters, bodies: &mut BodySet) -> bool { + let mut i = 0; + + while i < self.parts.len() { + let body = self.parts[i]; + + if bodies.contains(body) { + let mut part = bodies.body_part_mut(body); + let force = part.as_ref().inertia() * self.acceleration; + part.apply_force(&force); + i += 1; + } else { + let _ = self.parts.swap_remove(i); + } + } + + true + } +} diff --git a/src/force_generator/mod.rs b/src/force_generator/mod.rs index cbcdb43ea..5159336f2 100644 --- a/src/force_generator/mod.rs +++ b/src/force_generator/mod.rs @@ -1,6 +1,7 @@ pub use self::force_generator::{ForceGenerator, ForceGeneratorHandle}; +pub use self::constant_acceleration::ConstantAcceleration; pub use self::spring::Spring; - mod force_generator; -mod spring; \ No newline at end of file +mod constant_acceleration; +mod spring; diff --git a/src/object/body.rs b/src/object/body.rs index 0f8c57ec6..9bdc18944 100644 --- a/src/object/body.rs +++ b/src/object/body.rs @@ -1,8 +1,8 @@ use na::{self, DVectorSlice, DVectorSliceMut, Real}; -use object::{BodyHandle, Ground, Multibody, MultibodyLinkRef, MultibodyLinkMut, RigidBody}; +use object::{BodyHandle, Ground, Multibody, MultibodyLinkMut, MultibodyLinkRef, RigidBody}; use solver::IntegrationParameters; -use math::{Force, Isometry, Point, Velocity}; +use math::{Force, Inertia, Isometry, Point, Velocity}; #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub enum BodyStatus { @@ -319,6 +319,24 @@ impl<'a, N: Real> BodyPart<'a, N> { } } + #[inline] + pub fn inertia(&self) -> Inertia { + match *self { + BodyPart::RigidBody(ref rb) => *rb.inertia(), + BodyPart::MultibodyLink(ref mb) => *mb.inertia(), + BodyPart::Ground(ref g) => g.inertia(), + } + } + + #[inline] + pub fn local_inertia(&self) -> Inertia { + match *self { + BodyPart::RigidBody(ref rb) => *rb.local_inertia(), + BodyPart::MultibodyLink(ref mb) => *mb.local_inertia(), + BodyPart::Ground(ref g) => g.local_inertia(), + } + } + #[inline] pub fn status_dependent_velocity(&self) -> Velocity { match *self { @@ -382,5 +400,4 @@ impl<'a, N: Real> BodyPartMut<'a, N> { BodyPartMut::Ground(ref mut g) => g.apply_force(force), } } - -} \ No newline at end of file +} diff --git a/src/object/ground.rs b/src/object/ground.rs index 190e51113..c58a6bfff 100644 --- a/src/object/ground.rs +++ b/src/object/ground.rs @@ -1,6 +1,6 @@ use na::{self, DVectorSlice, DVectorSliceMut, Real}; -use math::{Force, Isometry, Point, Velocity}; +use math::{Force, Inertia, Isometry, Point, Velocity}; use object::{ActivationStatus, BodyHandle, BodyStatus}; use solver::IntegrationParameters; @@ -119,6 +119,16 @@ impl Ground { Velocity::zero() } + #[inline] + pub fn inertia(&self) -> Inertia { + Inertia::zero() + } + + #[inline] + pub fn local_inertia(&self) -> Inertia { + Inertia::zero() + } + #[inline] pub fn body_jacobian_mul_force(&self, _: &Force, _: &mut [N]) {} diff --git a/src/object/multibody_link.rs b/src/object/multibody_link.rs index 17376383f..5995e70ce 100644 --- a/src/object/multibody_link.rs +++ b/src/object/multibody_link.rs @@ -257,6 +257,16 @@ impl<'a, N: Real> MultibodyLinkRef<'a, N> { pub fn inv_mass_mul_force(&self, force: &Force, out: &mut [N]) { self.multibody.inv_mass_mul_force(self.id, force, out) } + + #[inline] + pub fn local_inertia(&self) -> &Inertia { + &self.link.local_inertia + } + + #[inline] + pub fn inertia(&self) -> &Inertia { + &self.link.inertia + } } // FIXME: keep this even if we already have the Index2 traits? diff --git a/src/world/world.rs b/src/world/world.rs index c02e0c2f4..a27c683e3 100644 --- a/src/world/world.rs +++ b/src/world/world.rs @@ -56,7 +56,10 @@ impl World { let gravity = Vector::zeros(); let params = IntegrationParameters::default(); let workspace = MultibodyWorkspace::new(); - cworld.register_broad_phase_pair_filter("__nphysics_internal_body_status_collision_filter", BodyStatusCollisionFilter); + cworld.register_broad_phase_pair_filter( + "__nphysics_internal_body_status_collision_filter", + BodyStatusCollisionFilter, + ); World { counters, @@ -198,7 +201,9 @@ impl World { .collision_object_mut(*collider_id) .expect("Internal error: collider not found."); let body = self.bodies.body_part(collider.data_mut().body()); - collider.data_mut().set_body_status_dependent_ndofs(body.status_dependent_parent_ndofs()); + collider + .data_mut() + .set_body_status_dependent_ndofs(body.status_dependent_parent_ndofs()); if !body.is_active() { continue; @@ -431,7 +436,10 @@ impl World { (to_parent, 0) } else { let parent = self.bodies.body_part(parent); - (parent.position() * to_parent, parent.status_dependent_parent_ndofs()) + ( + parent.position() * to_parent, + parent.status_dependent_parent_ndofs(), + ) }; let data = ColliderData::new(margin, parent, ndofs, to_parent, material); @@ -484,6 +492,9 @@ impl World { pub fn collision_world(&self) -> &CollisionWorld { &self.cworld } + pub fn collision_world_mut(&mut self) -> &mut CollisionWorld { + &mut self.cworld + } pub fn collider(&self, handle: ColliderHandle) -> Option<&Collider> { self.cworld.collision_object(handle) @@ -506,7 +517,6 @@ struct BodyStatusCollisionFilter; impl BroadPhasePairFilter> for BodyStatusCollisionFilter { /// Activate an action for when two objects start or stop to be close to each other. fn is_pair_valid(&self, b1: &Collider, b2: &Collider) -> bool { - b1.data().body_status_dependent_ndofs() != 0 || - b2.data().body_status_dependent_ndofs() != 0 + b1.data().body_status_dependent_ndofs() != 0 || b2.data().body_status_dependent_ndofs() != 0 } -} \ No newline at end of file +}