diff options
Diffstat (limited to 'src/dynamics')
| -rw-r--r-- | src/dynamics/island_manager.rs | 6 | ||||
| -rw-r--r-- | src/dynamics/joint/joint_set.rs | 4 | ||||
| -rw-r--r-- | src/dynamics/rigid_body.rs | 137 | ||||
| -rw-r--r-- | src/dynamics/rigid_body_components.rs | 172 | ||||
| -rw-r--r-- | src/dynamics/rigid_body_set.rs | 10 |
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); } } |
