Store either density or mass properties but not both
This commit is contained in:
@@ -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
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user