diff options
| author | Crozet Sébastien <developer@crozet.re> | 2020-11-03 15:34:01 +0100 |
|---|---|---|
| committer | Crozet Sébastien <developer@crozet.re> | 2020-11-03 15:34:01 +0100 |
| commit | db337c5df6de124e0fdff7eaa7aeebc28bfb27e6 (patch) | |
| tree | 60b0e03ee6345dcb4a4114ccb344486078116f84 | |
| parent | 71611d3e30ce2fddee20832db3c3e0c8b6ba0d07 (diff) | |
| download | rapier-db337c5df6de124e0fdff7eaa7aeebc28bfb27e6.tar.gz rapier-db337c5df6de124e0fdff7eaa7aeebc28bfb27e6.tar.bz2 rapier-db337c5df6de124e0fdff7eaa7aeebc28bfb27e6.zip | |
Add damping support + demos.
| -rw-r--r-- | examples2d/all_examples2.rs | 2 | ||||
| -rw-r--r-- | examples2d/damping2.rs | 45 | ||||
| -rw-r--r-- | examples3d/all_examples3.rs | 2 | ||||
| -rw-r--r-- | examples3d/damping3.rs | 45 | ||||
| -rw-r--r-- | src/dynamics/rigid_body.rs | 34 | ||||
| -rw-r--r-- | src_testbed/engine.rs | 1 | ||||
| -rw-r--r-- | src_testbed/testbed.rs | 11 |
7 files changed, 140 insertions, 0 deletions
diff --git a/examples2d/all_examples2.rs b/examples2d/all_examples2.rs index 052d6cc..92606d8 100644 --- a/examples2d/all_examples2.rs +++ b/examples2d/all_examples2.rs @@ -12,6 +12,7 @@ use std::cmp::Ordering; mod add_remove2; mod collision_groups2; +mod damping2; mod debug_box_ball2; mod heightfield2; mod joints2; @@ -55,6 +56,7 @@ pub fn main() { let mut builders: Vec<(_, fn(&mut Testbed))> = vec![ ("Add remove", add_remove2::init_world), ("Collision groups", collision_groups2::init_world), + ("Damping", damping2::init_world), ("Heightfield", heightfield2::init_world), ("Joints", joints2::init_world), ("Platform", platform2::init_world), diff --git a/examples2d/damping2.rs b/examples2d/damping2.rs new file mode 100644 index 0000000..43ca2b6 --- /dev/null +++ b/examples2d/damping2.rs @@ -0,0 +1,45 @@ +use na::{Point2, Vector2}; +use rapier2d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; +use rapier2d::geometry::{ColliderBuilder, ColliderSet}; +use rapier_testbed2d::Testbed; + +pub fn init_world(testbed: &mut Testbed) { + /* + * World + */ + let mut bodies = RigidBodySet::new(); + let mut colliders = ColliderSet::new(); + let joints = JointSet::new(); + + /* + * Create the balls + */ + let num = 10; + let rad = 0.2; + + let subdiv = 1.0 / (num as f32); + + for i in 0usize..num { + let (x, y) = (i as f32 * subdiv * std::f32::consts::PI * 2.0).sin_cos(); + + // Build the rigid body. + let rb = RigidBodyBuilder::new_dynamic() + .translation(x, y) + .linvel(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) + .build(); + let rb_handle = bodies.insert(rb); + + // Build the collider. + let co = ColliderBuilder::cuboid(rad, rad).build(); + colliders.insert(co, rb_handle, &mut bodies); + } + + /* + * Set up the testbed. + */ + testbed.set_world_with_gravity(bodies, colliders, joints, Vector2::zeros()); + testbed.look_at(Point2::new(3.0, 2.0), 50.0); +} diff --git a/examples3d/all_examples3.rs b/examples3d/all_examples3.rs index 2196605..9c1dffc 100644 --- a/examples3d/all_examples3.rs +++ b/examples3d/all_examples3.rs @@ -13,6 +13,7 @@ use std::cmp::Ordering; mod add_remove3; mod collision_groups3; mod compound3; +mod damping3; mod debug_boxes3; mod debug_cylinder3; mod debug_triangle3; @@ -69,6 +70,7 @@ pub fn main() { ("Primitives", primitives3::init_world), ("Collision groups", collision_groups3::init_world), ("Compound", compound3::init_world), + ("Damping", damping3::init_world), ("Domino", domino3::init_world), ("Heightfield", heightfield3::init_world), ("Joints", joints3::init_world), diff --git a/examples3d/damping3.rs b/examples3d/damping3.rs new file mode 100644 index 0000000..e055d8e --- /dev/null +++ b/examples3d/damping3.rs @@ -0,0 +1,45 @@ +use na::{Point3, Vector3}; +use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet}; +use rapier3d::geometry::{ColliderBuilder, ColliderSet}; +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(); + + /* + * Create the balls + */ + let num = 10; + let rad = 0.2; + + let subdiv = 1.0 / (num as f32); + + for i in 0usize..num { + let (x, y) = (i as f32 * subdiv * std::f32::consts::PI * 2.0).sin_cos(); + + // 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) + .linear_damping((i + 1) as f32 * subdiv * 10.0) + .angular_damping((num - i) as f32 * subdiv * 10.0) + .build(); + let rb_handle = bodies.insert(rb); + + // Build the collider. + let co = ColliderBuilder::cuboid(rad, rad, rad).build(); + colliders.insert(co, rb_handle, &mut bodies); + } + + /* + * Set up the testbed. + */ + testbed.set_world_with_gravity(bodies, colliders, joints, Vector3::zeros()); + testbed.look_at(Point3::new(2.0, 2.5, 20.0), Point3::new(2.0, 2.5, 0.0)); +} diff --git a/src/dynamics/rigid_body.rs b/src/dynamics/rigid_body.rs index d3bd8d7..4aaa474 100644 --- a/src/dynamics/rigid_body.rs +++ b/src/dynamics/rigid_body.rs @@ -42,6 +42,10 @@ pub struct RigidBody { pub linvel: Vector<f32>, /// The angular velocity of the rigid-body. pub angvel: AngVector<f32>, + /// Damping factor for gradually slowing down the translational motion of the rigid-body. + pub linear_damping: f32, + /// Damping factor for gradually slowing down the angular motion of the rigid-body. + pub angular_damping: f32, pub(crate) linacc: Vector<f32>, pub(crate) angacc: AngVector<f32>, pub(crate) colliders: Vec<ColliderHandle>, @@ -70,6 +74,8 @@ impl RigidBody { angvel: na::zero(), linacc: Vector::zeros(), angacc: na::zero(), + linear_damping: 0.0, + angular_damping: 0.0, colliders: Vec::new(), activation: ActivationStatus::new_active(), joint_graph_index: InteractionGraph::<()>::invalid_graph_index(), @@ -218,6 +224,10 @@ impl RigidBody { } pub(crate) fn integrate(&mut self, dt: f32) { + // TODO: do we want to apply damping before or after the velocity integration? + self.linvel *= 1.0 / (1.0 + dt * self.linear_damping); + self.angvel *= 1.0 / (1.0 + dt * self.angular_damping); + self.position = self.integrate_velocity(dt) * self.position; } @@ -338,6 +348,8 @@ pub struct RigidBodyBuilder { position: Isometry<f32>, linvel: Vector<f32>, angvel: AngVector<f32>, + linear_damping: f32, + angular_damping: f32, body_status: BodyStatus, mass_properties: MassProperties, can_sleep: bool, @@ -351,6 +363,8 @@ impl RigidBodyBuilder { position: Isometry::identity(), linvel: Vector::zeros(), angvel: na::zero(), + linear_damping: 0.0, + angular_damping: 0.0, body_status, mass_properties: MassProperties::zero(), can_sleep: true, @@ -438,6 +452,24 @@ impl RigidBodyBuilder { self } + /// Sets the damping factor for the linear part of the rigid-body motion. + /// + /// The higher the linear damping factor is, the more quickly the rigid-body + /// will slow-down its translational movement. + pub fn linear_damping(mut self, factor: f32) -> Self { + self.linear_damping = factor; + self + } + + /// Sets the damping factor for the angular part of the rigid-body motion. + /// + /// The higher the angular damping factor is, the more quickly the rigid-body + /// will slow-down its rotational movement. + pub fn angular_damping(mut self, factor: f32) -> Self { + self.angular_damping = factor; + self + } + /// Sets the initial linear velocity of the rigid-body to be created. #[cfg(feature = "dim2")] pub fn linvel(mut self, x: f32, y: f32) -> Self { @@ -474,6 +506,8 @@ impl RigidBodyBuilder { rb.body_status = self.body_status; rb.user_data = self.user_data; rb.mass_properties = self.mass_properties; + rb.linear_damping = self.linear_damping; + rb.angular_damping = self.angular_damping; if !self.can_sleep { rb.activation.threshold = -1.0; diff --git a/src_testbed/engine.rs b/src_testbed/engine.rs index 1bafdb6..52b9ca9 100644 --- a/src_testbed/engine.rs +++ b/src_testbed/engine.rs @@ -152,6 +152,7 @@ impl GraphicsManager { self.f2sn.clear(); #[cfg(feature = "fluids")] self.boundary2sn.clear(); + self.c2color.clear(); self.b2color.clear(); self.b2wireframe.clear(); self.rand = Pcg32::seed_from_u64(0); diff --git a/src_testbed/testbed.rs b/src_testbed/testbed.rs index 7160b3b..66b5953 100644 --- a/src_testbed/testbed.rs +++ b/src_testbed/testbed.rs @@ -405,8 +405,19 @@ impl Testbed { } pub fn set_world(&mut self, bodies: RigidBodySet, colliders: ColliderSet, joints: JointSet) { + self.set_world_with_gravity(bodies, colliders, joints, Vector::y() * -9.81) + } + + pub fn set_world_with_gravity( + &mut self, + bodies: RigidBodySet, + colliders: ColliderSet, + joints: JointSet, + gravity: Vector<f32>, + ) { println!("Num bodies: {}", bodies.len()); println!("Num joints: {}", joints.len()); + self.gravity = gravity; self.physics.bodies = bodies; self.physics.colliders = colliders; self.physics.joints = joints; |
