Skip to main content

soft_body_events

The tears applied during a step, whether they were generated by the simulation itself or requested with RapierSoftBody::tear_edge (as well as the ones applied by RapierContextMut::tear_soft_body and cut_soft_body), are reported the same way as the collision events, i.e., as messages. Each event (a SoftBodyTearEvent, read with a MessageReader) identifies the soft-body that tore and gives the pieces it was split into, so the rendering of the scene can be updated accordingly:

The SoftBodyTearEvent message gives the entities of the torn soft-body and of its pieces (the first piece being the torn entity itself, the other ones being the entities already returned by tear_soft_body and cut_soft_body for the tears they applied), the pieces of the clusters the tear split (cluster_splits), and the joints it moved from a cluster proxy to another (moved_joints). Its raw field is the event of Rapier, with every detail of the topology change in terms of handles and particle indices:

fn read_tear_events(context: ReadRapierContext, mut tears: MessageReader<SoftBodyTearEvent>) {
let Ok(context) = context.single() else {
return;
};
for tear in tears.read() {
// The first piece is the torn entity itself, the others are the entities spawned for
// the soft-bodies split off it.
for piece in &tear.pieces {
println!(
"Soft body {} tore: piece {} has {} particles",
tear.soft_body,
piece.soft_body,
piece.particles.len()
);
}
// Where a particle of the torn body went.
if let Some((handle, index)) = tear.raw.particle_destination(399) {
let entity = context.soft_body_entity(handle);
println!("particle 399 is now particle {index} of {entity:?}");
}
}
}