soft_body_forces_and_impulses
Forces and impulses can be applied to a soft-body as a whole
(add_force, apply_impulseSoftBodyExternalForce::force,
SoftBodyExternalImpulse::velocity_changeaddForce, applyImpulser3SoftBody_AddForce, r3SoftBody_ApplyImpulseadd_force, apply_impulseadd_particle_force, apply_particle_impulseSoftBodyExternalForce::particle_forces,
SoftBodyExternalImpulse::particle_impulsesaddParticleForce, applyParticleImpulser3SoftBody_AddParticleForce, r3SoftBody_ApplyParticleImpulseadd_particle_force, apply_particle_impulsereset_forcesSoftBodyExternalForce component
changes or is removedresetForcesr3SoftBody_ResetForcesreset_forces
Two additional methods are provided for the effects which magnitude depends on the distance to a point: an impulse
applied within a radius
(apply_impulse_at_pointapplyImpulseAtPointr3SoftBody_ApplyImpulseAtPointapply_impulse_at_pointapply_radial_impulseapplyRadialImpulser3SoftBody_ApplyRadialImpulseapply_radial_impulsewake_up argument (True by default)
- Example 2D
- Example 3D
let soft_body = &mut world.soft_bodies[sheet_handle];
// The `true` argument makes sure the soft body is awake.
soft_body.reset_forces(true); // Reset the forces to zero.
soft_body.add_force(Vector::new(0.0, 1.0), true); // Spread over the particles by mass.
soft_body.add_particle_force(3, Vector::new(0.0, 1.0), true);
soft_body.apply_impulse(Vector::new(0.0, 0.1), true);
soft_body.apply_particle_impulse(3, Vector::new(0.0, 0.1), true);
// An impulse on the particles within 0.5 of a point, scaled down with the distance.
soft_body.apply_impulse_at_point(Vector::new(0.0, 0.1), Vector::new(-3.0, 3.0), 0.5, true);
// A blast pushing the particles away from a center.
soft_body.apply_radial_impulse(Vector::new(-3.0, 3.0), 0.1, 1.0, true);
let soft_body = &mut world.soft_bodies[cloth_handle];
// The `true` argument makes sure the soft body is awake.
soft_body.reset_forces(true); // Reset the forces to zero.
soft_body.add_force(Vector::new(0.0, 1.0, 0.0), true); // Spread over the particles by mass.
soft_body.add_particle_force(3, Vector::new(0.0, 1.0, 0.0), true);
soft_body.apply_impulse(Vector::new(0.0, 0.1, 0.0), true);
soft_body.apply_particle_impulse(3, Vector::new(0.0, 0.1, 0.0), true);
// An impulse on the particles within 0.5 of a point, scaled down with the distance.
soft_body.apply_impulse_at_point(
Vector::new(0.0, 0.1, 0.0),
Vector::new(0.0, 2.0, 0.0),
0.5,
true,
);
// A blast pushing the particles away from a center.
soft_body.apply_radial_impulse(Vector::new(0.0, 2.0, 0.0), 0.1, 1.0, true);
- Example 2D
- Example 3D
// The `true` argument makes sure the soft body is awake.
sheet.resetForces(true); // Reset the forces to zero.
sheet.addForce({ x: 0.0, y: 1.0 }, true); // Spread over the particles by mass.
sheet.addParticleForce(3, { x: 0.0, y: 1.0 }, true);
sheet.applyImpulse({ x: 0.0, y: 0.1 }, true);
sheet.applyParticleImpulse(3, { x: 0.0, y: 0.1 }, true);
// An impulse on the particles within 0.5 of a point, scaled down with the distance.
sheet.applyImpulseAtPoint({ x: 0.0, y: 0.1 }, { x: -3.0, y: 3.0 }, 0.5, true);
// A blast pushing the particles away from a center.
sheet.applyRadialImpulse({ x: -3.0, y: 3.0 }, 0.1, 1.0, true);
// The `true` argument makes sure the soft body is awake.
cloth.resetForces(true); // Reset the forces to zero.
cloth.addForce({ x: 0.0, y: 1.0, z: 0.0 }, true); // Spread over the particles by mass.
cloth.addParticleForce(3, { x: 0.0, y: 1.0, z: 0.0 }, true);
cloth.applyImpulse({ x: 0.0, y: 0.1, z: 0.0 }, true);
cloth.applyParticleImpulse(3, { x: 0.0, y: 0.1, z: 0.0 }, true);
// An impulse on the particles within 0.5 of a point, scaled down with the distance.
cloth.applyImpulseAtPoint({ x: 0.0, y: 0.1, z: 0.0 }, { x: 0.0, y: 2.0, z: 0.0 }, 0.5, true);
// A blast pushing the particles away from a center.
cloth.applyRadialImpulse({ x: 0.0, y: 2.0, z: 0.0 }, 0.1, 1.0, true);
The SoftBodyExternalForce and SoftBodyExternalImpulse components wake the soft-body up
automatically, and the impulses of the SoftBodyExternalImpulse component are reset to zero once they are applied. The
impulses depending on the distance to a point are applied to the Rapier soft-body of the entity directly:
- Example 2D
- Example 3D
fn apply_forces(
mut commands: Commands,
mut context: WriteRapierContext,
sheet: Single<Entity, With<Sheet>>,
) -> Result {
commands.entity(*sheet).insert((
// Persistent forces: applied at each step until the component changes or is removed.
SoftBodyExternalForce {
force: Vec2::new(0.0, 1.0),
particle_forces: vec![(3, Vec2::new(0.0, 1.0))],
},
// One-time impulses: applied (and reset to zero) at the next step.
SoftBodyExternalImpulse {
velocity_change: Vec2::new(0.0, 0.1),
particle_impulses: vec![(3, Vec2::new(0.0, 0.1))],
},
));
// The other impulses are applied to the Rapier soft-body directly. The `true` argument
// makes sure the soft-body is awake.
let mut context = context.single_mut()?;
if let Some(soft_body) = context.soft_body_mut(*sheet) {
// An impulse on the particles within 0.5 of a point, scaled down with the distance.
soft_body.apply_impulse_at_point(Vec2::new(0.0, 0.1), Vec2::new(-3.0, 3.0), 0.5, true);
// A blast pushing the particles away from a center.
soft_body.apply_radial_impulse(Vec2::new(-3.0, 3.0), 0.1, 1.0, true);
}
Ok(())
}
fn apply_forces(
mut commands: Commands,
mut context: WriteRapierContext,
cloth: Single<Entity, With<Cloth>>,
) -> Result {
commands.entity(*cloth).insert((
// Persistent forces: applied at each step until the component changes or is removed.
SoftBodyExternalForce {
force: Vec3::new(0.0, 1.0, 0.0),
particle_forces: vec![(3, Vec3::new(0.0, 1.0, 0.0))],
},
// One-time impulses: applied (and reset to zero) at the next step.
SoftBodyExternalImpulse {
velocity_change: Vec3::new(0.0, 0.1, 0.0),
particle_impulses: vec![(3, Vec3::new(0.0, 0.1, 0.0))],
},
));
// The other impulses are applied to the Rapier soft-body directly. The `true` argument
// makes sure the soft-body is awake.
let mut context = context.single_mut()?;
if let Some(soft_body) = context.soft_body_mut(*cloth) {
// An impulse on the particles within 0.5 of a point, scaled down with the distance.
soft_body.apply_impulse_at_point(
Vec3::new(0.0, 0.1, 0.0),
Vec3::new(0.0, 2.0, 0.0),
0.5,
true,
);
// A blast pushing the particles away from a center.
soft_body.apply_radial_impulse(Vec3::new(0.0, 2.0, 0.0), 0.1, 1.0, true);
}
Ok(())
}
- Example 2D
- Example 3D
// The last argument set to 1 makes sure the soft-body is awake.
r2SoftBody_ResetForces(sheet, 1); // Reset the forces to zero.
r2SoftBody_AddForce(sheet, r2Vector(0.0, 1.0), 1); // Added to the force of each particle.
r2SoftBody_AddParticleForce(sheet, 3, r2Vector(0.0, 1.0), 1);
r2SoftBody_ApplyImpulse(sheet, r2Vector(0.0, 0.1), 1);
r2SoftBody_ApplyParticleImpulse(sheet, 3, r2Vector(0.0, 0.1), 1);
// An impulse on the particles within 0.5 of a point, scaled down with the distance.
r2SoftBody_ApplyImpulseAtPoint(sheet, r2Vector(0.0, 0.1), r2Vector(-3.0, 3.0), 0.5, 1);
// A blast pushing the particles away from a center.
r2SoftBody_ApplyRadialImpulse(sheet, r2Vector(-3.0, 3.0), 0.1, 1.0, 1);
// The last argument set to 1 makes sure the soft-body is awake.
r3SoftBody_ResetForces(cloth, 1); // Reset the forces to zero.
r3SoftBody_AddForce(cloth, r3Vector(0.0, 1.0, 0.0), 1); // Added to the force of each particle.
r3SoftBody_AddParticleForce(cloth, 3, r3Vector(0.0, 1.0, 0.0), 1);
r3SoftBody_ApplyImpulse(cloth, r3Vector(0.0, 0.1, 0.0), 1);
r3SoftBody_ApplyParticleImpulse(cloth, 3, r3Vector(0.0, 0.1, 0.0), 1);
// An impulse on the particles within 0.5 of a point, scaled down with the distance.
r3SoftBody_ApplyImpulseAtPoint(cloth, r3Vector(0.0, 0.1, 0.0), r3Vector(0.0, 2.0, 0.0), 0.5, 1);
// A blast pushing the particles away from a center.
r3SoftBody_ApplyRadialImpulse(cloth, r3Vector(0.0, 2.0, 0.0), 0.1, 1.0, 1);
soft_body = world.soft_bodies[cloth_handle]
# The soft-body is woken up, unless `wake_up=False` is given.
soft_body.reset_forces() # Reset the forces to zero.
soft_body.add_force((0.0, 1.0, 0.0)) # Spread over the particles by mass.
soft_body.add_particle_force(3, (0.0, 1.0, 0.0))
soft_body.apply_impulse((0.0, 0.1, 0.0))
soft_body.apply_particle_impulse(3, (0.0, 0.1, 0.0))
# An impulse on the particles within 0.5 of a point, scaled down with the distance.
soft_body.apply_impulse_at_point((0.0, 0.1, 0.0), (0.0, 2.0, 0.0), 0.5)
# A blast pushing the particles away from a center.
soft_body.apply_radial_impulse((0.0, 2.0, 0.0), 0.1, 1.0)