Skip to main content

soft_body_attachments

A particle can also be attached directly to a rigid-body (r3SoftBody_AttachParticle), which is the simplest way of combining the two kinds of bodies: a rope tied to a swinging ball, a flag attached to its pole, etc. Unlike pinning, an attachment is a two-way point-to-point constraint: the rigid-body holds the particle, and the particle pulls the rigid-body back. The anchor is the position the particle has when the attachment is created, expressed in the local frame of the rigid-body. Note that a particle attached twice keeps both of its attachments, and that an attachment is undone with r3SoftBody_DetachParticle:

// Attach the last particle of a rope to a rigid box, at the particle's position.
R2SoftBodyDesc rope = r2RopeSoftBodyDesc(r2Vector(8.0, 9.0), r2Vector(12.0, 9.0), 25);
uint32_t pinned[] = {0};
r2SoftBodyDesc_SetPinnedParticles(&rope, (R2IndexView){pinned, 1});
rope.material = r2UniformSoftBodyMaterial((R2SpringCoefficients){40.0, 1.0});
R2SoftBodyHandle rope_handle = r2InsertSoftBody(world, &rope);
R2Vector last_position = r2SoftBody_ParticlePosition(rope_handle, 24);
R2RigidBodyDesc weight_body = r2DynamicRigidBodyDesc();
weight_body.position.translation = r2VectorSub(last_position, r2Vector(0.0, 0.4));
R2RigidBodyHandle weight = r2InsertRigidBody(world, &weight_body);
R2ColliderDesc weight_collider = r2CuboidColliderDesc(r2Vector(0.3, 0.3));
weight_collider.density = 2.0;
r2InsertCollider(weight, &weight_collider);
r2SoftBody_AttachParticle(rope_handle, 24, weight);

Note that r3SoftBody_DetachParticle returns whether the particle was attached at all.

info

The target of an attachment must be an ordinary rigid-body: r3SoftBody_AttachParticle rejects the root body and the cluster proxies of a soft-body (they are rigid-bodies too, see r3RigidBody_IsSoftFrame). Two soft-bodies are linked with a joint between their soft frames instead.