aboutsummaryrefslogtreecommitdiff
path: root/src/dynamics
diff options
context:
space:
mode:
Diffstat (limited to 'src/dynamics')
-rw-r--r--src/dynamics/island_manager.rs6
-rw-r--r--src/dynamics/joint/joint_set.rs4
-rw-r--r--src/dynamics/rigid_body.rs137
-rw-r--r--src/dynamics/rigid_body_components.rs172
-rw-r--r--src/dynamics/rigid_body_set.rs10
5 files changed, 203 insertions, 126 deletions
diff --git a/src/dynamics/island_manager.rs b/src/dynamics/island_manager.rs
index 551e5a4..b79cdb2 100644
--- a/src/dynamics/island_manager.rs
+++ b/src/dynamics/island_manager.rs
@@ -6,6 +6,8 @@ use crate::dynamics::{
use crate::geometry::{ColliderParent, InteractionGraph, NarrowPhase};
use crate::math::Real;
+/// Structure responsible for maintaining the set of active rigid-bodies, and
+/// putting non-moving rigid-bodies to sleep to save computation times.
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub struct IslandManager {
pub(crate) active_dynamic_set: Vec<RigidBodyHandle>,
@@ -19,6 +21,7 @@ pub struct IslandManager {
}
impl IslandManager {
+ /// Creates a new empty island manager.
pub fn new() -> Self {
Self {
active_dynamic_set: vec![],
@@ -34,6 +37,7 @@ impl IslandManager {
self.active_islands.len() - 1
}
+ /// Update this data-structure after one or multiple rigid-bodies have been removed for `bodies`.
pub fn cleanup_removed_rigid_bodies(
&mut self,
bodies: &mut impl ComponentSetMut<RigidBodyIds>,
@@ -59,7 +63,7 @@ impl IslandManager {
}
}
- pub fn rigid_body_removed(
+ pub(crate) fn rigid_body_removed(
&mut self,
removed_handle: RigidBodyHandle,
removed_ids: &RigidBodyIds,
diff --git a/src/dynamics/joint/joint_set.rs b/src/dynamics/joint/joint_set.rs
index 8e4d9b8..c316008 100644
--- a/src/dynamics/joint/joint_set.rs
+++ b/src/dynamics/joint/joint_set.rs
@@ -94,7 +94,7 @@ impl JointSet {
///
/// 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: usize) -> Option<(&Joint, JointHandle)> {
+ pub fn get_unknown_gen(&self, i: u32) -> Option<(&Joint, JointHandle)> {
let (id, handle) = self.joint_ids.get_unknown_gen(i)?;
Some((
self.joint_graph.graph.edge_weight(*id)?,
@@ -111,7 +111,7 @@ impl JointSet {
///
/// Using this is discouraged in favor of `self.get_mut(handle)` which does not
/// suffer form the ABA problem.
- pub fn get_unknown_gen_mut(&mut self, i: usize) -> Option<(&mut Joint, JointHandle)> {
+ pub fn get_unknown_gen_mut(&mut self, i: u32) -> Option<(&mut Joint, JointHandle)> {
let (id, handle) = self.joint_ids.get_unknown_gen(i)?;
Some((
self.joint_graph.graph.edge_weight_mut(*id)?,
diff --git a/src/dynamics/rigid_body.rs b/src/dynamics/rigid_body.rs
index 1bd1ba5..824ec92 100644
--- a/src/dynamics/rigid_body.rs
+++ b/src/dynamics/rigid_body.rs
@@ -7,8 +7,8 @@ use crate::geometry::{
Collider, ColliderHandle, ColliderMassProperties, ColliderParent, ColliderPosition,
ColliderShape,
};
-use crate::math::{AngVector, Isometry, Point, Real, Rotation, Translation, Vector};
-use crate::utils::{self, WAngularInertia, WCross};
+use crate::math::{AngVector, Isometry, Point, Real, Rotation, Vector};
+use crate::utils::{self, WCross};
use na::ComplexField;
use num::Zero;
@@ -18,21 +18,21 @@ use num::Zero;
/// To create a new rigid-body, use the `RigidBodyBuilder` structure.
#[derive(Debug, Clone)]
pub struct RigidBody {
- pub rb_pos: RigidBodyPosition, // TODO ECS: public only for initial tests with bevy_rapier.
- pub rb_mprops: RigidBodyMassProps, // TODO ECS: public only for initial tests with bevy_rapier.
- pub rb_vels: RigidBodyVelocity, // TODO ECS: public only for initial tests with bevy_rapier.
- pub rb_damping: RigidBodyDamping, // TODO ECS: public only for initial tests with bevy_rapier.
- pub rb_forces: RigidBodyForces, // TODO ECS: public only for initial tests with bevy_rapier.
- pub rb_ccd: RigidBodyCcd, // TODO ECS: public only for initial tests with bevy_rapier.
- pub rb_ids: RigidBodyIds, // TODO ECS: public only for initial tests with bevy_rapier.
- pub rb_colliders: RigidBodyColliders, // TODO ECS: public only for initial tests with bevy_rapier.
+ pub(crate) rb_pos: RigidBodyPosition,
+ pub(crate) rb_mprops: RigidBodyMassProps,
+ pub(crate) rb_vels: RigidBodyVelocity,
+ pub(crate) rb_damping: RigidBodyDamping,
+ pub(crate) rb_forces: RigidBodyForces,
+ pub(crate) rb_ccd: RigidBodyCcd,
+ pub(crate) rb_ids: RigidBodyIds,
+ pub(crate) rb_colliders: RigidBodyColliders,
/// Whether or not this rigid-body is sleeping.
- pub rb_activation: RigidBodyActivation, // TODO ECS: public only for initial tests with bevy_rapier.
- pub changes: RigidBodyChanges, // TODO ECS: public only for initial tests with bevy_rapier.
+ pub(crate) rb_activation: RigidBodyActivation,
+ pub(crate) changes: RigidBodyChanges,
/// The status of the body, governing how it is affected by external forces.
- pub rb_type: RigidBodyType, // TODO ECS: public only for initial tests with bevy_rapier
+ pub(crate) rb_type: RigidBodyType,
/// The dominance group this rigid-body is part of.
- pub rb_dominance: RigidBodyDominance,
+ pub(crate) rb_dominance: RigidBodyDominance,
/// User-defined data associated to this rigid-body.
pub user_data: u128,
}
@@ -61,61 +61,48 @@ impl RigidBody {
self.rb_ids = Default::default();
}
- pub fn user_data(&self) -> u128 {
- self.user_data
- }
-
- pub fn set_user_data(&mut self, data: u128) {
- self.user_data = data;
- }
-
- #[inline]
- pub fn rb_activation(&self) -> &RigidBodyActivation {
+ /// The activation status of this rigid-body.
+ pub fn activation(&self) -> &RigidBodyActivation {
&self.rb_activation
}
- #[inline]
+ /// Mutable reference to the activation status of this rigid-body.
pub fn activation_mut(&mut self) -> &mut RigidBodyActivation {
+ self.changes |= RigidBodyChanges::SLEEP;
&mut self.rb_activation
}
- #[inline]
- pub(crate) fn changes(&self) -> RigidBodyChanges {
- self.changes
- }
-
- #[inline]
- pub(crate) fn changes_mut_internal(&mut self) -> &mut RigidBodyChanges {
- &mut self.changes
- }
-
+ /// The linear damping coefficient of this rigid-body.
#[inline]
pub fn linear_damping(&self) -> Real {
self.rb_damping.linear_damping
}
+ /// Sets the linear damping coefficient of this rigid-body.
#[inline]
pub fn set_linear_damping(&mut self, damping: Real) {
self.rb_damping.linear_damping = damping;
}
+ /// The angular damping coefficient of this rigid-body.
#[inline]
pub fn angular_damping(&self) -> Real {
self.rb_damping.angular_damping
}
+ /// Sets the angular damping coefficient of this rigid-body.
#[inline]
pub fn set_angular_damping(&mut self, damping: Real) {
self.rb_damping.angular_damping = damping
}
- /// The status of this rigid-body.
- pub fn rb_type(&self) -> RigidBodyType {
+ /// The type of this rigid-body.
+ pub fn body_type(&self) -> RigidBodyType {
self.rb_type
}
- /// Sets the status of this rigid-body.
- pub fn set_rb_type(&mut self, status: RigidBodyType) {
+ /// Sets the type of this rigid-body.
+ pub fn set_body_type(&mut self, status: RigidBodyType) {
if status != self.rb_type {
self.changes.insert(RigidBodyChanges::TYPE);
self.rb_type = status;
@@ -336,22 +323,6 @@ impl RigidBody {
!self.rb_vels.linvel.is_zero() || !self.rb_vels.angvel.is_zero()
}
- /// Computes the predict position of this rigid-body after `dt` seconds, taking
- /// into account its velocities and external forces applied to it.
- pub fn predict_position_using_velocity_and_forces(&self, dt: Real) -> Isometry<Real> {
- let dlinvel = self.rb_forces.force * (self.rb_mprops.effective_inv_mass * dt);
- let dangvel = self
- .rb_mprops
- .effective_world_inv_inertia_sqrt
- .transform_vector(self.rb_forces.torque * dt);
- let linvel = self.rb_vels.linvel + dlinvel;
- let angvel = self.rb_vels.angvel + dangvel;
-
- let com = self.rb_pos.position * self.rb_mprops.mass_properties.local_com;
- let shift = Translation::from(com.coords);
- shift * Isometry::new(linvel * dt, angvel * dt) * shift.inverse() * self.rb_pos.position
- }
-
/// The linear velocity of this rigid-body.
pub fn linvel(&self) -> &Vector<Real> {
&self.rb_vels.linvel
@@ -567,30 +538,13 @@ impl RigidBody {
impl RigidBody {
/// The velocity of the given world-space point on this rigid-body.
pub fn velocity_at_point(&self, point: &Point<Real>) -> Vector<Real> {
- let dpt = point - self.rb_mprops.world_com;
- self.rb_vels.linvel + self.rb_vels.angvel.gcross(dpt)
+ self.rb_vels
+ .velocity_at_point(point, &self.rb_mprops.world_com)
}
/// The kinetic energy of this body.
pub fn kinetic_energy(&self) -> Real {
- let mut energy = (self.mass() * self.rb_vels.linvel.norm_squared()) / 2.0;
-
- #[cfg(feature = "dim2")]
- if !self.rb_mprops.effective_world_inv_inertia_sqrt.is_zero() {
- let inertia_sqrt = 1.0 / self.rb_mprops.effective_world_inv_inertia_sqrt;
- energy += (inertia_sqrt * self.rb_vels.angvel).powi(2) / 2.0;
- }
-
- #[cfg(feature = "dim3")]
- if !self.rb_mprops.effective_world_inv_inertia_sqrt.is_zero() {
- let inertia_sqrt = self
- .rb_mprops
- .effective_world_inv_inertia_sqrt
- .inverse_unchecked();
- energy += (inertia_sqrt * self.rb_vels.angvel).norm_squared() / 2.0;
- }
-
- energy
+ self.rb_vels.kinetic_energy(&self.rb_mprops)
}
/// The potential energy of this body in a gravity field.
@@ -894,39 +848,6 @@ impl RigidBodyBuilder {
self
}
- pub fn components(
- &self,
- ) -> (
- RigidBodyPosition,
- RigidBodyMassProps,
- RigidBodyVelocity,
- RigidBodyDamping,
- RigidBodyForces,
- RigidBodyCcd,
- RigidBodyIds,
- RigidBodyColliders,
- RigidBodyActivation,
- RigidBodyChanges,
- RigidBodyType,
- RigidBodyDominance,
- ) {
- let rb = self.build();
- (
- rb.rb_pos,
- rb.rb_mprops,
- rb.rb_vels,
- rb.rb_damping,
- rb.rb_forces,
- rb.rb_ccd,
- rb.rb_ids,
- rb.rb_colliders,
- rb.rb_activation,
- rb.changes,
- rb.rb_type,
- rb.rb_dominance,
- )
- }
-
/// Build a new rigid-body with the parameters configured with this builder.
pub fn build(&self) -> RigidBody {
let mut rb = RigidBody::new();
diff --git a/src/dynamics/rigid_body_components.rs b/src/dynamics/rigid_body_components.rs
index c87df1f..2a652f7 100644
--- a/src/dynamics/rigid_body_components.rs
+++ b/src/dynamics/rigid_body_components.rs
@@ -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;
diff --git a/src/dynamics/rigid_body_set.rs b/src/dynamics/rigid_body_set.rs
index b0cf39a..70a5451 100644
--- a/src/dynamics/rigid_body_set.rs
+++ b/src/dynamics/rigid_body_set.rs
@@ -125,7 +125,7 @@ impl RigidBodySet {
// Make sure the internal links are reset, they may not be
// if this rigid-body was obtained by cloning another one.
rb.reset_internal_references();
- rb.changes_mut_internal().set(RigidBodyChanges::all(), true);
+ rb.changes.set(RigidBodyChanges::all(), true);
let handle = RigidBodyHandle(self.bodies.insert(rb));
self.modified_bodies.push(handle);
@@ -170,7 +170,7 @@ impl RigidBodySet {
///
/// 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: usize) -> Option<(&RigidBody, RigidBodyHandle)> {
+ pub fn get_unknown_gen(&self, i: u32) -> Option<(&RigidBody, RigidBodyHandle)> {
self.bodies
.get_unknown_gen(i)
.map(|(b, h)| (b, RigidBodyHandle(h)))
@@ -186,7 +186,7 @@ impl RigidBodySet {
/// Using this is discouraged in favor of `self.get_mut(handle)` which does not
/// suffer form the ABA problem.
#[cfg(not(feature = "dev-remove-slow-accessors"))]
- pub fn get_unknown_gen_mut(&mut self, i: usize) -> Option<(&mut RigidBody, RigidBodyHandle)> {
+ pub fn get_unknown_gen_mut(&mut self, i: u32) -> Option<(&mut RigidBody, RigidBodyHandle)> {
let (rb, handle) = self.bodies.get_unknown_gen_mut(i)?;
let handle = RigidBodyHandle(handle);
Self::mark_as_modified(handle, rb, &mut self.modified_bodies);
@@ -203,8 +203,8 @@ impl RigidBodySet {
rb: &mut RigidBody,
modified_bodies: &mut Vec<RigidBodyHandle>,
) {
- if !rb.changes().contains(RigidBodyChanges::MODIFIED) {
- *rb.changes_mut_internal() = RigidBodyChanges::MODIFIED;
+ if !rb.changes.contains(RigidBodyChanges::MODIFIED) {
+ rb.changes = RigidBodyChanges::MODIFIED;
modified_bodies.push(handle);
}
}