Merge pull request #360 from dimforge/easier-mass-props
Improve the API for initializing/setting mass-properties
This commit is contained in:
25
CHANGELOG.md
25
CHANGELOG.md
@@ -1,3 +1,28 @@
|
|||||||
|
## Unreleased
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
### Modified
|
||||||
|
- The `RigidBodyBuilder::additional_mass` method will now result in the additional angular inertia
|
||||||
|
being automatically computed based on the shapes of the colliders attached to the rigid-body.
|
||||||
|
- Remove the deprecated methods `RigidBodyBuilder::mass`, `::principal_angular_inertia`, `::principal_inertia`.
|
||||||
|
- Remove the methods `RigidBodyBuilder::additional_principal_angular_inertia`. Use
|
||||||
|
`RigidBodyBuilder::additional_mass_properties` instead.
|
||||||
|
- The `Collider::density` method now always returns a `Real` (instead of an `Option<Real>`).
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Add `RigidBody::recompute_mass_properties_from_colliders` to force the immediate computation
|
||||||
|
of a rigid-body’s mass properties (instead of waiting for them to be recomputed during the next
|
||||||
|
timestep). This is useful to be able to read immediately the result of a change of a rigid-body
|
||||||
|
additional mass-properties or a change of one of its collider’s mass-properties.
|
||||||
|
- Add `RigidBody::set_additional_mass` to set the additional mass for the collider. The additional
|
||||||
|
angular inertia is automatically computed based on the attached colliders shapes.
|
||||||
|
- Add `Collider::set_density`, `::set_mass`, `set_mass_properties`, to alter a collider’s mass
|
||||||
|
properties. Note that `::set_mass` will result in the collider’s angular inertia being automatically
|
||||||
|
computed based on this mass and on its shape.
|
||||||
|
- Add `ColliderBuilder::mass` to set the mass of the collider instead of its density. Its angular
|
||||||
|
inertia tensor will be automatically computed based on this mass and its shape.
|
||||||
|
- Add `Collider::mass` and `Collider::volume` to retrieve the mass or volume of a collider.
|
||||||
|
|
||||||
## v0.13.0 (31 May 2022)
|
## v0.13.0 (31 May 2022)
|
||||||
### Fixed
|
### Fixed
|
||||||
- Fix incorrect sensor events being generated after collider removal.
|
- Fix incorrect sensor events being generated after collider removal.
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
use crate::dynamics::{
|
use crate::dynamics::{
|
||||||
LockedAxes, MassProperties, RigidBodyActivation, RigidBodyCcd, RigidBodyChanges,
|
LockedAxes, MassProperties, RigidBodyActivation, RigidBodyAdditionalMassProps, RigidBodyCcd,
|
||||||
RigidBodyColliders, RigidBodyDamping, RigidBodyDominance, RigidBodyForces, RigidBodyIds,
|
RigidBodyChanges, RigidBodyColliders, RigidBodyDamping, RigidBodyDominance, RigidBodyForces,
|
||||||
RigidBodyMassProps, RigidBodyPosition, RigidBodyType, RigidBodyVelocity,
|
RigidBodyIds, RigidBodyMassProps, RigidBodyPosition, RigidBodyType, RigidBodyVelocity,
|
||||||
};
|
};
|
||||||
use crate::geometry::{
|
use crate::geometry::{
|
||||||
Collider, ColliderHandle, ColliderMassProps, ColliderParent, ColliderPosition, ColliderShape,
|
ColliderHandle, ColliderMassProps, ColliderParent, ColliderPosition, ColliderSet, ColliderShape,
|
||||||
};
|
};
|
||||||
use crate::math::{AngVector, Isometry, Point, Real, Rotation, Vector};
|
use crate::math::{AngVector, Isometry, Point, Real, Rotation, Vector};
|
||||||
use crate::utils::{self, WCross};
|
use crate::utils::WCross;
|
||||||
use na::ComplexField;
|
|
||||||
use num::Zero;
|
use num::Zero;
|
||||||
|
|
||||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||||
@@ -123,7 +122,7 @@ impl RigidBody {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The mass properties of this rigid-body.
|
/// The mass-properties of this rigid-body.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn mass_properties(&self) -> &MassProperties {
|
pub fn mass_properties(&self) -> &MassProperties {
|
||||||
&self.mprops.local_mprops
|
&self.mprops.local_mprops
|
||||||
@@ -310,26 +309,82 @@ impl RigidBody {
|
|||||||
self.ccd.ccd_active
|
self.ccd.ccd_active
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the rigid-body's additional mass properties.
|
/// Recompute the mass-properties of this rigid-bodies based on its currently attached colliders.
|
||||||
|
pub fn recompute_mass_properties_from_colliders(&mut self, colliders: &ColliderSet) {
|
||||||
|
self.mprops.recompute_mass_properties_from_colliders(
|
||||||
|
colliders,
|
||||||
|
&self.colliders,
|
||||||
|
&self.pos.position,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the rigid-body's additional mass.
|
||||||
|
///
|
||||||
|
/// The total angular inertia of the rigid-body will be scaled automatically based on this
|
||||||
|
/// additional mass. If this scaling effect isn’t desired, use [`Self::additional_mass_properties`]
|
||||||
|
/// instead of this method.
|
||||||
|
///
|
||||||
|
/// This is only the "additional" mass because the total mass of the rigid-body is
|
||||||
|
/// equal to the sum of this additional mass and the mass computed from the colliders
|
||||||
|
/// (with non-zero densities) attached to this rigid-body.
|
||||||
|
///
|
||||||
|
/// That total mass (which includes the attached colliders’ contributions)
|
||||||
|
/// will be updated at the name physics step, or can be updated manually with
|
||||||
|
/// [`Self::recompute_mass_properties_from_colliders`].
|
||||||
|
///
|
||||||
|
/// This will override any previous mass-properties set by [`Self::set_additional_mass`],
|
||||||
|
/// [`Self::set_additional_mass_properties`], [`RigidBodyBuilder::additional_mass`], or
|
||||||
|
/// [`RigidBodyBuilder::additional_mass_properties`] for this rigid-body.
|
||||||
|
///
|
||||||
|
/// If `wake_up` is `true` then the rigid-body will be woken up if it was
|
||||||
|
/// put to sleep because it did not move for a while.
|
||||||
|
#[inline]
|
||||||
|
pub fn set_additional_mass(&mut self, additional_mass: Real, wake_up: bool) {
|
||||||
|
self.do_set_additional_mass_properties(
|
||||||
|
RigidBodyAdditionalMassProps::Mass(additional_mass),
|
||||||
|
wake_up,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the rigid-body's additional mass-properties.
|
||||||
|
///
|
||||||
|
/// This is only the "additional" mass-properties because the total mass-properties of the
|
||||||
|
/// rigid-body is equal to the sum of this additional mass-properties and the mass computed from
|
||||||
|
/// the colliders (with non-zero densities) attached to this rigid-body.
|
||||||
|
///
|
||||||
|
/// That total mass-properties (which include the attached colliders’ contributions)
|
||||||
|
/// will be updated at the name physics step, or can be updated manually with
|
||||||
|
/// [`Self::recompute_mass_properties_from_colliders`].
|
||||||
|
///
|
||||||
|
/// This will override any previous mass-properties set by [`Self::set_additional_mass`],
|
||||||
|
/// [`Self::set_additional_mass_properties`], [`RigidBodyBuilder::additional_mass`], or
|
||||||
|
/// [`RigidBodyBuilder::additional_mass_properties`] for this rigid-body.
|
||||||
///
|
///
|
||||||
/// If `wake_up` is `true` then the rigid-body will be woken up if it was
|
/// If `wake_up` is `true` then the rigid-body will be woken up if it was
|
||||||
/// put to sleep because it did not move for a while.
|
/// put to sleep because it did not move for a while.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_additional_mass_properties(&mut self, props: MassProperties, wake_up: bool) {
|
pub fn set_additional_mass_properties(&mut self, props: MassProperties, wake_up: bool) {
|
||||||
if let Some(add_mprops) = &mut self.mprops.additional_local_mprops {
|
self.do_set_additional_mass_properties(
|
||||||
self.mprops.local_mprops += props;
|
RigidBodyAdditionalMassProps::MassProps(props),
|
||||||
self.mprops.local_mprops -= **add_mprops;
|
wake_up,
|
||||||
**add_mprops = props;
|
)
|
||||||
} else {
|
}
|
||||||
self.mprops.additional_local_mprops = Some(Box::new(props));
|
|
||||||
self.mprops.local_mprops += props;
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.is_dynamic() && wake_up {
|
fn do_set_additional_mass_properties(
|
||||||
self.wake_up(true);
|
&mut self,
|
||||||
}
|
props: RigidBodyAdditionalMassProps,
|
||||||
|
wake_up: bool,
|
||||||
|
) {
|
||||||
|
let new_mprops = Some(Box::new(props));
|
||||||
|
|
||||||
self.update_world_mass_properties();
|
if self.mprops.additional_local_mprops != new_mprops {
|
||||||
|
self.changes.insert(RigidBodyChanges::LOCAL_MASS_PROPERTIES);
|
||||||
|
self.mprops.additional_local_mprops = new_mprops;
|
||||||
|
|
||||||
|
if self.is_dynamic() && wake_up {
|
||||||
|
self.wake_up(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The handles of colliders attached to this rigid body.
|
/// The handles of colliders attached to this rigid body.
|
||||||
@@ -428,16 +483,10 @@ impl RigidBody {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Removes a collider from this rigid-body.
|
/// Removes a collider from this rigid-body.
|
||||||
pub(crate) fn remove_collider_internal(&mut self, handle: ColliderHandle, coll: &Collider) {
|
pub(crate) fn remove_collider_internal(&mut self, handle: ColliderHandle) {
|
||||||
if let Some(i) = self.colliders.0.iter().position(|e| *e == handle) {
|
if let Some(i) = self.colliders.0.iter().position(|e| *e == handle) {
|
||||||
self.changes.set(RigidBodyChanges::COLLIDERS, true);
|
self.changes.set(RigidBodyChanges::COLLIDERS, true);
|
||||||
self.colliders.0.swap_remove(i);
|
self.colliders.0.swap_remove(i);
|
||||||
|
|
||||||
let mass_properties = coll
|
|
||||||
.mass_properties()
|
|
||||||
.transform_by(coll.position_wrt_parent().unwrap());
|
|
||||||
self.mprops.local_mprops -= mass_properties;
|
|
||||||
self.update_world_mass_properties();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -859,8 +908,8 @@ pub struct RigidBodyBuilder {
|
|||||||
pub angular_damping: Real,
|
pub angular_damping: Real,
|
||||||
body_type: RigidBodyType,
|
body_type: RigidBodyType,
|
||||||
mprops_flags: LockedAxes,
|
mprops_flags: LockedAxes,
|
||||||
/// The additional mass properties of the rigid-body being built. See [`RigidBodyBuilder::additional_mass_properties`] for more information.
|
/// The additional mass-properties of the rigid-body being built. See [`RigidBodyBuilder::additional_mass_properties`] for more information.
|
||||||
pub additional_mass_properties: MassProperties,
|
additional_mass_properties: RigidBodyAdditionalMassProps,
|
||||||
/// Whether or not the rigid-body to be created can sleep if it reaches a dynamic equilibrium.
|
/// Whether or not the rigid-body to be created can sleep if it reaches a dynamic equilibrium.
|
||||||
pub can_sleep: bool,
|
pub can_sleep: bool,
|
||||||
/// Whether or not the rigid-body is to be created asleep.
|
/// Whether or not the rigid-body is to be created asleep.
|
||||||
@@ -887,7 +936,7 @@ impl RigidBodyBuilder {
|
|||||||
angular_damping: 0.0,
|
angular_damping: 0.0,
|
||||||
body_type,
|
body_type,
|
||||||
mprops_flags: LockedAxes::empty(),
|
mprops_flags: LockedAxes::empty(),
|
||||||
additional_mass_properties: MassProperties::zero(),
|
additional_mass_properties: RigidBodyAdditionalMassProps::default(),
|
||||||
can_sleep: true,
|
can_sleep: true,
|
||||||
sleeping: false,
|
sleeping: false,
|
||||||
ccd_enabled: false,
|
ccd_enabled: false,
|
||||||
@@ -968,18 +1017,41 @@ impl RigidBodyBuilder {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the additional mass properties of the rigid-body being built.
|
/// Sets the additional mass-properties of the rigid-body being built.
|
||||||
///
|
///
|
||||||
/// Note that "additional" means that the final mass properties of the rigid-bodies depends
|
/// This will be overridden by a call to [`Self::additional_mass`] so it only makes sense to call
|
||||||
|
/// either [`Self::additional_mass`] or [`Self::additional_mass_properties`].
|
||||||
|
///
|
||||||
|
/// Note that "additional" means that the final mass-properties of the rigid-bodies depends
|
||||||
/// on the initial mass-properties of the rigid-body (set by this method)
|
/// on the initial mass-properties of the rigid-body (set by this method)
|
||||||
/// to which is added the contributions of all the colliders with non-zero density
|
/// to which is added the contributions of all the colliders with non-zero density
|
||||||
/// attached to this rigid-body.
|
/// attached to this rigid-body.
|
||||||
///
|
///
|
||||||
/// Therefore, if you want your provided mass properties to be the final
|
/// Therefore, if you want your provided mass-properties to be the final
|
||||||
/// mass properties of your rigid-body, don't attach colliders to it, or
|
/// mass-properties of your rigid-body, don't attach colliders to it, or
|
||||||
/// only attach colliders with densities equal to zero.
|
/// only attach colliders with densities equal to zero.
|
||||||
pub fn additional_mass_properties(mut self, props: MassProperties) -> Self {
|
pub fn additional_mass_properties(mut self, mprops: MassProperties) -> Self {
|
||||||
self.additional_mass_properties = props;
|
self.additional_mass_properties = RigidBodyAdditionalMassProps::MassProps(mprops);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the additional mass of the rigid-body being built.
|
||||||
|
///
|
||||||
|
/// This will be overridden by a call to [`Self::additional_mass_properties`] so it only makes
|
||||||
|
/// sense to call either [`Self::additional_mass`] or [`Self::additional_mass_properties`].
|
||||||
|
///
|
||||||
|
/// This is only the "additional" mass because the total mass of the rigid-body is
|
||||||
|
/// equal to the sum of this additional mass and the mass computed from the colliders
|
||||||
|
/// (with non-zero densities) attached to this rigid-body.
|
||||||
|
///
|
||||||
|
/// The total angular inertia of the rigid-body will be scaled automatically based on this
|
||||||
|
/// additional mass. If this scaling effect isn’t desired, use [`Self::additional_mass_properties`]
|
||||||
|
/// instead of this method.
|
||||||
|
///
|
||||||
|
/// # Parameters
|
||||||
|
/// * `mass`- The mass that will be added to the created rigid-body.
|
||||||
|
pub fn additional_mass(mut self, mass: Real) -> Self {
|
||||||
|
self.additional_mass_properties = RigidBodyAdditionalMassProps::Mass(mass);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1037,78 +1109,6 @@ impl RigidBodyBuilder {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the additional mass of the rigid-body being built.
|
|
||||||
///
|
|
||||||
/// This is only the "additional" mass because the total mass of the rigid-body is
|
|
||||||
/// equal to the sum of this additional mass and the mass computed from the colliders
|
|
||||||
/// (with non-zero densities) attached to this rigid-body.
|
|
||||||
pub fn additional_mass(mut self, mass: Real) -> Self {
|
|
||||||
self.additional_mass_properties.set_mass(mass, false);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets the additional mass of the rigid-body being built.
|
|
||||||
///
|
|
||||||
/// This is only the "additional" mass because the total mass of the rigid-body is
|
|
||||||
/// equal to the sum of this additional mass and the mass computed from the colliders
|
|
||||||
/// (with non-zero densities) attached to this rigid-body.
|
|
||||||
#[deprecated(note = "renamed to `additional_mass`.")]
|
|
||||||
pub fn mass(self, mass: Real) -> Self {
|
|
||||||
self.additional_mass(mass)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets the additional angular inertia of this rigid-body.
|
|
||||||
///
|
|
||||||
/// This is only the "additional" angular inertia because the total angular inertia of
|
|
||||||
/// the rigid-body is equal to the sum of this additional value and the angular inertia
|
|
||||||
/// computed from the colliders (with non-zero densities) attached to this rigid-body.
|
|
||||||
#[cfg(feature = "dim2")]
|
|
||||||
pub fn additional_principal_angular_inertia(mut self, inertia: Real) -> Self {
|
|
||||||
self.additional_mass_properties.inv_principal_inertia_sqrt =
|
|
||||||
utils::inv(ComplexField::sqrt(inertia.max(0.0)));
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets the angular inertia of this rigid-body.
|
|
||||||
#[cfg(feature = "dim2")]
|
|
||||||
#[deprecated(note = "renamed to `additional_principal_angular_inertia`.")]
|
|
||||||
pub fn principal_angular_inertia(self, inertia: Real) -> Self {
|
|
||||||
self.additional_principal_angular_inertia(inertia)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Use `self.principal_angular_inertia` instead.
|
|
||||||
#[cfg(feature = "dim2")]
|
|
||||||
#[deprecated(note = "renamed to `additional_principal_angular_inertia`.")]
|
|
||||||
pub fn principal_inertia(self, inertia: Real) -> Self {
|
|
||||||
self.additional_principal_angular_inertia(inertia)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets the additional principal angular inertia of this rigid-body.
|
|
||||||
///
|
|
||||||
/// This is only the "additional" angular inertia because the total angular inertia of
|
|
||||||
/// the rigid-body is equal to the sum of this additional value and the angular inertia
|
|
||||||
/// computed from the colliders (with non-zero densities) attached to this rigid-body.
|
|
||||||
#[cfg(feature = "dim3")]
|
|
||||||
pub fn additional_principal_angular_inertia(mut self, inertia: AngVector<Real>) -> Self {
|
|
||||||
self.additional_mass_properties.inv_principal_inertia_sqrt =
|
|
||||||
inertia.map(|e| utils::inv(ComplexField::sqrt(e.max(0.0))));
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets the principal angular inertia of this rigid-body.
|
|
||||||
#[cfg(feature = "dim3")]
|
|
||||||
#[deprecated(note = "renamed to `additional_principal_angular_inertia`.")]
|
|
||||||
pub fn principal_angular_inertia(self, inertia: AngVector<Real>) -> Self {
|
|
||||||
self.additional_principal_angular_inertia(inertia)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Use `self.principal_angular_inertia` instead.
|
|
||||||
#[cfg(feature = "dim3")]
|
|
||||||
#[deprecated(note = "renamed to `additional_principal_angular_inertia`.")]
|
|
||||||
pub fn principal_inertia(self, inertia: AngVector<Real>) -> Self {
|
|
||||||
self.additional_principal_angular_inertia(inertia)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets the damping factor for the linear part of the rigid-body motion.
|
/// Sets the damping factor for the linear part of the rigid-body motion.
|
||||||
///
|
///
|
||||||
/// The higher the linear damping factor is, the more quickly the rigid-body
|
/// The higher the linear damping factor is, the more quickly the rigid-body
|
||||||
@@ -1169,9 +1169,11 @@ impl RigidBodyBuilder {
|
|||||||
rb.body_type = self.body_type;
|
rb.body_type = self.body_type;
|
||||||
rb.user_data = self.user_data;
|
rb.user_data = self.user_data;
|
||||||
|
|
||||||
if self.additional_mass_properties != MassProperties::default() {
|
if self.additional_mass_properties
|
||||||
|
!= RigidBodyAdditionalMassProps::MassProps(MassProperties::zero())
|
||||||
|
&& self.additional_mass_properties != RigidBodyAdditionalMassProps::Mass(0.0)
|
||||||
|
{
|
||||||
rb.mprops.additional_local_mprops = Some(Box::new(self.additional_mass_properties));
|
rb.mprops.additional_local_mprops = Some(Box::new(self.additional_mass_properties));
|
||||||
rb.mprops.local_mprops = self.additional_mass_properties;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rb.mprops.flags = self.mprops_flags;
|
rb.mprops.flags = self.mprops_flags;
|
||||||
|
|||||||
@@ -110,6 +110,8 @@ bitflags::bitflags! {
|
|||||||
const TYPE = 1 << 4;
|
const TYPE = 1 << 4;
|
||||||
/// Flag indicating that the `RigidBodyDominance` component of this rigid-body has been modified.
|
/// Flag indicating that the `RigidBodyDominance` component of this rigid-body has been modified.
|
||||||
const DOMINANCE = 1 << 5;
|
const DOMINANCE = 1 << 5;
|
||||||
|
/// Flag indicating that the local mass-properties of this rigid-body must be recomputed.
|
||||||
|
const LOCAL_MASS_PROPERTIES = 1 << 6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,7 +224,23 @@ bitflags::bitflags! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: split this into "LocalMassProps" and `WorldMassProps"?
|
/// Mass and angular inertia added to a rigid-body on top of its attached colliders’ contributions.
|
||||||
|
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
|
pub enum RigidBodyAdditionalMassProps {
|
||||||
|
/// Mass properties to be added as-is.
|
||||||
|
MassProps(MassProperties),
|
||||||
|
/// Mass to be added to the rigid-body. This will also automatically scale
|
||||||
|
/// the attached colliders total angular inertia to account for the added mass.
|
||||||
|
Mass(Real),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for RigidBodyAdditionalMassProps {
|
||||||
|
fn default() -> Self {
|
||||||
|
RigidBodyAdditionalMassProps::MassProps(MassProperties::default())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
/// The mass properties of this rigid-bodies.
|
/// The mass properties of this rigid-bodies.
|
||||||
@@ -232,7 +250,7 @@ pub struct RigidBodyMassProps {
|
|||||||
/// The local mass properties of the rigid-body.
|
/// The local mass properties of the rigid-body.
|
||||||
pub local_mprops: MassProperties,
|
pub local_mprops: MassProperties,
|
||||||
/// Mass-properties of this rigid-bodies, added to the contributions of its attached colliders.
|
/// Mass-properties of this rigid-bodies, added to the contributions of its attached colliders.
|
||||||
pub additional_local_mprops: Option<Box<MassProperties>>,
|
pub additional_local_mprops: Option<Box<RigidBodyAdditionalMassProps>>,
|
||||||
/// The world-space center of mass of the rigid-body.
|
/// The world-space center of mass of the rigid-body.
|
||||||
pub world_com: Point<Real>,
|
pub world_com: Point<Real>,
|
||||||
/// The inverse mass taking into account translation locking.
|
/// The inverse mass taking into account translation locking.
|
||||||
@@ -294,18 +312,20 @@ impl RigidBodyMassProps {
|
|||||||
self.effective_world_inv_inertia_sqrt.squared().inverse()
|
self.effective_world_inv_inertia_sqrt.squared().inverse()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Recompute the mass-properties of this rigid-bodies based on its currentely attached colliders.
|
/// Recompute the mass-properties of this rigid-bodies based on its currently attached colliders.
|
||||||
pub fn recompute_mass_properties_from_colliders(
|
pub fn recompute_mass_properties_from_colliders(
|
||||||
&mut self,
|
&mut self,
|
||||||
colliders: &ColliderSet,
|
colliders: &ColliderSet,
|
||||||
attached_colliders: &RigidBodyColliders,
|
attached_colliders: &RigidBodyColliders,
|
||||||
position: &Isometry<Real>,
|
position: &Isometry<Real>,
|
||||||
) {
|
) {
|
||||||
self.local_mprops = self
|
let added_mprops = self
|
||||||
.additional_local_mprops
|
.additional_local_mprops
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|mprops| **mprops)
|
.map(|mprops| **mprops)
|
||||||
.unwrap_or_else(MassProperties::default);
|
.unwrap_or_else(|| RigidBodyAdditionalMassProps::MassProps(MassProperties::default()));
|
||||||
|
|
||||||
|
self.local_mprops = MassProperties::default();
|
||||||
|
|
||||||
for handle in &attached_colliders.0 {
|
for handle in &attached_colliders.0 {
|
||||||
if let Some(co) = colliders.get(*handle) {
|
if let Some(co) = colliders.get(*handle) {
|
||||||
@@ -319,6 +339,16 @@ impl RigidBodyMassProps {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
match added_mprops {
|
||||||
|
RigidBodyAdditionalMassProps::MassProps(mprops) => {
|
||||||
|
self.local_mprops += mprops;
|
||||||
|
}
|
||||||
|
RigidBodyAdditionalMassProps::Mass(mass) => {
|
||||||
|
let new_mass = self.local_mprops.mass() + mass;
|
||||||
|
self.local_mprops.set_mass(new_mass, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.update_world_mass_properties(position);
|
self.update_world_mass_properties(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -237,11 +237,75 @@ impl Collider {
|
|||||||
&self.material
|
&self.material
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The density of this collider, if set.
|
/// The volume (or surface in 2D) of this collider.
|
||||||
pub fn density(&self) -> Option<Real> {
|
pub fn volume(&self) -> Real {
|
||||||
|
self.shape.mass_properties(1.0).mass()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The density of this collider.
|
||||||
|
pub fn density(&self) -> Real {
|
||||||
match &self.mprops {
|
match &self.mprops {
|
||||||
ColliderMassProps::Density(density) => Some(*density),
|
ColliderMassProps::Density(density) => *density,
|
||||||
ColliderMassProps::MassProperties(_) => None,
|
ColliderMassProps::Mass(mass) => {
|
||||||
|
let inv_volume = self.shape.mass_properties(1.0).inv_mass;
|
||||||
|
mass * inv_volume
|
||||||
|
}
|
||||||
|
ColliderMassProps::MassProperties(mprops) => {
|
||||||
|
let inv_volume = self.shape.mass_properties(1.0).inv_mass;
|
||||||
|
mprops.mass() * inv_volume
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The mass of this collider.
|
||||||
|
pub fn mass(&self) -> Real {
|
||||||
|
match &self.mprops {
|
||||||
|
ColliderMassProps::Density(density) => self.shape.mass_properties(*density).mass(),
|
||||||
|
ColliderMassProps::Mass(mass) => *mass,
|
||||||
|
ColliderMassProps::MassProperties(mprops) => mprops.mass(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the uniform density of this collider.
|
||||||
|
///
|
||||||
|
/// This will override any previous mass-properties set by [`Self::set_density`],
|
||||||
|
/// [`Self::set_mass`], [`Self::set_mass_properties`], [`ColliderBuilder::density`],
|
||||||
|
/// [`ColliderBuilder::mass`], or [`ColliderBuilder::mass_properties`]
|
||||||
|
/// for this collider.
|
||||||
|
///
|
||||||
|
/// The mass and angular inertia of this collider will be computed automatically based on its
|
||||||
|
/// shape.
|
||||||
|
pub fn set_density(&mut self, density: Real) {
|
||||||
|
self.do_set_mass_properties(ColliderMassProps::Density(density));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the mass of this collider.
|
||||||
|
///
|
||||||
|
/// This will override any previous mass-properties set by [`Self::set_density`],
|
||||||
|
/// [`Self::set_mass`], [`Self::set_mass_properties`], [`ColliderBuilder::density`],
|
||||||
|
/// [`ColliderBuilder::mass`], or [`ColliderBuilder::mass_properties`]
|
||||||
|
/// for this collider.
|
||||||
|
///
|
||||||
|
/// The angular inertia of this collider will be computed automatically based on its shape
|
||||||
|
/// and this mass value.
|
||||||
|
pub fn set_mass(&mut self, mass: Real) {
|
||||||
|
self.do_set_mass_properties(ColliderMassProps::Mass(mass));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the mass properties of this collider.
|
||||||
|
///
|
||||||
|
/// This will override any previous mass-properties set by [`Self::set_density`],
|
||||||
|
/// [`Self::set_mass`], [`Self::set_mass_properties`], [`ColliderBuilder::density`],
|
||||||
|
/// [`ColliderBuilder::mass`], or [`ColliderBuilder::mass_properties`]
|
||||||
|
/// for this collider.
|
||||||
|
pub fn set_mass_properties(&mut self, mass_properties: MassProperties) {
|
||||||
|
self.do_set_mass_properties(ColliderMassProps::MassProperties(Box::new(mass_properties)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_set_mass_properties(&mut self, mprops: ColliderMassProps) {
|
||||||
|
if mprops != self.mprops {
|
||||||
|
self.changes |= ColliderChanges::LOCAL_MASS_PROPERTIES;
|
||||||
|
self.mprops = mprops;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -284,10 +348,7 @@ impl Collider {
|
|||||||
|
|
||||||
/// Compute the local-space mass properties of this collider.
|
/// Compute the local-space mass properties of this collider.
|
||||||
pub fn mass_properties(&self) -> MassProperties {
|
pub fn mass_properties(&self) -> MassProperties {
|
||||||
match &self.mprops {
|
self.mprops.mass_properties(&*self.shape)
|
||||||
ColliderMassProps::Density(density) => self.shape.mass_properties(*density),
|
|
||||||
ColliderMassProps::MassProperties(mass_properties) => **mass_properties,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The total force magnitude beyond which a contact force event can be emitted.
|
/// The total force magnitude beyond which a contact force event can be emitted.
|
||||||
@@ -303,11 +364,8 @@ impl Collider {
|
|||||||
pub struct ColliderBuilder {
|
pub struct ColliderBuilder {
|
||||||
/// The shape of the collider to be built.
|
/// The shape of the collider to be built.
|
||||||
pub shape: SharedShape,
|
pub shape: SharedShape,
|
||||||
/// The uniform density of the collider to be built.
|
/// Controls the way the collider’s mass-properties are computed.
|
||||||
pub density: Option<Real>,
|
pub mass_properties: ColliderMassProps,
|
||||||
/// Overrides automatic computation of `MassProperties`.
|
|
||||||
/// If None, it will be computed based on shape and density.
|
|
||||||
pub mass_properties: Option<MassProperties>,
|
|
||||||
/// The friction coefficient of the collider to be built.
|
/// The friction coefficient of the collider to be built.
|
||||||
pub friction: Real,
|
pub friction: Real,
|
||||||
/// The rule used to combine two friction coefficients.
|
/// The rule used to combine two friction coefficients.
|
||||||
@@ -341,8 +399,7 @@ impl ColliderBuilder {
|
|||||||
pub fn new(shape: SharedShape) -> Self {
|
pub fn new(shape: SharedShape) -> Self {
|
||||||
Self {
|
Self {
|
||||||
shape,
|
shape,
|
||||||
density: None,
|
mass_properties: ColliderMassProps::default(),
|
||||||
mass_properties: None,
|
|
||||||
friction: Self::default_friction(),
|
friction: Self::default_friction(),
|
||||||
restitution: 0.0,
|
restitution: 0.0,
|
||||||
position: Isometry::identity(),
|
position: Isometry::identity(),
|
||||||
@@ -627,9 +684,6 @@ impl ColliderBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Sets whether or not the collider built by this builder is a sensor.
|
/// Sets whether or not the collider built by this builder is a sensor.
|
||||||
///
|
|
||||||
/// Sensors will have a default density of zero,
|
|
||||||
/// but if you call [`Self::mass_properties`] you can assign a mass to a sensor.
|
|
||||||
pub fn sensor(mut self, is_sensor: bool) -> Self {
|
pub fn sensor(mut self, is_sensor: bool) -> Self {
|
||||||
self.is_sensor = is_sensor;
|
self.is_sensor = is_sensor;
|
||||||
self
|
self
|
||||||
@@ -679,19 +733,34 @@ impl ColliderBuilder {
|
|||||||
|
|
||||||
/// Sets the uniform density of the collider this builder will build.
|
/// Sets the uniform density of the collider this builder will build.
|
||||||
///
|
///
|
||||||
/// This will be overridden by a call to [`Self::mass_properties`] so it only makes sense to call
|
/// This will be overridden by a call to [`Self::mass`] or [`Self::mass_properties`] so it only
|
||||||
/// either [`Self::density`] or [`Self::mass_properties`].
|
/// makes sense to call either [`Self::density`] or [`Self::mass`] or [`Self::mass_properties`].
|
||||||
|
///
|
||||||
|
/// The mass and angular inertia of this collider will be computed automatically based on its
|
||||||
|
/// shape.
|
||||||
pub fn density(mut self, density: Real) -> Self {
|
pub fn density(mut self, density: Real) -> Self {
|
||||||
self.density = Some(density);
|
self.mass_properties = ColliderMassProps::Density(density);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the mass of the collider this builder will build.
|
||||||
|
///
|
||||||
|
/// This will be overridden by a call to [`Self::density`] or [`Self::mass_properties`] so it only
|
||||||
|
/// makes sense to call either [`Self::density`] or [`Self::mass`] or [`Self::mass_properties`].
|
||||||
|
///
|
||||||
|
/// The angular inertia of this collider will be computed automatically based on its shape
|
||||||
|
/// and this mass value.
|
||||||
|
pub fn mass(mut self, mass: Real) -> Self {
|
||||||
|
self.mass_properties = ColliderMassProps::Mass(mass);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the mass properties of the collider this builder will build.
|
/// Sets the mass properties of the collider this builder will build.
|
||||||
///
|
///
|
||||||
/// If this is set, [`Self::density`] will be ignored, so it only makes sense to call
|
/// This will be overridden by a call to [`Self::density`] or [`Self::mass`] so it only
|
||||||
/// either [`Self::density`] or [`Self::mass_properties`].
|
/// makes sense to call either [`Self::density`] or [`Self::mass`] or [`Self::mass_properties`].
|
||||||
pub fn mass_properties(mut self, mass_properties: MassProperties) -> Self {
|
pub fn mass_properties(mut self, mass_properties: MassProperties) -> Self {
|
||||||
self.mass_properties = Some(mass_properties);
|
self.mass_properties = ColliderMassProps::MassProperties(Box::new(mass_properties));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -745,16 +814,7 @@ impl ColliderBuilder {
|
|||||||
|
|
||||||
/// Builds a new collider attached to the given rigid-body.
|
/// Builds a new collider attached to the given rigid-body.
|
||||||
pub fn build(&self) -> Collider {
|
pub fn build(&self) -> Collider {
|
||||||
let mass_info = if let Some(mp) = self.mass_properties {
|
|
||||||
ColliderMassProps::MassProperties(Box::new(mp))
|
|
||||||
} else {
|
|
||||||
let default_density = Self::default_density();
|
|
||||||
let density = self.density.unwrap_or(default_density);
|
|
||||||
ColliderMassProps::Density(density)
|
|
||||||
};
|
|
||||||
|
|
||||||
let shape = self.shape.clone();
|
let shape = self.shape.clone();
|
||||||
let mprops = mass_info;
|
|
||||||
let material = ColliderMaterial {
|
let material = ColliderMaterial {
|
||||||
friction: self.friction,
|
friction: self.friction,
|
||||||
restitution: self.restitution,
|
restitution: self.restitution,
|
||||||
@@ -779,7 +839,7 @@ impl ColliderBuilder {
|
|||||||
|
|
||||||
Collider {
|
Collider {
|
||||||
shape,
|
shape,
|
||||||
mprops,
|
mprops: self.mass_properties.clone(),
|
||||||
material,
|
material,
|
||||||
parent: None,
|
parent: None,
|
||||||
changes,
|
changes,
|
||||||
|
|||||||
@@ -47,21 +47,23 @@ bitflags::bitflags! {
|
|||||||
pub struct ColliderChanges: u32 {
|
pub struct ColliderChanges: u32 {
|
||||||
/// Flag indicating that any component of the collider has been modified.
|
/// Flag indicating that any component of the collider has been modified.
|
||||||
const MODIFIED = 1 << 0;
|
const MODIFIED = 1 << 0;
|
||||||
|
/// Flag indicating that the density or mass-properties of this collider was changed.
|
||||||
|
const LOCAL_MASS_PROPERTIES = 1 << 1; // => RigidBody local mass-properties update.
|
||||||
/// Flag indicating that the `ColliderParent` component of the collider has been modified.
|
/// Flag indicating that the `ColliderParent` component of the collider has been modified.
|
||||||
const PARENT = 1 << 1; // => BF & NF updates.
|
const PARENT = 1 << 2; // => BF & NF updates.
|
||||||
/// Flag indicating that the `ColliderPosition` component of the collider has been modified.
|
/// Flag indicating that the `ColliderPosition` component of the collider has been modified.
|
||||||
const POSITION = 1 << 2; // => BF & NF updates.
|
const POSITION = 1 << 3; // => BF & NF updates.
|
||||||
/// Flag indicating that the collision groups of the collider have been modified.
|
/// Flag indicating that the collision groups of the collider have been modified.
|
||||||
const GROUPS = 1 << 3; // => NF update.
|
const GROUPS = 1 << 4; // => NF update.
|
||||||
/// Flag indicating that the `ColliderShape` component of the collider has been modified.
|
/// Flag indicating that the `ColliderShape` component of the collider has been modified.
|
||||||
const SHAPE = 1 << 4; // => BF & NF update. NF pair workspace invalidation.
|
const SHAPE = 1 << 5; // => BF & NF update. NF pair workspace invalidation.
|
||||||
/// Flag indicating that the `ColliderType` component of the collider has been modified.
|
/// Flag indicating that the `ColliderType` component of the collider has been modified.
|
||||||
const TYPE = 1 << 5; // => NF update. NF pair invalidation.
|
const TYPE = 1 << 6; // => NF update. NF pair invalidation.
|
||||||
/// Flag indicating that the dominance groups of the parent of this collider have been modified.
|
/// Flag indicating that the dominance groups of the parent of this collider have been modified.
|
||||||
///
|
///
|
||||||
/// This flags is automatically set by the `PhysicsPipeline` when the `RigidBodyChanges::DOMINANCE`
|
/// This flags is automatically set by the `PhysicsPipeline` when the `RigidBodyChanges::DOMINANCE`
|
||||||
/// or `RigidBodyChanges::TYPE` of the parent rigid-body of this collider is detected.
|
/// or `RigidBodyChanges::TYPE` of the parent rigid-body of this collider is detected.
|
||||||
const PARENT_EFFECTIVE_DOMINANCE = 1 << 6; // NF update.
|
const PARENT_EFFECTIVE_DOMINANCE = 1 << 7; // NF update.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +88,7 @@ impl ColliderChanges {
|
|||||||
// bottleneck at some point in the future (which is very unlikely)
|
// bottleneck at some point in the future (which is very unlikely)
|
||||||
// we could do a special-case for dominance-only change (so that
|
// we could do a special-case for dominance-only change (so that
|
||||||
// we only update the relative_dominance of the pre-existing contact.
|
// we only update the relative_dominance of the pre-existing contact.
|
||||||
self.bits() > 1
|
self.bits() > 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,6 +136,10 @@ pub enum ColliderMassProps {
|
|||||||
/// Its actual `MassProperties` are computed automatically with
|
/// Its actual `MassProperties` are computed automatically with
|
||||||
/// the help of [`SharedShape::mass_properties`].
|
/// the help of [`SharedShape::mass_properties`].
|
||||||
Density(Real),
|
Density(Real),
|
||||||
|
/// The collider is given a mass.
|
||||||
|
///
|
||||||
|
/// Its angular inertia will be computed automatically based on this mass.
|
||||||
|
Mass(Real),
|
||||||
/// The collider is given explicit mass-properties.
|
/// The collider is given explicit mass-properties.
|
||||||
MassProperties(Box<MassProperties>),
|
MassProperties(Box<MassProperties>),
|
||||||
}
|
}
|
||||||
@@ -159,8 +165,23 @@ impl ColliderMassProps {
|
|||||||
/// If `self` is the `MassProperties` variant, then this returns the stored mass-properties.
|
/// If `self` is the `MassProperties` variant, then this returns the stored mass-properties.
|
||||||
pub fn mass_properties(&self, shape: &dyn Shape) -> MassProperties {
|
pub fn mass_properties(&self, shape: &dyn Shape) -> MassProperties {
|
||||||
match self {
|
match self {
|
||||||
Self::Density(density) => shape.mass_properties(*density),
|
ColliderMassProps::Density(density) => {
|
||||||
Self::MassProperties(mprops) => **mprops,
|
if *density != 0.0 {
|
||||||
|
shape.mass_properties(*density)
|
||||||
|
} else {
|
||||||
|
MassProperties::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ColliderMassProps::Mass(mass) => {
|
||||||
|
if *mass != 0.0 {
|
||||||
|
let mut mprops = shape.mass_properties(1.0);
|
||||||
|
mprops.set_mass(*mass, true);
|
||||||
|
mprops
|
||||||
|
} else {
|
||||||
|
MassProperties::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ColliderMassProps::MassProperties(mass_properties) => **mass_properties,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ impl ColliderSet {
|
|||||||
|
|
||||||
if let Some(parent_handle) = curr_parent {
|
if let Some(parent_handle) = curr_parent {
|
||||||
if let Some(rb) = bodies.get_mut(parent_handle) {
|
if let Some(rb) = bodies.get_mut(parent_handle) {
|
||||||
rb.remove_collider_internal(handle, &*collider);
|
rb.remove_collider_internal(handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,7 +189,7 @@ impl ColliderSet {
|
|||||||
if let Some(parent_rb) =
|
if let Some(parent_rb) =
|
||||||
bodies.get_mut_internal_with_modification_tracking(parent.handle)
|
bodies.get_mut_internal_with_modification_tracking(parent.handle)
|
||||||
{
|
{
|
||||||
parent_rb.remove_collider_internal(handle, &collider);
|
parent_rb.remove_collider_internal(handle);
|
||||||
|
|
||||||
if wake_up {
|
if wake_up {
|
||||||
islands.wake_up(bodies, parent.handle, true);
|
islands.wake_up(bodies, parent.handle, true);
|
||||||
|
|||||||
@@ -407,6 +407,9 @@ impl PhysicsPipeline {
|
|||||||
hooks: &dyn PhysicsHooks,
|
hooks: &dyn PhysicsHooks,
|
||||||
events: &dyn EventHandler,
|
events: &dyn EventHandler,
|
||||||
) {
|
) {
|
||||||
|
self.counters.reset();
|
||||||
|
self.counters.step_started();
|
||||||
|
|
||||||
// Apply some of delayed wake-ups.
|
// Apply some of delayed wake-ups.
|
||||||
for handle in impulse_joints
|
for handle in impulse_joints
|
||||||
.to_wake_up
|
.to_wake_up
|
||||||
@@ -417,18 +420,15 @@ impl PhysicsPipeline {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Apply modifications.
|
// Apply modifications.
|
||||||
let modified_bodies = bodies.take_modified();
|
|
||||||
let mut modified_colliders = colliders.take_modified();
|
let mut modified_colliders = colliders.take_modified();
|
||||||
let mut removed_colliders = colliders.take_removed();
|
let mut removed_colliders = colliders.take_removed();
|
||||||
|
|
||||||
self.counters.reset();
|
|
||||||
self.counters.step_started();
|
|
||||||
|
|
||||||
super::user_changes::handle_user_changes_to_colliders(
|
super::user_changes::handle_user_changes_to_colliders(
|
||||||
bodies,
|
bodies,
|
||||||
colliders,
|
colliders,
|
||||||
&modified_colliders[..],
|
&modified_colliders[..],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let modified_bodies = bodies.take_modified();
|
||||||
super::user_changes::handle_user_changes_to_rigid_bodies(
|
super::user_changes::handle_user_changes_to_rigid_bodies(
|
||||||
Some(islands),
|
Some(islands),
|
||||||
bodies,
|
bodies,
|
||||||
|
|||||||
@@ -2,17 +2,12 @@ use crate::dynamics::{
|
|||||||
IslandManager, RigidBodyChanges, RigidBodyHandle, RigidBodySet, RigidBodyType,
|
IslandManager, RigidBodyChanges, RigidBodyHandle, RigidBodySet, RigidBodyType,
|
||||||
};
|
};
|
||||||
use crate::geometry::{ColliderChanges, ColliderHandle, ColliderPosition, ColliderSet};
|
use crate::geometry::{ColliderChanges, ColliderHandle, ColliderPosition, ColliderSet};
|
||||||
use parry::utils::hashmap::HashMap;
|
|
||||||
|
|
||||||
pub(crate) fn handle_user_changes_to_colliders(
|
pub(crate) fn handle_user_changes_to_colliders(
|
||||||
bodies: &mut RigidBodySet,
|
bodies: &mut RigidBodySet,
|
||||||
colliders: &mut ColliderSet,
|
colliders: &mut ColliderSet,
|
||||||
modified_colliders: &[ColliderHandle],
|
modified_colliders: &[ColliderHandle],
|
||||||
) {
|
) {
|
||||||
// TODO: avoid this hashmap? We could perhaps add a new flag to RigidBodyChanges to
|
|
||||||
// indicated that the mass properties need to be recomputed?
|
|
||||||
let mut mprops_to_update = HashMap::default();
|
|
||||||
|
|
||||||
for handle in modified_colliders {
|
for handle in modified_colliders {
|
||||||
// NOTE: we use `get` because the collider may no longer
|
// NOTE: we use `get` because the collider may no longer
|
||||||
// exist if it has been removed.
|
// exist if it has been removed.
|
||||||
@@ -26,22 +21,19 @@ pub(crate) fn handle_user_changes_to_colliders(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if co.changes.contains(ColliderChanges::SHAPE) {
|
if co
|
||||||
if let Some(co_parent) = co.parent {
|
.changes
|
||||||
mprops_to_update.insert(co_parent.handle, ());
|
.intersects(ColliderChanges::SHAPE | ColliderChanges::LOCAL_MASS_PROPERTIES)
|
||||||
|
{
|
||||||
|
if let Some(rb) = co
|
||||||
|
.parent
|
||||||
|
.and_then(|p| bodies.get_mut_internal_with_modification_tracking(p.handle))
|
||||||
|
{
|
||||||
|
rb.changes |= RigidBodyChanges::LOCAL_MASS_PROPERTIES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (to_update, _) in mprops_to_update {
|
|
||||||
let rb = bodies.index_mut_internal(to_update);
|
|
||||||
rb.mprops.recompute_mass_properties_from_colliders(
|
|
||||||
colliders,
|
|
||||||
&rb.colliders,
|
|
||||||
&rb.pos.position,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn handle_user_changes_to_rigid_bodies(
|
pub(crate) fn handle_user_changes_to_rigid_bodies(
|
||||||
@@ -163,6 +155,16 @@ pub(crate) fn handle_user_changes_to_rigid_bodies(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if changes
|
||||||
|
.intersects(RigidBodyChanges::LOCAL_MASS_PROPERTIES | RigidBodyChanges::COLLIDERS)
|
||||||
|
{
|
||||||
|
rb.mprops.recompute_mass_properties_from_colliders(
|
||||||
|
colliders,
|
||||||
|
&rb.colliders,
|
||||||
|
&rb.pos.position,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
rb.changes = RigidBodyChanges::empty();
|
rb.changes = RigidBodyChanges::empty();
|
||||||
rb.ids = ids;
|
rb.ids = ids;
|
||||||
rb.activation = activation;
|
rb.activation = activation;
|
||||||
|
|||||||
@@ -338,7 +338,7 @@ impl PhysxWorld {
|
|||||||
let densities: Vec<_> = rb
|
let densities: Vec<_> = rb
|
||||||
.colliders()
|
.colliders()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|h| colliders[*h].density().unwrap_or(0.0))
|
.map(|h| colliders[*h].density())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|||||||
Reference in New Issue
Block a user