From c32da78f2a6014c491aa3e975fb83ddb7c80610e Mon Sep 17 00:00:00 2001 From: Crozet Sébastien Date: Mon, 26 Apr 2021 17:59:25 +0200 Subject: Split rigid-bodies and colliders into multiple components --- examples3d/debug_add_remove_collider3.rs | 7 +++- examples3d/debug_dynamic_collider_add3.rs | 4 ++- examples3d/fountain3.rs | 9 +++-- examples3d/joints3.rs | 20 +++++------ examples3d/one_way_platforms3.rs | 43 +++++++++++++----------- examples3d/platform3.rs | 56 +++++++++++++++++++------------ 6 files changed, 82 insertions(+), 57 deletions(-) (limited to 'examples3d') diff --git a/examples3d/debug_add_remove_collider3.rs b/examples3d/debug_add_remove_collider3.rs index f353162..9aab754 100644 --- a/examples3d/debug_add_remove_collider3.rs +++ b/examples3d/debug_add_remove_collider3.rs @@ -38,7 +38,12 @@ pub fn init_world(testbed: &mut Testbed) { // Remove then re-add the ground collider. let coll = physics .colliders - .remove(ground_collider_handle, &mut physics.bodies, true) + .remove( + ground_collider_handle, + &mut physics.islands, + &mut physics.bodies, + true, + ) .unwrap(); ground_collider_handle = physics .colliders diff --git a/examples3d/debug_dynamic_collider_add3.rs b/examples3d/debug_dynamic_collider_add3.rs index bd7205e..61c1482 100644 --- a/examples3d/debug_dynamic_collider_add3.rs +++ b/examples3d/debug_dynamic_collider_add3.rs @@ -79,7 +79,9 @@ pub fn init_world(testbed: &mut Testbed) { step = snapped_frame; for handle in &extra_colliders { - physics.colliders.remove(*handle, &mut physics.bodies, true); + physics + .colliders + .remove(*handle, &mut physics.islands, &mut physics.bodies, true); } extra_colliders.clear(); diff --git a/examples3d/fountain3.rs b/examples3d/fountain3.rs index 6c80562..08e1dfe 100644 --- a/examples3d/fountain3.rs +++ b/examples3d/fountain3.rs @@ -61,9 +61,12 @@ pub fn init_world(testbed: &mut Testbed) { let num_to_remove = to_remove.len() - MAX_NUMBER_OF_BODIES; for (handle, _) in &to_remove[..num_to_remove] { - physics - .bodies - .remove(*handle, &mut physics.colliders, &mut physics.joints); + physics.bodies.remove( + *handle, + &mut physics.islands, + &mut physics.colliders, + &mut physics.joints, + ); if let (Some(graphics), Some(window)) = (&mut graphics, &mut window) { graphics.remove_body_nodes(window, *handle); diff --git a/examples3d/joints3.rs b/examples3d/joints3.rs index 6ba9461..5b082fb 100644 --- a/examples3d/joints3.rs +++ b/examples3d/joints3.rs @@ -1,7 +1,7 @@ use na::{Isometry3, Point3, Unit, UnitQuaternion, Vector3}; use rapier3d::dynamics::{ - BallJoint, BodyStatus, FixedJoint, JointSet, PrismaticJoint, RevoluteJoint, RigidBodyBuilder, - RigidBodyHandle, RigidBodySet, + BallJoint, FixedJoint, JointSet, PrismaticJoint, RevoluteJoint, RigidBodyBuilder, + RigidBodyHandle, RigidBodySet, RigidBodyType, }; use rapier3d::geometry::{ColliderBuilder, ColliderSet}; use rapier_testbed3d::Testbed; @@ -203,9 +203,9 @@ fn create_fixed_joints( // fixed bodies. Because physx will crash if we add // a joint between these. let status = if i == 0 && (k % 4 == 0 && k != num - 2 || k == num - 1) { - BodyStatus::Static + RigidBodyType::Static } else { - BodyStatus::Dynamic + RigidBodyType::Dynamic }; let rigid_body = RigidBodyBuilder::new(status) @@ -258,9 +258,9 @@ fn create_ball_joints( let fi = i as f32; let status = if i == 0 && (k % 4 == 0 || k == num - 1) { - BodyStatus::Static + RigidBodyType::Static } else { - BodyStatus::Dynamic + RigidBodyType::Dynamic }; let rigid_body = RigidBodyBuilder::new(status) @@ -317,9 +317,9 @@ fn create_actuated_revolute_joints( // fixed bodies. Because physx will crash if we add // a joint between these. let status = if i == 0 { - BodyStatus::Static + RigidBodyType::Static } else { - BodyStatus::Dynamic + RigidBodyType::Dynamic }; let shifty = (i >= 1) as u32 as f32 * -2.0; @@ -378,9 +378,9 @@ fn create_actuated_ball_joints( // fixed bodies. Because physx will crash if we add // a joint between these. let status = if i == 0 { - BodyStatus::Static + RigidBodyType::Static } else { - BodyStatus::Dynamic + RigidBodyType::Dynamic }; let rigid_body = RigidBodyBuilder::new(status) diff --git a/examples3d/one_way_platforms3.rs b/examples3d/one_way_platforms3.rs index d117a5b..f5a2f1b 100644 --- a/examples3d/one_way_platforms3.rs +++ b/examples3d/one_way_platforms3.rs @@ -9,36 +9,39 @@ struct OneWayPlatformHook { platform2: ColliderHandle, } -impl PhysicsHooks for OneWayPlatformHook { +impl PhysicsHooks for OneWayPlatformHook { fn active_hooks(&self) -> PhysicsHooksFlags { PhysicsHooksFlags::MODIFY_SOLVER_CONTACTS } - fn modify_solver_contacts(&self, context: &mut ContactModificationContext) { + fn modify_solver_contacts( + &self, + context: &mut ContactModificationContext, + ) { // The allowed normal for the first platform is its local +y axis, and the // allowed normal for the second platform is its local -y axis. // // Now we have to be careful because the `manifold.local_n1` normal points // toward the outside of the shape of `context.co1`. So we need to flip the - // allowed normal direction if the platform is in `context.collider_handle2`. + // allowed normal direction if the platform is in `context.collider2`. // // Therefore: - // - If context.collider_handle1 == self.platform1 then the allowed normal is +y. - // - 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. + // - If context.collider1 == self.platform1 then the allowed normal is +y. + // - 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(); - if context.collider_handle1 == self.platform1 { + if context.collider1 == self.platform1 { allowed_local_n1 = Vector3::y(); - } else if context.collider_handle2 == self.platform1 { + } else if context.collider2 == self.platform1 { // Flip the allowed direction. allowed_local_n1 = -Vector3::y(); } - if context.collider_handle1 == self.platform2 { + if context.collider1 == self.platform2 { allowed_local_n1 = -Vector3::y(); - } else if context.collider_handle2 == self.platform2 { + } else if context.collider2 == self.platform2 { // Flip the allowed direction. allowed_local_n1 = Vector3::y(); } @@ -47,13 +50,12 @@ impl PhysicsHooks for OneWayPlatformHook { context.update_as_oneway_platform(&allowed_local_n1, 0.1); // Set the surface velocity of the accepted contacts. - let tangent_velocity = if context.collider_handle1 == self.platform1 - || context.collider_handle2 == self.platform2 - { - -12.0 - } else { - 12.0 - }; + let tangent_velocity = + if context.collider1 == self.platform1 || context.collider2 == self.platform2 { + -12.0 + } else { + 12.0 + }; for contact in context.solver_contacts.iter_mut() { contact.tangent_velocity.z = tangent_velocity; @@ -115,13 +117,14 @@ pub fn init_world(testbed: &mut Testbed) { } } - physics.bodies.foreach_active_dynamic_body_mut(|_, body| { + for handle in physics.islands.active_dynamic_bodies() { + let body = physics.bodies.get_mut(*handle).unwrap(); if body.position().translation.y > 1.0 { body.set_gravity_scale(1.0, false); } else if body.position().translation.y < -1.0 { body.set_gravity_scale(-1.0, false); } - }); + } }); /* diff --git a/examples3d/platform3.rs b/examples3d/platform3.rs index 7b5c986..cbe5b15 100644 --- a/examples3d/platform3.rs +++ b/examples3d/platform3.rs @@ -1,4 +1,4 @@ -use na::Point3; +use na::{Isometry3, Point3, UnitQuaternion, Vector3}; use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; use rapier3d::geometry::{ColliderBuilder, ColliderSet}; use rapier_testbed3d::Testbed; @@ -14,7 +14,7 @@ pub fn init_world(testbed: &mut Testbed) { /* * Ground. */ - let ground_size = 10.0; + let ground_size = 20.0; let ground_height = 0.1; let rigid_body = RigidBodyBuilder::new_static() @@ -27,25 +27,28 @@ pub fn init_world(testbed: &mut Testbed) { /* * Create the boxes */ - let num = 6; + let num = 1; let rad = 0.2; let shift = rad * 2.0; let centerx = shift * num as f32 / 2.0; - let centery = shift / 2.0 + 3.04; + let centery = shift / 2.0; let centerz = shift * num as f32 / 2.0; - for i in 0usize..num { + for i in 0usize..20 { for j in 0usize..num { for k in 0usize..num { - let x = i as f32 * shift - centerx; + let x = i as f32 * (shift + rad / 4.0) - centerx; let y = j as f32 * shift + centery; 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(x, y + rad, z) + .ccd_enabled(true) + .build(); let handle = bodies.insert(rigid_body); - let collider = ColliderBuilder::cuboid(rad, rad, rad).build(); + let collider = ColliderBuilder::cuboid(rad, rad * 2.0, rad).build(); colliders.insert(collider, handle, &mut bodies); } } @@ -55,11 +58,16 @@ pub fn init_world(testbed: &mut Testbed) { * Setup a kinematic rigid body. */ let platform_body = RigidBodyBuilder::new_kinematic() - .translation(0.0, 1.5 + 0.8, -10.0 * rad) + .translation(0.2, 0.4, -40.0 * rad) .build(); let 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); + let collider1 = ColliderBuilder::cuboid(rad * 5.0, rad * 2.0, rad * 10.0).build(); + let collider2 = ColliderBuilder::cuboid(rad * 5.0, rad * 2.0, rad * 10.0) + .position_wrt_parent(Isometry3::translation(0.0, rad * 2.1, 0.0)) + .build(); + colliders.insert(collider1, platform_handle, &mut bodies); + colliders.insert(collider2, platform_handle, &mut bodies); + testbed.set_body_color(platform_handle, Point3::new(1.0, 1.0, 0.0)); /* * Setup a callback to control the platform. @@ -67,23 +75,27 @@ pub fn init_world(testbed: &mut Testbed) { let mut count = 0; testbed.add_callback(move |_, _, physics, _, run_state| { count += 1; - if count % 100 > 50 { - return; - } + // if count % 100 > 50 { + // return; + // } if let Some(platform) = physics.bodies.get_mut(platform_handle) { let mut next_pos = *platform.position(); 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; + // next_pos.translation.vector.y += (run_state.time * 5.0).sin() * dt; + // next_pos.translation.vector.z += run_state.time.sin() * 5.0 * dt; - 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; - } + let drot = UnitQuaternion::new(Vector3::y() * 0.01); + next_pos.rotation = drot * next_pos.rotation; + next_pos.translation.vector += next_pos.rotation * Vector3::z() * 0.1; + + // 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); } -- cgit From 38104663261fc1617644cc17f6aa3b723a7db2ef Mon Sep 17 00:00:00 2001 From: Crozet Sébastien Date: Thu, 29 Apr 2021 10:33:07 +0200 Subject: Fix some warnings --- examples3d/platform3.rs | 56 +++++++++++++++++++------------------------------ 1 file changed, 22 insertions(+), 34 deletions(-) (limited to 'examples3d') diff --git a/examples3d/platform3.rs b/examples3d/platform3.rs index cbe5b15..7b5c986 100644 --- a/examples3d/platform3.rs +++ b/examples3d/platform3.rs @@ -1,4 +1,4 @@ -use na::{Isometry3, Point3, UnitQuaternion, Vector3}; +use na::Point3; use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; use rapier3d::geometry::{ColliderBuilder, ColliderSet}; use rapier_testbed3d::Testbed; @@ -14,7 +14,7 @@ pub fn init_world(testbed: &mut Testbed) { /* * Ground. */ - let ground_size = 20.0; + let ground_size = 10.0; let ground_height = 0.1; let rigid_body = RigidBodyBuilder::new_static() @@ -27,28 +27,25 @@ pub fn init_world(testbed: &mut Testbed) { /* * Create the boxes */ - let num = 1; + let num = 6; let rad = 0.2; let shift = rad * 2.0; let centerx = shift * num as f32 / 2.0; - let centery = shift / 2.0; + let centery = shift / 2.0 + 3.04; let centerz = shift * num as f32 / 2.0; - for i in 0usize..20 { + for i in 0usize..num { for j in 0usize..num { for k in 0usize..num { - let x = i as f32 * (shift + rad / 4.0) - centerx; + let x = i as f32 * shift - centerx; let y = j as f32 * shift + centery; let z = k as f32 * shift - centerz; // Build the rigid body. - let rigid_body = RigidBodyBuilder::new_dynamic() - .translation(x, y + rad, z) - .ccd_enabled(true) - .build(); + let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y, z).build(); let handle = bodies.insert(rigid_body); - let collider = ColliderBuilder::cuboid(rad, rad * 2.0, rad).build(); + let collider = ColliderBuilder::cuboid(rad, rad, rad).build(); colliders.insert(collider, handle, &mut bodies); } } @@ -58,16 +55,11 @@ pub fn init_world(testbed: &mut Testbed) { * Setup a kinematic rigid body. */ let platform_body = RigidBodyBuilder::new_kinematic() - .translation(0.2, 0.4, -40.0 * rad) + .translation(0.0, 1.5 + 0.8, -10.0 * rad) .build(); let platform_handle = bodies.insert(platform_body); - let collider1 = ColliderBuilder::cuboid(rad * 5.0, rad * 2.0, rad * 10.0).build(); - let collider2 = ColliderBuilder::cuboid(rad * 5.0, rad * 2.0, rad * 10.0) - .position_wrt_parent(Isometry3::translation(0.0, rad * 2.1, 0.0)) - .build(); - colliders.insert(collider1, platform_handle, &mut bodies); - colliders.insert(collider2, platform_handle, &mut bodies); - testbed.set_body_color(platform_handle, Point3::new(1.0, 1.0, 0.0)); + let collider = ColliderBuilder::cuboid(rad * 10.0, rad, rad * 10.0).build(); + colliders.insert(collider, platform_handle, &mut bodies); /* * Setup a callback to control the platform. @@ -75,27 +67,23 @@ pub fn init_world(testbed: &mut Testbed) { let mut count = 0; testbed.add_callback(move |_, _, physics, _, run_state| { count += 1; - // if count % 100 > 50 { - // return; - // } + if count % 100 > 50 { + return; + } if let Some(platform) = physics.bodies.get_mut(platform_handle) { let mut next_pos = *platform.position(); 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; - - let drot = UnitQuaternion::new(Vector3::y() * 0.01); - next_pos.rotation = drot * next_pos.rotation; - next_pos.translation.vector += next_pos.rotation * Vector3::z() * 0.1; + next_pos.translation.vector.y += (run_state.time * 5.0).sin() * dt; + next_pos.translation.vector.z += run_state.time.sin() * 5.0 * dt; - // 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; - // } + 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); } -- cgit From 2dfbd9ae92c139e306afc87994adac82489f30eb Mon Sep 17 00:00:00 2001 From: Crozet Sébastien Date: Fri, 30 Apr 2021 11:37:58 +0200 Subject: Add comments. --- examples3d/all_examples3.rs | 5 ++ examples3d/debug_shape_modification3.rs | 123 ++++++++++++++++++++++++++++++++ examples3d/primitives3.rs | 2 +- 3 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 examples3d/debug_shape_modification3.rs (limited to 'examples3d') diff --git a/examples3d/all_examples3.rs b/examples3d/all_examples3.rs index 2611a2f..8031814 100644 --- a/examples3d/all_examples3.rs +++ b/examples3d/all_examples3.rs @@ -25,6 +25,7 @@ mod debug_friction3; mod debug_infinite_fall3; mod debug_prismatic3; mod debug_rollback3; +mod debug_shape_modification3; mod debug_triangle3; mod debug_trimesh3; mod domino3; @@ -112,6 +113,10 @@ pub fn main() { ("(Debug) infinite fall", debug_infinite_fall3::init_world), ("(Debug) prismatic", debug_prismatic3::init_world), ("(Debug) rollback", debug_rollback3::init_world), + ( + "(Debug) shape modification", + debug_shape_modification3::init_world, + ), ]; // Lexicographic sort, with stress tests moved at the end of the list. diff --git a/examples3d/debug_shape_modification3.rs b/examples3d/debug_shape_modification3.rs new file mode 100644 index 0000000..7ec06dd --- /dev/null +++ b/examples3d/debug_shape_modification3.rs @@ -0,0 +1,123 @@ +use na::{Isometry3, Point3, Vector3}; +use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; +use rapier3d::geometry::{ColliderBuilder, ColliderSet, SharedShape}; +use rapier_testbed3d::Testbed; + +pub fn init_world(testbed: &mut Testbed) { + /* + * World + */ + let mut bodies = RigidBodySet::new(); + let mut colliders = ColliderSet::new(); + let joints = JointSet::new(); + /* + * Ground. + */ + let ground_size = 20.0; + let ground_height = 0.1; + + let rigid_body = RigidBodyBuilder::new_static() + .translation(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); + + /* + * 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) + .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 mut linvel = Vector3::zeros(); + let mut angvel = Vector3::zeros(); + let mut pos = Isometry3::identity(); + let mut step = 0; + let snapped_frame = 51; + + testbed.add_callback(move |_, _, physics, _, _| { + step += 1; + + // Snap the ball velocity or restore it. + let ball = physics.bodies.get_mut(ball_handle).unwrap(); + + if step == snapped_frame { + linvel = *ball.linvel(); + angvel = *ball.angvel(); + pos = *ball.position(); + } + + if step == 100 { + ball.set_linvel(linvel, true); + ball.set_angvel(angvel, true); + ball.set_position(pos, true); + step = snapped_frame; + } + + let ball_coll = physics.colliders.get_mut(ball_coll_handle).unwrap(); + ball_coll.set_shape(SharedShape::ball(ball_rad * step as f32 * 2.0)); + }); + + /* + * Create the primitives + */ + let num = 8; + let rad = 1.0; + + let shiftx = rad * 2.0 + rad; + let shifty = rad * 2.0 + rad; + let shiftz = rad * 2.0 + rad; + let centerx = shiftx * (num / 2) as f32; + let centery = shifty / 2.0; + let centerz = shiftz * (num / 2) as f32; + + let mut offset = -(num as f32) * (rad * 2.0 + rad) * 0.5; + + for j in 0usize..20 { + for i in 0..num { + for k in 0usize..num { + let x = i as f32 * shiftx - centerx + offset + 5.0; + let y = j as f32 * shifty + centery + 3.0; + let z = k as f32 * shiftz - centerz + offset; + + // Build the rigid body. + let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y, z).build(); + let handle = bodies.insert(rigid_body); + + let collider = match j % 5 { + 0 => ColliderBuilder::cuboid(rad, rad, rad).build(), + 1 => ColliderBuilder::ball(rad).build(), + // Rounded cylinders are much more efficient that cylinder, even if the + // rounding margin is small. + 2 => ColliderBuilder::round_cylinder(rad, rad, rad / 10.0).build(), + 3 => ColliderBuilder::cone(rad, rad).build(), + _ => ColliderBuilder::capsule_y(rad, rad).build(), + }; + + colliders.insert(collider, handle, &mut bodies); + } + } + + offset -= 0.05 * rad * (num as f32 - 1.0); + } + + /* + * Set up the testbed. + */ + testbed.set_world(bodies, colliders, joints); + testbed.look_at(Point3::new(10.0, 10.0, 10.0), Point3::origin()); +} + +fn main() { + let testbed = Testbed::from_builders(0, vec![("Boxes", init_world)]); + testbed.run() +} diff --git a/examples3d/primitives3.rs b/examples3d/primitives3.rs index db15341..2711ba9 100644 --- a/examples3d/primitives3.rs +++ b/examples3d/primitives3.rs @@ -25,7 +25,7 @@ pub fn init_world(testbed: &mut Testbed) { colliders.insert(collider, handle, &mut bodies); /* - * Create the cubes + * Create the primitives */ let num = 8; let rad = 1.0; -- cgit