force.containment

Keep a 3D swarm inside a shape: a spring at the surface, a pull back from far away, and a drag when the shape rotates.

force.containment(layout: VolumeSwarmLayout, cfg: {
    field: ShapeField3
    /** How far apart the two samples of the field's slope are taken. 0.02 is typical. */
    // Central-difference epsilon for the field gradient.
    gradEps: number
    /** The spring at the surface: fades in from `featherFrom` to `featherTo` (signed distance), `base` push plus `springK` per unit outside. */
    // Strong outside, diffuse inside (a sharp feather packs a coherent shell).
    wall: {featherFrom: number; featherTo: number; base: number; springK: number}
    /** The pull home once an agent is `from`..`to` from the origin, with strength `k`. */
    // A hard clamp piles strays into lines.
    recall: {from: number; to: number; k: number}
    /** The pull toward the middle where the signed distance is `from`..`to`, with strength `k`. */
    // SDF-VALUE-driven pull toward the origin — direction-safe where the gradient degenerates.
    homing: {from: number; to: number; k: number}
    /** How wide a band around the surface the rotation drag fades over. */
    // Drag toward the rotating container's feature velocity ω×r, feathered to inside.
    entrainment: {featherHalf: number}
}): AgentForce3

Import sim from shaders/std and use sim.agentForces.force.containment.

Parameters

NameTypeNotes
layoutVolumeSwarmLayout
cfg`{
field: ShapeField3
/** How far apart the two samples of the field's slope are taken. 0.02 is typical. */
// Central-difference epsilon for the field gradient.
gradEps: number
/** The spring at the surface: fades in from `featherFrom` to `featherTo` (signed distance), `base` push plus `springK` per unit outside. */
// Strong outside, diffuse inside (a sharp feather packs a coherent shell).
wall: {featherFrom: number; featherTo: number; base: number; springK: number}
/** The pull home once an agent is `from`..`to` from the origin, with strength `k`. */
// A hard clamp piles strays into lines.
recall: {from: number; to: number; k: number}
/** The pull toward the middle where the signed distance is `from`..`to`, with strength `k`. */
// SDF-VALUE-driven pull toward the origin — direction-safe where the gradient degenerates.
homing: {from: number; to: number; k: number}
/** How wide a band around the surface the rotation drag fades over. */
// Drag toward the rotating container's feature velocity ω×r, feathered to inside.
entrainment: {featherHalf: number}

}` | |

Example

forces: [pressure.force, force.containment(simLayout, {field: hexField, gradEps: 0.02, wall: {featherFrom: -0.1, featherTo: 0.01, base: 1.1, springK: 22}, recall: {from: 0.85, to: 1.1, k: 9}, homing: {from: 0.12, to: 0.45, k: 5}, entrainment: {featherHalf: 0.05}})]

See also

  • shapeField — The signed-distance function of the shape a swarm lives in, for force.containment.
  • force.pressure — Spread a 3D swarm evenly by pushing agents away from crowded cells of a density grid.