diff options
| author | Sébastien Crozet <developer@crozet.re> | 2022-01-02 14:47:40 +0100 |
|---|---|---|
| committer | Sébastien Crozet <developer@crozet.re> | 2022-01-02 16:58:36 +0100 |
| commit | f74b8401ad9ef50b8cdbf1f43a2b21f6c42b0ebc (patch) | |
| tree | 53ac492fea5942a7d466f58a0095f39505674ea4 /src/dynamics/rigid_body_components.rs | |
| parent | b45d4b5ac2b31856c15e802b31e288a58940cbf2 (diff) | |
| download | rapier-f74b8401ad9ef50b8cdbf1f43a2b21f6c42b0ebc.tar.gz rapier-f74b8401ad9ef50b8cdbf1f43a2b21f6c42b0ebc.tar.bz2 rapier-f74b8401ad9ef50b8cdbf1f43a2b21f6c42b0ebc.zip | |
Implement multibody joints and the new solver
Diffstat (limited to 'src/dynamics/rigid_body_components.rs')
| -rw-r--r-- | src/dynamics/rigid_body_components.rs | 168 |
1 files changed, 165 insertions, 3 deletions
diff --git a/src/dynamics/rigid_body_components.rs b/src/dynamics/rigid_body_components.rs index a135a1c..e24cb57 100644 --- a/src/dynamics/rigid_body_components.rs +++ b/src/dynamics/rigid_body_components.rs @@ -4,9 +4,11 @@ use crate::geometry::{ ColliderChanges, ColliderHandle, ColliderMassProps, ColliderParent, ColliderPosition, ColliderShape, }; -use crate::math::{AngVector, AngularInertia, Isometry, Point, Real, Translation, Vector}; +use crate::math::{ + AngVector, AngularInertia, Isometry, Point, Real, Rotation, Translation, Vector, +}; use crate::parry::partitioning::IndexedData; -use crate::utils::{WCross, WDot}; +use crate::utils::{WAngularInertia, WCross, WDot}; use num::Zero; /// The unique handle of a rigid body added to a `RigidBodySet`. @@ -276,6 +278,13 @@ impl RigidBodyMassProps { crate::utils::inv(self.effective_inv_mass) } + /// The effective world-space angular inertia (that takes the potential rotation locking into account) of + /// this rigid-body. + #[must_use] + pub fn effective_angular_inertia(&self) -> AngularInertia<Real> { + self.effective_world_inv_inertia_sqrt.squared().inverse() + } + /// Update the world-space mass properties of `self`, taking into account the new position. pub fn update_world_mass_properties(&mut self, position: &Isometry<Real>) { self.world_com = self.local_mprops.world_com(&position); @@ -348,6 +357,51 @@ impl Default for RigidBodyVelocity { } impl RigidBodyVelocity { + /// Create a new rigid-body velocity component. + #[must_use] + pub fn new(linvel: Vector<Real>, angvel: AngVector<Real>) -> Self { + Self { linvel, angvel } + } + + /// Converts a slice to a rigid-body velocity. + /// + /// The slice must contain at least 3 elements: the `slice[0..2] contains + /// the linear velocity and the `slice[2]` contains the angular velocity. + #[must_use] + #[cfg(feature = "dim2")] + pub fn from_slice(slice: &[Real]) -> Self { + Self { + linvel: Vector::new(slice[0], slice[1]), + angvel: slice[2], + } + } + + /// Converts a slice to a rigid-body velocity. + /// + /// The slice must contain at least 6 elements: the `slice[0..3] contains + /// the linear velocity and the `slice[3..6]` contains the angular velocity. + #[must_use] + #[cfg(feature = "dim3")] + pub fn from_slice(slice: &[Real]) -> Self { + Self { + linvel: Vector::new(slice[0], slice[1], slice[2]), + angvel: AngVector::new(slice[3], slice[4], slice[5]), + } + } + + #[cfg(feature = "dim2")] + pub(crate) fn from_vectors(linvel: Vector<Real>, angvel: na::Vector1<Real>) -> Self { + Self { + linvel, + angvel: angvel.x, + } + } + + #[cfg(feature = "dim3")] + pub(crate) fn from_vectors(linvel: Vector<Real>, angvel: Vector<Real>) -> Self { + Self { linvel, angvel } + } + /// Velocities set to zero. #[must_use] pub fn zero() -> Self { @@ -357,6 +411,82 @@ impl RigidBodyVelocity { } } + /// This velocity seen as a slice. + /// + /// The linear part is stored first. + #[inline] + pub fn as_slice(&self) -> &[Real] { + self.as_vector().as_slice() + } + + /// This velocity seen as a mutable slice. + /// + /// The linear part is stored first. + #[inline] + pub fn as_mut_slice(&mut self) -> &mut [Real] { + self.as_vector_mut().as_mut_slice() + } + + /// This velocity seen as a vector. + /// + /// The linear part is stored first. + #[inline] + #[cfg(feature = "dim2")] + pub fn as_vector(&self) -> &na::Vector3<Real> { + unsafe { std::mem::transmute(self) } + } + + /// This velocity seen as a mutable vector. + /// + /// The linear part is stored first. + #[inline] + #[cfg(feature = "dim2")] + pub fn as_vector_mut(&mut self) -> &mut na::Vector3<Real> { + unsafe { std::mem::transmute(self) } + } + + /// This velocity seen as a vector. + /// + /// The linear part is stored first. + #[inline] + #[cfg(feature = "dim3")] + pub fn as_vector(&self) -> &na::Vector6<Real> { + unsafe { std::mem::transmute(self) } + } + + /// This velocity seen as a mutable vector. + /// + /// The linear part is stored first. + #[inline] + #[cfg(feature = "dim3")] + pub fn as_vector_mut(&mut self) -> &mut na::Vector6<Real> { + unsafe { std::mem::transmute(self) } + } + + /// Return `self` transformed by `transform`. + #[must_use] + pub fn transformed(self, transform: &Isometry<Real>) -> Self { + Self { + linvel: transform * self.linvel, + #[cfg(feature = "dim2")] + angvel: self.angvel, + #[cfg(feature = "dim3")] + angvel: transform * self.angvel, + } + } + + /// Return `self` rotated by `rotation`. + #[must_use] + pub fn rotated(self, rotation: &Rotation<Real>) -> Self { + Self { + linvel: rotation * self.linvel, + #[cfg(feature = "dim2")] + angvel: self.angvel, + #[cfg(feature = "dim3")] + angvel: rotation * self.angvel, + } + } + /// The approximate kinetic energy of this rigid-body. /// /// This approximation does not take the rigid-body's mass and angular inertia @@ -471,6 +601,38 @@ impl RigidBodyVelocity { } } +impl std::ops::Mul<Real> for RigidBodyVelocity { + type Output = Self; + + #[must_use] + fn mul(self, rhs: Real) -> Self { + RigidBodyVelocity { + linvel: self.linvel * rhs, + angvel: self.angvel * rhs, + } + } +} + +impl std::ops::Add<RigidBodyVelocity> for RigidBodyVelocity { + type Output = Self; + + #[must_use] + fn add(self, rhs: Self) -> Self { + RigidBodyVelocity { + linvel: self.linvel + rhs.linvel, + angvel: self.angvel + rhs.angvel, + } + } +} + +impl std::ops::AddAssign<RigidBodyVelocity> for RigidBodyVelocity { + #[must_use] + fn add_assign(&mut self, rhs: Self) { + self.linvel += rhs.linvel; + self.angvel += rhs.angvel; + } +} + #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[derive(Clone, Debug, Copy, PartialEq)] /// Damping factors to progressively slow down a rigid-body. @@ -784,7 +946,7 @@ impl Default for RigidBodyActivation { } impl RigidBodyActivation { - /// The default amount of energy bellow which a body can be put to sleep by nphysics. + /// The default amount of energy bellow which a body can be put to sleep by rapier. pub fn default_threshold() -> Real { 0.01 } |
