Add comments.
This commit is contained in:
@@ -6,7 +6,7 @@ use crate::geometry::{
|
||||
};
|
||||
use crate::math::{AngVector, AngularInertia, Isometry, Point, Real, Translation, Vector};
|
||||
use crate::parry::partitioning::IndexedData;
|
||||
use crate::utils::WDot;
|
||||
use crate::utils::{WCross, WDot};
|
||||
use num::Zero;
|
||||
|
||||
/// The unique handle of a rigid body added to a `RigidBodySet`.
|
||||
@@ -69,14 +69,17 @@ pub enum RigidBodyType {
|
||||
}
|
||||
|
||||
impl RigidBodyType {
|
||||
/// Is this rigid-body static (i.e. cannot move)?
|
||||
pub fn is_static(self) -> bool {
|
||||
self == RigidBodyType::Static
|
||||
}
|
||||
|
||||
/// Is this rigid-body dynamic (i.e. can move and be affected by forces)?
|
||||
pub fn is_dynamic(self) -> bool {
|
||||
self == RigidBodyType::Dynamic
|
||||
}
|
||||
|
||||
/// Is this rigid-body kinematic (i.e. can move but is unaffected by forces)?
|
||||
pub fn is_kinematic(self) -> bool {
|
||||
self == RigidBodyType::Kinematic
|
||||
}
|
||||
@@ -86,10 +89,15 @@ bitflags::bitflags! {
|
||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||
/// Flags describing how the rigid-body has been modified by the user.
|
||||
pub struct RigidBodyChanges: u32 {
|
||||
/// Flag indicating that any component of this rigid-body has been modified.
|
||||
const MODIFIED = 1 << 0;
|
||||
/// Flag indicating that the `RigidBodyPosition` component of this rigid-body has been modified.
|
||||
const POSITION = 1 << 1;
|
||||
/// Flag indicating that the `RigidBodyActivation` component of this rigid-body has been modified.
|
||||
const SLEEP = 1 << 2;
|
||||
/// Flag indicating that the `RigidBodyColliders` component of this rigid-body has been modified.
|
||||
const COLLIDERS = 1 << 3;
|
||||
/// Flag indicating that the `RigidBodyType` component of this rigid-body has been modified.
|
||||
const TYPE = 1 << 4;
|
||||
}
|
||||
}
|
||||
@@ -102,6 +110,7 @@ impl Default for RigidBodyChanges {
|
||||
|
||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||
#[derive(Clone, Debug, Copy)]
|
||||
/// The position of this rigid-body.
|
||||
pub struct RigidBodyPosition {
|
||||
/// The world-space position of the rigid-body.
|
||||
pub position: Isometry<Real>,
|
||||
@@ -127,6 +136,8 @@ impl Default for RigidBodyPosition {
|
||||
}
|
||||
|
||||
impl RigidBodyPosition {
|
||||
/// Computes the velocity need to travel from `self.position` to `self.next_position` in
|
||||
/// a time equal to `1.0 / inv_dt`.
|
||||
#[must_use]
|
||||
pub fn interpolate_velocity(&self, inv_dt: Real) -> RigidBodyVelocity {
|
||||
let dpos = self.next_position * self.position.inverse();
|
||||
@@ -143,6 +154,9 @@ impl RigidBodyPosition {
|
||||
RigidBodyVelocity { linvel, angvel }
|
||||
}
|
||||
|
||||
/// Compute new positions after integrating the given forces and velocities.
|
||||
///
|
||||
/// This uses a symplectic Euler integration scheme.
|
||||
#[must_use]
|
||||
pub fn integrate_forces_and_velocities(
|
||||
&self,
|
||||
@@ -173,16 +187,23 @@ bitflags::bitflags! {
|
||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||
/// Flags affecting the behavior of the constraints solver for a given contact manifold.
|
||||
pub struct RigidBodyMassPropsFlags: u8 {
|
||||
/// Flag indicating that the rigid-body cannot translate along any direction.
|
||||
const TRANSLATION_LOCKED = 1 << 0;
|
||||
/// Flag indicating that the rigid-body cannot rotate along the `X` axis.
|
||||
const ROTATION_LOCKED_X = 1 << 1;
|
||||
/// Flag indicating that the rigid-body cannot rotate along the `X` axis.
|
||||
const ROTATION_LOCKED_Y = 1 << 2;
|
||||
/// Flag indicating that the rigid-body cannot rotate along the `X` axis.
|
||||
const ROTATION_LOCKED_Z = 1 << 3;
|
||||
/// Combination of flags indicating that the rigid-body cannot rotate along any axis.
|
||||
const ROTATION_LOCKED = Self::ROTATION_LOCKED_X.bits | Self::ROTATION_LOCKED_Y.bits | Self::ROTATION_LOCKED_Z.bits;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: split this into "LocalMassProps" and `WorldMassProps"?
|
||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||
#[derive(Clone, Debug, Copy)]
|
||||
/// The mass properties of this rigid-bodies.
|
||||
pub struct RigidBodyMassProps {
|
||||
/// Flags for locking rotation and translation.
|
||||
pub flags: RigidBodyMassPropsFlags,
|
||||
@@ -219,16 +240,20 @@ impl From<RigidBodyMassPropsFlags> for RigidBodyMassProps {
|
||||
}
|
||||
|
||||
impl RigidBodyMassProps {
|
||||
/// The mass of the rigid-body.
|
||||
#[must_use]
|
||||
pub fn with_translations_locked(mut self) -> Self {
|
||||
self.flags |= RigidBodyMassPropsFlags::TRANSLATION_LOCKED;
|
||||
self
|
||||
pub fn mass(&self) -> Real {
|
||||
crate::utils::inv(self.mass_properties.inv_mass)
|
||||
}
|
||||
|
||||
/// The effective mass (that takes the potential translation locking into account) of
|
||||
/// this rigid-body.
|
||||
#[must_use]
|
||||
pub fn effective_mass(&self) -> Real {
|
||||
crate::utils::inv(self.effective_inv_mass)
|
||||
}
|
||||
|
||||
/// 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.mass_properties.world_com(&position);
|
||||
self.effective_inv_mass = self.mass_properties.inv_mass;
|
||||
@@ -286,6 +311,7 @@ impl RigidBodyMassProps {
|
||||
|
||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||
#[derive(Clone, Debug, Copy)]
|
||||
/// The velocities of this rigid-body.
|
||||
pub struct RigidBodyVelocity {
|
||||
/// The linear velocity of the rigid-body.
|
||||
pub linvel: Vector<Real>,
|
||||
@@ -300,6 +326,7 @@ impl Default for RigidBodyVelocity {
|
||||
}
|
||||
|
||||
impl RigidBodyVelocity {
|
||||
/// Velocities set to zero.
|
||||
#[must_use]
|
||||
pub fn zero() -> Self {
|
||||
Self {
|
||||
@@ -308,11 +335,16 @@ impl RigidBodyVelocity {
|
||||
}
|
||||
}
|
||||
|
||||
/// The approximate kinetic energy of this rigid-body.
|
||||
///
|
||||
/// This approximation does not take the rigid-body's mass and angular inertia
|
||||
/// into account.
|
||||
#[must_use]
|
||||
pub fn pseudo_kinetic_energy(&self) -> Real {
|
||||
self.linvel.norm_squared() + self.angvel.gdot(self.angvel)
|
||||
}
|
||||
|
||||
/// Returns the update velocities after applying the given damping.
|
||||
#[must_use]
|
||||
pub fn apply_damping(&self, dt: Real, damping: &RigidBodyDamping) -> Self {
|
||||
RigidBodyVelocity {
|
||||
@@ -321,6 +353,15 @@ impl RigidBodyVelocity {
|
||||
}
|
||||
}
|
||||
|
||||
/// The velocity of the given world-space point on this rigid-body.
|
||||
#[must_use]
|
||||
pub fn velocity_at_point(&self, point: &Point<Real>, world_com: &Point<Real>) -> Vector<Real> {
|
||||
let dpt = point - world_com;
|
||||
self.linvel + self.angvel.gcross(dpt)
|
||||
}
|
||||
|
||||
/// Integrate the velocities in `self` to compute obtain new positions when moving from the given
|
||||
/// inital position `init_pos`.
|
||||
#[must_use]
|
||||
pub fn integrate(
|
||||
&self,
|
||||
@@ -336,14 +377,81 @@ impl RigidBodyVelocity {
|
||||
result
|
||||
}
|
||||
|
||||
/// Are these velocities exactly equal to zero?
|
||||
#[must_use]
|
||||
pub fn is_zero(&self) -> bool {
|
||||
self.linvel.is_zero() && self.angvel.is_zero()
|
||||
}
|
||||
|
||||
/// The kinetic energy of this rigid-body.
|
||||
#[must_use]
|
||||
pub fn kinetic_energy(&self, rb_mprops: &RigidBodyMassProps) -> Real {
|
||||
let mut energy = (rb_mprops.mass() * self.linvel.norm_squared()) / 2.0;
|
||||
|
||||
#[cfg(feature = "dim2")]
|
||||
if !rb_mprops.effective_world_inv_inertia_sqrt.is_zero() {
|
||||
let inertia_sqrt = 1.0 / rb_mprops.effective_world_inv_inertia_sqrt;
|
||||
energy += (inertia_sqrt * self.angvel).powi(2) / 2.0;
|
||||
}
|
||||
|
||||
#[cfg(feature = "dim3")]
|
||||
if !rb_mprops.effective_world_inv_inertia_sqrt.is_zero() {
|
||||
let inertia_sqrt = rb_mprops
|
||||
.effective_world_inv_inertia_sqrt
|
||||
.inverse_unchecked();
|
||||
energy += (inertia_sqrt * self.angvel).norm_squared() / 2.0;
|
||||
}
|
||||
|
||||
energy
|
||||
}
|
||||
|
||||
/// Applies an impulse at the center-of-mass of this rigid-body.
|
||||
/// The impulse is applied right away, changing the linear velocity.
|
||||
/// This does nothing on non-dynamic bodies.
|
||||
pub fn apply_impulse(&mut self, rb_mprops: &RigidBodyMassProps, impulse: Vector<Real>) {
|
||||
self.linvel += impulse * rb_mprops.effective_inv_mass;
|
||||
}
|
||||
|
||||
/// Applies an angular impulse at the center-of-mass of this rigid-body.
|
||||
/// The impulse is applied right away, changing the angular velocity.
|
||||
/// This does nothing on non-dynamic bodies.
|
||||
#[cfg(feature = "dim2")]
|
||||
pub fn apply_torque_impulse(&mut self, rb_mprops: &RigidBodyMassProps, torque_impulse: Real) {
|
||||
self.angvel += rb_mprops.effective_world_inv_inertia_sqrt
|
||||
* (rb_mprops.effective_world_inv_inertia_sqrt * torque_impulse);
|
||||
}
|
||||
|
||||
/// Applies an angular impulse at the center-of-mass of this rigid-body.
|
||||
/// The impulse is applied right away, changing the angular velocity.
|
||||
/// This does nothing on non-dynamic bodies.
|
||||
#[cfg(feature = "dim3")]
|
||||
pub fn apply_torque_impulse(
|
||||
&mut self,
|
||||
rb_mprops: &RigidBodyMassProps,
|
||||
torque_impulse: Vector<Real>,
|
||||
) {
|
||||
self.angvel += rb_mprops.effective_world_inv_inertia_sqrt
|
||||
* (rb_mprops.effective_world_inv_inertia_sqrt * torque_impulse);
|
||||
}
|
||||
|
||||
/// Applies an impulse at the given world-space point of this rigid-body.
|
||||
/// The impulse is applied right away, changing the linear and/or angular velocities.
|
||||
/// This does nothing on non-dynamic bodies.
|
||||
pub fn apply_impulse_at_point(
|
||||
&mut self,
|
||||
rb_mprops: &RigidBodyMassProps,
|
||||
impulse: Vector<Real>,
|
||||
point: Point<Real>,
|
||||
) {
|
||||
let torque_impulse = (point - rb_mprops.world_com).gcross(impulse);
|
||||
self.apply_impulse(rb_mprops, impulse);
|
||||
self.apply_torque_impulse(rb_mprops, torque_impulse);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||
#[derive(Clone, Debug, Copy)]
|
||||
/// Damping factors to progressively slow down a rigid-body.
|
||||
pub struct RigidBodyDamping {
|
||||
/// Damping factor for gradually slowing down the translational motion of the rigid-body.
|
||||
pub linear_damping: Real,
|
||||
@@ -362,11 +470,14 @@ impl Default for RigidBodyDamping {
|
||||
|
||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||
#[derive(Clone, Debug, Copy)]
|
||||
/// The user-defined external forces applied to this rigid-body.
|
||||
pub struct RigidBodyForces {
|
||||
/// Accumulation of external forces (only for dynamic bodies).
|
||||
pub force: Vector<Real>,
|
||||
/// Accumulation of external torques (only for dynamic bodies).
|
||||
pub torque: AngVector<Real>,
|
||||
/// Gravity is multiplied by this scaling factor before it's
|
||||
/// applied to this rigid-body.
|
||||
pub gravity_scale: Real,
|
||||
}
|
||||
|
||||
@@ -381,6 +492,7 @@ impl Default for RigidBodyForces {
|
||||
}
|
||||
|
||||
impl RigidBodyForces {
|
||||
/// Integrate these forces to compute new velocities.
|
||||
#[must_use]
|
||||
pub fn integrate(
|
||||
&self,
|
||||
@@ -398,17 +510,41 @@ impl RigidBodyForces {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_linear_acceleration(&mut self, gravity: &Vector<Real>, mass: Real) {
|
||||
/// Adds to `self` the gravitational force that would result in a gravitational acceleration
|
||||
/// equal to `gravity`.
|
||||
pub fn add_gravity_acceleration(&mut self, gravity: &Vector<Real>, mass: Real) {
|
||||
self.force += gravity * self.gravity_scale * mass;
|
||||
}
|
||||
|
||||
/// Applies a force at the given world-space point of the rigid-body with the given mass properties.
|
||||
pub fn apply_force_at_point(
|
||||
&mut self,
|
||||
rb_mprops: &RigidBodyMassProps,
|
||||
force: Vector<Real>,
|
||||
point: Point<Real>,
|
||||
) {
|
||||
self.force += force;
|
||||
self.torque += (point - rb_mprops.world_com).gcross(force);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||
#[derive(Clone, Debug, Copy)]
|
||||
/// Information used for Continuous-Collision-Detection.
|
||||
pub struct RigidBodyCcd {
|
||||
/// The distance used by the CCD solver to decide if a movement would
|
||||
/// result in a tunnelling problem.
|
||||
pub ccd_thickness: Real,
|
||||
/// The max distance between this rigid-body's center of mass and its
|
||||
/// furthest collider point.
|
||||
pub ccd_max_dist: Real,
|
||||
/// Is CCD active for this rigid-body?
|
||||
///
|
||||
/// If `self.ccd_enabled` is `true`, then this is automatically set to
|
||||
/// `true` when the CCD solver detects that the rigid-body is moving fast
|
||||
/// enough to potential cause a tunneling problem.
|
||||
pub ccd_active: bool,
|
||||
/// Is CCD enabled for this rigid-body?
|
||||
pub ccd_enabled: bool,
|
||||
}
|
||||
|
||||
@@ -424,6 +560,8 @@ impl Default for RigidBodyCcd {
|
||||
}
|
||||
|
||||
impl RigidBodyCcd {
|
||||
/// The maximum velocity any point of any collider attached to this rigid-body
|
||||
/// moving with the given velocity can have.
|
||||
pub fn max_point_velocity(&self, vels: &RigidBodyVelocity) -> Real {
|
||||
#[cfg(feature = "dim2")]
|
||||
return vels.linvel.norm() + vels.angvel.abs() * self.ccd_max_dist;
|
||||
@@ -431,6 +569,7 @@ impl RigidBodyCcd {
|
||||
return vels.linvel.norm() + vels.angvel.norm() * self.ccd_max_dist;
|
||||
}
|
||||
|
||||
/// Is this rigid-body moving fast enough so that it may cause a tunneling problem?
|
||||
pub fn is_moving_fast(
|
||||
&self,
|
||||
dt: Real,
|
||||
@@ -463,12 +602,13 @@ impl RigidBodyCcd {
|
||||
|
||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||
#[derive(Clone, Debug, Copy)]
|
||||
/// Internal identifiers used by the physics engine.
|
||||
pub struct RigidBodyIds {
|
||||
pub joint_graph_index: RigidBodyGraphIndex,
|
||||
pub active_island_id: usize,
|
||||
pub active_set_id: usize,
|
||||
pub active_set_offset: usize,
|
||||
pub active_set_timestamp: u32,
|
||||
pub(crate) joint_graph_index: RigidBodyGraphIndex,
|
||||
pub(crate) active_island_id: usize,
|
||||
pub(crate) active_set_id: usize,
|
||||
pub(crate) active_set_offset: usize,
|
||||
pub(crate) active_set_timestamp: u32,
|
||||
}
|
||||
|
||||
impl Default for RigidBodyIds {
|
||||
@@ -485,6 +625,11 @@ impl Default for RigidBodyIds {
|
||||
|
||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||
#[derive(Clone, Debug)]
|
||||
/// The set of colliders attached to this rigid-bodies.
|
||||
///
|
||||
/// This should not be modified manually unless you really know what
|
||||
/// you are doing (for example if you are trying to integrate Rapier
|
||||
/// to a game engine using its component-based interface).
|
||||
pub struct RigidBodyColliders(pub Vec<ColliderHandle>);
|
||||
|
||||
impl Default for RigidBodyColliders {
|
||||
@@ -494,6 +639,7 @@ impl Default for RigidBodyColliders {
|
||||
}
|
||||
|
||||
impl RigidBodyColliders {
|
||||
/// Detach a collider from this rigid-body.
|
||||
pub fn detach_collider(
|
||||
&mut self,
|
||||
rb_changes: &mut RigidBodyChanges,
|
||||
@@ -508,6 +654,7 @@ impl RigidBodyColliders {
|
||||
}
|
||||
}
|
||||
|
||||
/// Attach a collider to this rigid-body.
|
||||
pub fn attach_collider(
|
||||
&mut self,
|
||||
rb_changes: &mut RigidBodyChanges,
|
||||
@@ -541,6 +688,7 @@ impl RigidBodyColliders {
|
||||
rb_mprops.update_world_mass_properties(&rb_pos.position);
|
||||
}
|
||||
|
||||
/// Update the positions of all the colliders attached to this rigid-body.
|
||||
pub fn update_positions<Colliders>(
|
||||
&self,
|
||||
colliders: &mut Colliders,
|
||||
@@ -574,6 +722,7 @@ impl RigidBodyColliders {
|
||||
|
||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||
#[derive(Clone, Debug, Copy)]
|
||||
/// The dominance groups of a rigid-body.
|
||||
pub struct RigidBodyDominance(pub i8);
|
||||
|
||||
impl Default for RigidBodyDominance {
|
||||
@@ -583,6 +732,7 @@ impl Default for RigidBodyDominance {
|
||||
}
|
||||
|
||||
impl RigidBodyDominance {
|
||||
/// The actually dominance group of this rigid-body, after taking into account its type.
|
||||
pub fn effective_group(&self, status: &RigidBodyType) -> i16 {
|
||||
if status.is_dynamic() {
|
||||
self.0 as i16
|
||||
@@ -643,6 +793,7 @@ impl RigidBodyActivation {
|
||||
self.energy != 0.0
|
||||
}
|
||||
|
||||
/// Wakes up this rigid-body.
|
||||
#[inline]
|
||||
pub fn wake_up(&mut self, strong: bool) {
|
||||
self.sleeping = false;
|
||||
@@ -651,6 +802,7 @@ impl RigidBodyActivation {
|
||||
}
|
||||
}
|
||||
|
||||
/// Put this rigid-body to sleep.
|
||||
#[inline]
|
||||
pub fn sleep(&mut self) {
|
||||
self.energy = 0.0;
|
||||
|
||||
Reference in New Issue
Block a user