Skip to main content

soft_body_contacts

A soft-body collides through the collider covering its surface, which is a deformable triangle-mesh (a polyline in 2D) built from the template given to the builder.

Thickness​

The radius of the particles (particle_radius) is the thickness of the soft-body wrt. collision-detection: it is the contact skin of its surface collider, i.e., the distance kept between the surface and the objects touching it, as well as the distance the solver bounds the motion of one particle by at each substep. A radius that is too small relative to the distance between two neighboring particles may let thin objects pass through the surface, whereas a radius larger than that distance will make the body collide with itself even when it is at rest. Therefore it is recommended to keep it well below the distance between two neighboring particles. Note that every constructor picks a sensible default, i.e., about half the length of its edges or of its cells.

Oriented surfaces and shells​

A closed surface (a balloon, a jelly cube, a filled polygon) is oriented: its contacts are generated on its outward side only, like for an oriented triangle-mesh, so nothing is held inside it. An open surface (a rope, a cloth) is two-sided, because a body arriving from either side must be stopped. This is what the builder does by default, and it is what a solid body wants. A shell, i.e., a closed surface which inner side must hold the bodies contained in it, is obtained by asking for a surface that is not oriented (oriented):

// A shell: a closed surface that is not oriented, so its inner side holds the bodies put
// inside it (a bowl, a box, a container). A closed surface is oriented by default.
commands.spawn((
Transform::from_xyz(-3.0, 2.0, 0.0),
SoftBody::disk(0.8, 24).map(|builder| {
builder
.oriented(false)
.softness(SpringCoefficients::new(60.0, 1.0))
}),
));
note

After the insertion, the shape of the Rapier collider of the surface is the authority: the flag is changed there, like for any other collider.

Self-contacts​

A soft-body doesn't collide with itself by default. Self-contacts are enabled by SoftBodyBuilder::self_contacts, which makes the vertices and the edges of the surface collide with the surface of their own body: this is what keeps a cloth folding onto itself, or a jelly squashed against itself, from passing through itself. Note that they are more expensive, since the whole surface must be tested against itself.

Penetrations and tangles​

The contacts between two meshes are computed triangle by triangle (segment by segment in 2D), without any notion of their interiors. As long as the two surfaces don't penetrate, this works well. But as soon as they do, some of these local contacts start pointing the wrong way, and actively keep the two surfaces in their penetrating state instead of separating them. Deformations make it worse, since a single surface can also cross itself and end up tangled:

Local contacts between penetrating meshes

Rapier handles these configurations by measuring the volume of the overlap between the two surfaces. The gradient of that volume gives a good approximation of the direction separating the two bodies, aka. the volume normal, which is used both to push the overlapping regions apart, and to correct the direction of the local contacts inside them:

Contact directions corrected with the volume normal

This is enabled by default for the closed surfaces, against other soft-bodies as well as against rigid colliders.

It is configured, along with the detection and the recovery of the tangled configurations, by the recovery settings of the global settings (integration_parameters.soft_bodies.recovery of the RapierContextSimulation component). Every mechanism can be switched off individually, and the table below lists the ones to look at for the most common problems:

ProblemWhat to change
Thin or fast objects pass through a surface.Raise the particle radius (particle_radius). Let the body request more substeps while it is hit fast (max_extra_substeps).
Two bodies crossing corner-first don't collide.Enable edge_speculation (note that it can leave pressed 3D piles crossed).
A body stays tangled with itself.Keep self_stand_down enabled (the default), which lets the elasticity untangle it, or push the crossed features apart with crossing_repulsion.
The recovery from a penetration is too slow, or too violent.Change the recovery_pace, i.e., the corrective speed allowed to the recovery (in length units per second).
Soft contacts feel too spongy.Raise the contact_stiffening of the soft-body contacts relative to the rigid ones.
The overlap of two bodies isn't resolved at all.Make sure both surfaces are closed: the intersection-volume constraints (overlap_constraints) only apply to them.