use crate::math::Real; /// Rules used to combine two coefficients. /// /// This is used to determine the effective restitution and /// friction coefficients for a contact between two colliders. /// Each collider has its combination rule of type /// `CoefficientCombineRule`. And the rule /// actually used is given by `max(first_combine_rule as usize, second_combine_rule as usize)`. #[derive(Copy, Clone, Debug, PartialEq, Eq)] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] pub enum CoefficientCombineRule { /// The two coefficients are averaged. Average = 0, /// The smallest coefficient is chosen. Min, /// The two coefficients are multiplied. Multiply, /// The greatest coefficient is chosen. Max, } impl CoefficientCombineRule { pub(crate) fn from_value(val: u8) -> Self { match val { 0 => CoefficientCombineRule::Average, 1 => CoefficientCombineRule::Min, 2 => CoefficientCombineRule::Multiply, 3 => CoefficientCombineRule::Max, _ => panic!("Invalid coefficient combine rule."), } } pub(crate) fn combine(coeff1: Real, coeff2: Real, rule_value1: u8, rule_value2: u8) -> Real { let effective_rule = rule_value1.max(rule_value2); match effective_rule { 0 => (coeff1 + coeff2) / 2.0, 1 => coeff1.min(coeff2), 2 => coeff1 * coeff2, _ => coeff1.max(coeff2), } } }