diff options
| author | Sébastien Crozet <developer@crozet.re> | 2022-01-16 16:40:59 +0100 |
|---|---|---|
| committer | Sébastien Crozet <developer@crozet.re> | 2022-01-16 16:52:40 +0100 |
| commit | 0703e5527fd95d86bb6621e61dbcb1a6e7f9329a (patch) | |
| tree | 806e7d950015875ebfcca5520784aea6e7c5ae10 /src/dynamics/joint | |
| parent | 4454a845e98b990abf3929ca46b59d0fca5a18ec (diff) | |
| download | rapier-0703e5527fd95d86bb6621e61dbcb1a6e7f9329a.tar.gz rapier-0703e5527fd95d86bb6621e61dbcb1a6e7f9329a.tar.bz2 rapier-0703e5527fd95d86bb6621e61dbcb1a6e7f9329a.zip | |
Fix some solver issues
- Fix the wrong codepath taken by the solver for contacts involving a collider without parent.
- Properly adress the non-linear treatment of the friction direction
- Simplify the sleeping strategy
- Add an impulse resolution multiplier
Diffstat (limited to 'src/dynamics/joint')
6 files changed, 44 insertions, 9 deletions
diff --git a/src/dynamics/joint/impulse_joint/impulse_joint_set.rs b/src/dynamics/joint/impulse_joint/impulse_joint_set.rs index 183b668..890f021 100644 --- a/src/dynamics/joint/impulse_joint/impulse_joint_set.rs +++ b/src/dynamics/joint/impulse_joint/impulse_joint_set.rs @@ -100,7 +100,7 @@ impl ImpulseJointSet { /// Gets the joint with the given handle without a known generation. /// - /// This is useful when you know you want the joint at position `i` but + /// This is useful when you know you want the joint at index `i` but /// don't know what is its current generation number. Generation numbers are /// used to protect from the ABA problem because the joint position `i` /// are recycled between two insertion and a removal. diff --git a/src/dynamics/joint/joint_data.rs b/src/dynamics/joint/joint_data.rs index 35d832d..b1ad6c6 100644 --- a/src/dynamics/joint/joint_data.rs +++ b/src/dynamics/joint/joint_data.rs @@ -218,12 +218,14 @@ impl JointData { } /// Set the spring-like model used by the motor to reach the desired target velocity and position. + #[must_use] pub fn motor_model(mut self, axis: JointAxis, model: MotorModel) -> Self { self.motors[axis as usize].model = model; self } /// Sets the target velocity this motor needs to reach. + #[must_use] pub fn motor_velocity(self, axis: JointAxis, target_vel: Real, factor: Real) -> Self { self.motor_axis( axis, @@ -235,6 +237,7 @@ impl JointData { } /// Sets the target angle this motor needs to reach. + #[must_use] pub fn motor_position( self, axis: JointAxis, @@ -246,6 +249,7 @@ impl JointData { } /// Configure both the target angle and target velocity of the motor. + #[must_use] pub fn motor_axis( mut self, axis: JointAxis, @@ -263,6 +267,7 @@ impl JointData { self } + #[must_use] pub fn motor_max_impulse(mut self, axis: JointAxis, max_impulse: Real) -> Self { self.motors[axis as usize].max_impulse = max_impulse; self diff --git a/src/dynamics/joint/multibody_joint/multibody.rs b/src/dynamics/joint/multibody_joint/multibody.rs index 1b88245..e31a333 100644 --- a/src/dynamics/joint/multibody_joint/multibody.rs +++ b/src/dynamics/joint/multibody_joint/multibody.rs @@ -62,7 +62,10 @@ fn concat_rb_mass_matrix( } /// An articulated body simulated using the reduced-coordinates approach. +#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] +#[derive(Clone)] pub struct Multibody { + // TODO: serialization: skip the workspace fields. links: MultibodyLinkVec, pub(crate) velocities: DVector<Real>, pub(crate) damping: DVector<Real>, diff --git a/src/dynamics/joint/multibody_joint/multibody_joint.rs b/src/dynamics/joint/multibody_joint/multibody_joint.rs index 92749c1..1d14680 100644 --- a/src/dynamics/joint/multibody_joint/multibody_joint.rs +++ b/src/dynamics/joint/multibody_joint/multibody_joint.rs @@ -11,6 +11,7 @@ use na::{DVector, DVectorSliceMut}; #[cfg(feature = "dim3")] use na::{UnitQuaternion, Vector3}; +#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[derive(Copy, Clone, Debug)] pub struct MultibodyJoint { pub data: JointData, diff --git a/src/dynamics/joint/multibody_joint/multibody_joint_set.rs b/src/dynamics/joint/multibody_joint/multibody_joint_set.rs index 8337158..24b329f 100644 --- a/src/dynamics/joint/multibody_joint/multibody_joint_set.rs +++ b/src/dynamics/joint/multibody_joint/multibody_joint_set.rs @@ -1,4 +1,4 @@ -use crate::data::{Arena, Coarena, ComponentSet, ComponentSetMut}; +use crate::data::{Arena, Coarena, ComponentSet, ComponentSetMut, Index}; use crate::dynamics::joint::MultibodyLink; use crate::dynamics::{ IslandManager, JointData, Multibody, MultibodyJoint, RigidBodyActivation, RigidBodyHandle, @@ -6,19 +6,18 @@ use crate::dynamics::{ }; use crate::geometry::{InteractionGraph, RigidBodyGraphIndex}; use crate::parry::partitioning::IndexedData; -use std::ops::Index; /// The unique handle of an multibody_joint added to a `MultibodyJointSet`. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[repr(transparent)] -pub struct MultibodyJointHandle(pub crate::data::arena::Index); +pub struct MultibodyJointHandle(pub Index); /// The temporary index of a multibody added to a `MultibodyJointSet`. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[repr(transparent)] -pub struct MultibodyIndex(pub crate::data::arena::Index); +pub struct MultibodyIndex(pub Index); impl MultibodyJointHandle { /// Converts this handle into its (index, generation) components. @@ -28,12 +27,12 @@ impl MultibodyJointHandle { /// Reconstructs an handle from its (index, generation) components. pub fn from_raw_parts(id: u32, generation: u32) -> Self { - Self(crate::data::arena::Index::from_raw_parts(id, generation)) + Self(Index::from_raw_parts(id, generation)) } /// An always-invalid rigid-body handle. pub fn invalid() -> Self { - Self(crate::data::arena::Index::from_raw_parts( + Self(Index::from_raw_parts( crate::INVALID_U32, crate::INVALID_U32, )) @@ -55,6 +54,7 @@ impl IndexedData for MultibodyJointHandle { } } +#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct MultibodyJointLink { pub graph_id: RigidBodyGraphIndex, @@ -66,7 +66,7 @@ impl Default for MultibodyJointLink { fn default() -> Self { Self { graph_id: RigidBodyGraphIndex::new(crate::INVALID_U32), - multibody: MultibodyIndex(crate::data::arena::Index::from_raw_parts( + multibody: MultibodyIndex(Index::from_raw_parts( crate::INVALID_U32, crate::INVALID_U32, )), @@ -76,6 +76,8 @@ impl Default for MultibodyJointLink { } /// A set of rigid bodies that can be handled by a physics pipeline. +#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] +#[derive(Clone)] pub struct MultibodyJointSet { pub(crate) multibodies: Arena<Multibody>, // NOTE: a Slab would be sufficient. pub(crate) rb2mb: Coarena<MultibodyJointLink>, @@ -316,6 +318,26 @@ impl MultibodyJointSet { Some((multibody, link.id)) } + /// Gets the joint with the given handle without a known generation. + /// + /// This is useful when you know you want the joint at index `i` but + /// don't know what is its current generation number. Generation numbers are + /// used to protect from the ABA problem because the joint position `i` + /// are recycled between two insertion and a removal. + /// + /// Using this is discouraged in favor of `self.get(handle)` which does not + /// suffer form the ABA problem. + pub fn get_unknown_gen(&self, i: u32) -> Option<(&Multibody, usize, MultibodyJointHandle)> { + let link = self.rb2mb.get_unknown_gen(i)?; + let gen = self.rb2mb.get_gen(i)?; + let multibody = self.multibodies.get(link.multibody.0)?; + Some(( + multibody, + link.id, + MultibodyJointHandle(Index::from_raw_parts(i, gen)), + )) + } + /// Iterate through the handles of all the rigid-bodies attached to this rigid-body /// by an multibody_joint. pub fn attached_bodies<'a>( @@ -335,7 +357,7 @@ impl MultibodyJointSet { } } -impl Index<MultibodyIndex> for MultibodyJointSet { +impl std::ops::Index<MultibodyIndex> for MultibodyJointSet { type Output = Multibody; fn index(&self, index: MultibodyIndex) -> &Multibody { diff --git a/src/dynamics/joint/multibody_joint/multibody_link.rs b/src/dynamics/joint/multibody_joint/multibody_link.rs index 4738865..3c35446 100644 --- a/src/dynamics/joint/multibody_joint/multibody_link.rs +++ b/src/dynamics/joint/multibody_joint/multibody_link.rs @@ -5,6 +5,8 @@ use crate::math::{Isometry, Real, Vector}; use crate::prelude::RigidBodyVelocity; /// One link of a multibody. +#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] +#[derive(Clone)] pub struct MultibodyLink { // FIXME: make all those private. pub(crate) internal_id: usize, @@ -96,6 +98,8 @@ impl MultibodyLink { } // FIXME: keep this even if we already have the Index2 traits? +#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] +#[derive(Clone)] pub(crate) struct MultibodyLinkVec(pub Vec<MultibodyLink>); impl MultibodyLinkVec { |
