softbody2d
2d · physics · 56 properties · 2D
A deformable 2D body: particles linked by elastic constraints, laid out by kind and made of what the material rows say. A polygon on the same node is drawn from the solver's positions when the two agree on the vertex count, which the polygon, trimesh and volumetric kinds give and a generator does not.
In a scene, softbody2d is the node key that applies it. A script reaches each property below as a field on node.softbody2d: reading one asks the running component, and assigning one leaves the rest alone. The whole table is node.softbody2d.get() and node.softbody2d.set(table).
Properties
| property | type | default | description |
|---|---|---|---|
a | vec2 | [0,0] | Where a rope starts, relative to the node |
b | vec2 | [0,-1] | Where a rope ends, relative to the node |
bend_damping | float | 1 | The damping ratio of the bending springs Range 0–100. |
bend_frequency | float | 10 | The same for the bending edges, which are what stop a cloth folding flat Range 0–10000. |
can_sleep | bool | true | Let the body stop being simulated once it settles |
cell_model | enum | volume | What a cell resists with: a volume constraint for a cheap jelly, or an elastic model a Young modulus parameterises One of volume, corotational, neo_hookean. |
cell_size | float | 0.25 | How big one triangle is when a volumetric body fills an outline; smaller is finer, slower and stiffer to tear At least 0.001. |
cells | vec2 | [4,4] | How many cells along each axis of a grid |
deformation_damping | float | 0 | How fast the particles are pulled towards the body's own rigid motion, which settles a residual sway without slowing the body down Range 0–1000. |
dominance | int | 0 | Which body wins a contact: a higher one is never pushed by a lower one Range -127–127. |
edge_damping | float | 1 | The damping ratio of that spring; 1 settles without overshooting Range 0–100. |
edge_frequency | float | 30 | The frequency of the spring a structural edge is solved as, in hertz; higher is stiffer Range 0–10000. |
edge_plastic_creep | float | 1 | How fast, per second, an edge's excess strain is absorbed into its rest length At least 0. |
edge_plastic_flow | enum | both | Whether an edge sets under a squeeze, a stretch, or both: clay dents but does not stay stretched One of both, compression, tension. |
edge_plastic_max | float | 0.5 | The largest permanent set an edge may take, as a fraction of its first length At least 0. |
edge_plastic_yield | float | 0 | The edge strain past which its rest length flows towards its current length At least 0. |
elastic_damping | float | 1 | Damping ratio of the elastic cells Range 0–100. |
friction | float | 0.5 | Surface friction of the body's collider; 0 is ice At least 0. |
gravity_scale | float | 1 | How much gravity pulls on the particles |
half_extents | vec2 | [0.5,0.5] | Half-sizes of the sheet, when kind is grid |
interior_strength | float | 1 | How many times tougher an undamaged inside element is than a surface one, so cracks start at the surface and run inward At least 1. |
kind | enum | grid | How the body's particles and elements are laid out One of grid, disk, polygon, rope, volumetric, trimesh, polyline. |
layers | flags | ["0"] | The layers this body is on One of 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31. |
linear_damping | float | 0 | Air friction on the particles At least 0. |
mask | flags | [] | The layers it collides with; empty means every layer One of 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31. |
mass | float | 1 | What the whole body weighs, spread over its particles At least 0. |
max_tears_per_step | float | 0 | The most edges that may tear in one step, which paces a crack; 0 is no limit At least 0. |
mesh | asset · mesh | — | Points and triangles for a polygon, trimesh, polyline or volumetric body: the same asset a polygon draws |
min_piece | float | 0 | The smallest piece, in elements, a tear may split off; 0 lets rapier choose At least 0. |
oriented | bool | false | Treat the surface as closed and outward-facing, so its inside holds bodies in instead of pushing them out |
particle_radius | float | 0 | How thick the particles are; 0 takes what the layout works out At least 0. |
particles | float | 16 | How many particles a rope or the rim of a disk is made of At least 2. |
pgs_iterations | float | 3 | Extra iterations inside each substep, for the same Range 0–64. |
pinned | list | [] | The particles held where they are, by index: a cloth hangs from these, and softbody_particles says how many there are to choose from |
plastic_creep | float | 1 | How fast, per second, the strain past the yield is absorbed into the rest shape At least 0. |
plastic_max | float | 1 | The most permanent deformation a cell may take, so a crushed cell cannot flow to a sliver At least 0. |
plastic_yield | float | 0 | The cell strain past which the rest shape flows towards the current one; 0 is perfectly elastic At least 0. |
poisson_ratio | float | 0.3 | How much an elastic cell bulges sideways when squeezed; towards 0.5 it stops changing volume at all Range 0–0.499. |
radius | float | 0.5 | Radius, when kind is disk At least 0.001. |
restitution | float | 0 | Bounciness of the body's collider Range 0–1. |
self_contacts | bool | false | Let the body's own surface collide with itself, which stops a cloth passing through its own fold |
shape_matching | bool | false | Pull the body back towards the shape it was built in, which is what keeps a jelly a jelly |
shape_matching_damping | float | 1 | The damping ratio of the shape-matching constraints Range 0–100. |
shape_matching_frequency | float | 10 | The same for shape matching, which pulls the body back towards the shape it was built in Range 0–10000. |
skin | bool | false | Keep the outline as the drawn shape and let the cells carry it, so a detail the cell size cannot resolve survives |
solver | enum | constraints | Which solver runs the elasticity: sequential constraints, or an implicit Euler step over the whole body One of constraints, fem. |
solver_iterations | float | 0 | Extra solver substeps for this body and everything it touches Range 0–64. |
tear_force | float | 0 | The pull past which an edge breaks; 0 is unbreakable. Either criterion tears an edge At least 0. |
tear_smoothing | float | 0 | Over how many seconds a load is averaged before it is tested, so one hard frame does not tear a body At least 0. |
tear_strain | float | 0 | The stretch past which an element breaks, as a fraction of its rest length; 0 is unbreakable At least 0. |
tension_only | bool | false | Let the edges resist stretching only, so the body folds freely and never pushes itself open |
volume_damping | float | 1 | The damping ratio of the volume constraints Range 0–100. |
volume_factor | float | 1 | What that volume is held at, as a multiple of the rest volume; above 1 inflates the body At least 0. |
volume_frequency | float | 30 | The same for the constraints holding a cell's volume, and for the whole-body one Range 0–10000. |
volume_preservation | bool | false | Hold the volume each closed piece of the body encloses |
young_modulus | float | 10000 | Stiffness of the elastic cells, as force per unit area; a finer mesh does not get stiffer for it At least 0. |
Asset types this component references: mesh.
Script functions
Methods of node.softbody2d, the handle a node carrying this component exposes. Every handle also has get(), set(table), patch(table), has() and remove().
From physics2d:
| method | what it does |
|---|---|
pin_particle(int) | Hold one particle where it is, which is how a cloth hangs from a hook. |
set_softbody(any) | Build the node's soft body from a softbody2d table: kind, the shape rows, and the material rows. |
softbody_area() -> float | How much area the body encloses right now, against softbody_rest_area for how far it is squeezed. |
softbody_center() -> any | The body's centre of mass, which is where it is when a deformable body has no one position. |
softbody_particles() -> int | How many particles the body ended up with, which a generator decides rather than the author. |
softbody_position(int) -> any | Where one particle is, in world space. |
softbody_rest_area() -> float | How much it encloses at rest. |