collider_friction
Friction is a force that opposes the relative tangential motion between two rigid-bodies with colliders in contact. This force has a direction orthogonal to the contact normal and opposite to the relative rigid-body motion at the contact point. Following the Coulomb friction model, the maximum magnitude of this force is the magnitude of the force along the contact normal multiplied by a friction coefficient. A friction coefficient of 0 implies no friction at all (completely sliding contact) and a coefficient greater or equal to 1 implies a very strong friction. Values greater than 1 are allowed.
Rapier does not make any distinction between the fixed and dynamic friction coefficients currently.
Each collider has its own friction coefficient. This means that when two colliders are in contact, we need to apply a
rule that combines the friction coefficients of these two colliders into a single coefficient that will be used for
the contact. This rule is described by CoefficientCombineRule enumR3_COMBINE_* constants
CoefficientCombineRule::AverageCoefficientCombineRule.AverageR3_COMBINE_AVERAGE : the average of the two coefficients is used for the contact.CoefficientCombineRule.AVERAGECoefficientCombineRule::MinCoefficientCombineRule.MinR3_COMBINE_MIN : the minimum among the two coefficients is used for the contact.CoefficientCombineRule.MINCoefficientCombineRule::MultiplyCoefficientCombineRule.MultiplyR3_COMBINE_MULTIPLY : the product of the two coefficients is used for the contact.CoefficientCombineRule.MULTIPLYCoefficientCombineRule::MaxCoefficientCombineRule.MaxR3_COMBINE_MAX : the maximum among the two coefficients is used for the contact.CoefficientCombineRule.MAX
CoefficientCombineRule::ClampedSum: the sum of the two coefficients, clamped to , is used for the contact.CoefficientCombineRule::GeometricMean: the square root of the product of the two coefficients is used for the contact. It is stricter than the average (any coefficient of zero results in zero) but less aggressive than the product.
R3_COMBINE_CLAMPED_SUM: the sum of the two coefficients, clamped to , is used for the contact.R3_COMBINE_GEOMETRIC_MEAN: the square root of the product of the two coefficients is used for the contact. It is stricter than the average (any coefficient of zero results in zero) but less aggressive than the product.
CoefficientCombineRule.CLAMPED_SUM: the sum of the two coefficients, clamped to , is used for the contact.CoefficientCombineRule.GEOMETRIC_MEAN: the square root of the product of the two coefficients is used for the contact. It is stricter than the average (any coefficient of zero results in zero) but less aggressive than the product.
By default, the AverageR3_COMBINE_AVERAGEGeometricMean > ClampedSum > Max > Multiply > Min > Average.R3_COMBINE_GEOMETRIC_MEAN > R3_COMBINE_CLAMPED_SUM > R3_COMBINE_MAX > R3_COMBINE_MULTIPLY > R3_COMBINE_MIN > R3_COMBINE_AVERAGE, i.e., the rule with the greatest value wins.
For example if one collider with the Multiply friction combine rule is in contact with a collider with the Average friction
combine rule, then the Multiply rule will be applied for the friction coefficient of this contact (i.e. the coefficients
of both colliders will be multiplied to obtain the coefficient used by the contact).
The CoefficientCombineRule
The friction coefficient and friction combine rule can both be set when the collider is created or after its creation:
/* Set the friction coefficient and friction combine rule
when the collider is created. */
let collider = ColliderBuilder::ball(0.5)
.friction(0.7)
.friction_combine_rule(CoefficientCombineRule::Min)
.build();
/* Set the friction coefficient and friction combine rule
after the collider creation. */
let collider = &mut world.colliders[collider_handle];
collider.set_friction(0.7);
collider.set_friction_combine_rule(CoefficientCombineRule::Min);
assert_eq!(collider.friction(), 0.7);
assert_eq!(
collider.friction_combine_rule(),
CoefficientCombineRule::Min
);
/* Set the friction coefficient and friction combine rule
when the collider is created. */
commands.spawn(Collider::ball(0.5)).insert(Friction {
coefficient: 0.7,
combine_rule: CoefficientCombineRule::Min,
});
/* Set the friction coefficient and friction combine rule
inside of a system. */
fn modify_collider_friction(mut frictions: Query<&mut Friction>) {
for mut friction in frictions.iter_mut() {
friction.coefficient = 0.7;
friction.combine_rule = CoefficientCombineRule::Min;
}
}
/* Set the friction coefficient and friction combine rule
when the collider is created. */
let colliderDesc = RAPIER.ColliderDesc.ball(0.5)
.setFriction(0.7)
.setFrictionCombineRule(RAPIER.CoefficientCombineRule.Min);
let collider = world.createCollider(colliderDesc);
/* Set the friction coefficient and friction combine rule
after the collider creation. */
collider.setFriction(0.7);
collider.setFrictionCombineRule(RAPIER.CoefficientCombineRule.Min);
/* Set the friction coefficient and friction combine rule
when the collider is created. */
R2ColliderDesc collider = r2BallColliderDesc(0.5);
collider.friction = 0.7;
collider.frictionCombineRule = R2_COMBINE_MIN;
/* Set the friction coefficient and friction combine rule
after the collider creation. */
r2Collider_SetFriction(collider_handle, 0.7);
r2Collider_SetFrictionCombineRule(collider_handle, R2_COMBINE_MIN);
assert(r2Collider_Friction(collider_handle) == (R2Real)0.7);
assert(r2Collider_FrictionCombineRule(collider_handle) == R2_COMBINE_MIN);
# Set the friction coefficient and friction combine rule
# when the collider is created.
collider = (
rp.Collider.ball(0.5)
.friction(0.7)
.friction_combine_rule(rp.CoefficientCombineRule.MIN)
.build()
)
# Set the friction coefficient and friction combine rule
# after the collider creation.
collider = world.colliders[collider_handle]
collider.friction = 0.7
collider.friction_combine_rule = rp.CoefficientCombineRule.MIN
assert math.isclose(collider.friction, 0.7, rel_tol=1.0e-6)
assert collider.friction_combine_rule == rp.CoefficientCombineRule.MIN