Add ability to set MassProperties for each ColliderBuilder
Fix https://github.com/dimforge/rapier/issues/132
This commit is contained in:
@@ -49,6 +49,7 @@ impl ColliderFlags {
|
|||||||
pub struct Collider {
|
pub struct Collider {
|
||||||
shape: SharedShape,
|
shape: SharedShape,
|
||||||
density: Real,
|
density: Real,
|
||||||
|
mass_properties: MassProperties,
|
||||||
pub(crate) flags: ColliderFlags,
|
pub(crate) flags: ColliderFlags,
|
||||||
pub(crate) solver_flags: SolverFlags,
|
pub(crate) solver_flags: SolverFlags,
|
||||||
pub(crate) parent: RigidBodyHandle,
|
pub(crate) parent: RigidBodyHandle,
|
||||||
@@ -134,9 +135,9 @@ impl Collider {
|
|||||||
// aabb1.merged(&aabb2)
|
// aabb1.merged(&aabb2)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
/// Compute the local-space mass properties of this collider.
|
/// Read the local-space mass properties of this collider.
|
||||||
pub fn mass_properties(&self) -> MassProperties {
|
pub fn mass_properties(&self) -> &MassProperties {
|
||||||
self.shape.mass_properties(self.density)
|
&self.mass_properties
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,8 +147,11 @@ 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 density of the collider to be built.
|
/// The uniform density of the collider to be built.
|
||||||
density: Option<Real>,
|
density: Option<Real>,
|
||||||
|
/// Overrides automatic computation of `MassProperties`.
|
||||||
|
/// If None, it will be computed based on shape and desnity.
|
||||||
|
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.
|
||||||
@@ -177,6 +181,7 @@ impl ColliderBuilder {
|
|||||||
Self {
|
Self {
|
||||||
shape,
|
shape,
|
||||||
density: None,
|
density: None,
|
||||||
|
mass_properties: None,
|
||||||
friction: Self::default_friction(),
|
friction: Self::default_friction(),
|
||||||
restitution: 0.0,
|
restitution: 0.0,
|
||||||
delta: Isometry::identity(),
|
delta: Isometry::identity(),
|
||||||
@@ -456,6 +461,8 @@ 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 assigna 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
|
||||||
@@ -492,12 +499,22 @@ impl ColliderBuilder {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the 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
|
||||||
|
/// either [`Self::density`] or [`Self::mass_properties`].
|
||||||
pub fn density(mut self, density: Real) -> Self {
|
pub fn density(mut self, density: Real) -> Self {
|
||||||
self.density = Some(density);
|
self.density = Some(density);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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
|
||||||
|
/// either [`Self::density`] or [`Self::mass_properties`].
|
||||||
|
pub fn mass_properties(mut self, mass_properties: MassProperties) -> Self {
|
||||||
|
self.mass_properties = Some(mass_properties);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets the initial translation of the collider to be created,
|
/// Sets the initial translation of the collider to be created,
|
||||||
/// relative to the rigid-body it is attached to.
|
/// relative to the rigid-body it is attached to.
|
||||||
#[cfg(feature = "dim2")]
|
#[cfg(feature = "dim2")]
|
||||||
@@ -540,7 +557,21 @@ 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 density = self.get_density();
|
let (density, mass_properties);
|
||||||
|
if let Some(mp) = self.mass_properties {
|
||||||
|
mass_properties = mp;
|
||||||
|
|
||||||
|
let volume = volume(&self.shape);
|
||||||
|
density = if volume == 0.0 || mp.inv_mass == 0.0 {
|
||||||
|
Real::INFINITY
|
||||||
|
} else {
|
||||||
|
mass(&mp) / volume
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
density = self.get_density();
|
||||||
|
mass_properties = self.shape.mass_properties(density);
|
||||||
|
}
|
||||||
|
|
||||||
let mut flags = ColliderFlags::empty();
|
let mut flags = ColliderFlags::empty();
|
||||||
flags.set(ColliderFlags::SENSOR, self.is_sensor);
|
flags.set(ColliderFlags::SENSOR, self.is_sensor);
|
||||||
flags = flags
|
flags = flags
|
||||||
@@ -555,6 +586,7 @@ impl ColliderBuilder {
|
|||||||
Collider {
|
Collider {
|
||||||
shape: self.shape.clone(),
|
shape: self.shape.clone(),
|
||||||
density,
|
density,
|
||||||
|
mass_properties,
|
||||||
friction: self.friction,
|
friction: self.friction,
|
||||||
restitution: self.restitution,
|
restitution: self.restitution,
|
||||||
delta: self.delta,
|
delta: self.delta,
|
||||||
@@ -570,3 +602,11 @@ impl ColliderBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn volume(shape: &SharedShape) -> Real {
|
||||||
|
mass(&shape.mass_properties(1.0)) // TODO: add SharedShape::volume to parry
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mass(mp: &MassProperties) -> Real {
|
||||||
|
crate::utils::inv(mp.inv_mass) // TODO: add MassProperties::mass() to parry
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user