Store either density or mass properties but not both

This commit is contained in:
Emil Ernerfeldt
2021-03-08 10:12:12 +01:00
parent 05614dc471
commit 0370e7e37d

View File

@@ -41,6 +41,14 @@ impl ColliderFlags {
} }
} }
#[derive(Clone)]
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
enum MassInfo {
/// `MassProperties` are computed with the help of [`SharedShape::mass_properties`].
Density(Real),
MassProperties(Box<MassProperties>),
}
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[derive(Clone)] #[derive(Clone)]
/// A geometric entity that can be attached to a body so it can be affected by contacts and proximity queries. /// A geometric entity that can be attached to a body so it can be affected by contacts and proximity queries.
@@ -48,9 +56,7 @@ impl ColliderFlags {
/// To build a new collider, use the `ColliderBuilder` structure. /// To build a new collider, use the `ColliderBuilder` structure.
pub struct Collider { pub struct Collider {
shape: SharedShape, shape: SharedShape,
density: Real, mass_info: MassInfo,
/// If None, use [`Self::density`] and [`SharedShape::mass_properties`].
mass_properties: Option<Box<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,
@@ -115,9 +121,12 @@ impl Collider {
self.solver_groups self.solver_groups
} }
/// The density of this collider. /// The density of this collider, if set.
pub fn density(&self) -> Real { pub fn density(&self) -> Option<Real> {
self.density match &self.mass_info {
MassInfo::Density(density) => Some(*density),
MassInfo::MassProperties(_) => None,
}
} }
/// The geometric shape of this collider. /// The geometric shape of this collider.
@@ -138,9 +147,9 @@ 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.mass_properties { match &self.mass_info {
Some(mass_properties) => **mass_properties, MassInfo::Density(density) => self.shape.mass_properties(*density),
None => self.shape.mass_properties(self.density), MassInfo::MassProperties(mass_properties) => **mass_properties,
} }
} }
} }
@@ -199,12 +208,6 @@ impl ColliderBuilder {
} }
} }
/// The density of the collider being built.
pub fn get_density(&self) -> Real {
let default_density = if self.is_sensor { 0.0 } else { 1.0 };
self.density.unwrap_or(default_density)
}
/// Initialize a new collider builder with a compound shape. /// Initialize a new collider builder with a compound shape.
pub fn compound(shapes: Vec<(Isometry<Real>, SharedShape)>) -> Self { pub fn compound(shapes: Vec<(Isometry<Real>, SharedShape)>) -> Self {
Self::new(SharedShape::compound(shapes)) Self::new(SharedShape::compound(shapes))
@@ -564,20 +567,13 @@ 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, mass_properties); let mass_info = if let Some(mp) = self.mass_properties {
if let Some(mp) = self.mass_properties { MassInfo::MassProperties(Box::new(mp))
mass_properties = Some(Box::new(mp));
let volume = volume(&self.shape);
density = if volume == 0.0 || mp.inv_mass == 0.0 {
Real::INFINITY
} else {
mass(&mp) / volume
};
} else { } else {
density = self.get_density(); let default_density = if self.is_sensor { 0.0 } else { 1.0 };
mass_properties = None; let density = self.density.unwrap_or(default_density);
} MassInfo::Density(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);
@@ -592,8 +588,7 @@ impl ColliderBuilder {
Collider { Collider {
shape: self.shape.clone(), shape: self.shape.clone(),
density, mass_info,
mass_properties,
friction: self.friction, friction: self.friction,
restitution: self.restitution, restitution: self.restitution,
delta: self.delta, delta: self.delta,
@@ -609,11 +604,3 @@ 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
}