The contribution at position, for a body moving at velocity, at
absolute simulation time time (seconds). Whether the vector is read as
newtons or as m/s² is declared by the caller — see ForceFieldUnits.
OptionalsampleOptional fast path: the same contribution as ForceField.sample,
for count bodies at once, added into out (stride-3 xyz).
This is @fourjs/particles' ParticleForceField.sampleAll transcribed
member-for-member so every built-in particle field is a batched
ForceField with no adapter. Contract, restated from that
transcription:
out and may hand over a
zeroed buffer or a running sum; overwriting it deletes whatever was
already there.out is binary64. The scalar path accumulates in JavaScript
numbers; a binary32 accumulator would make a batched step differ from
a scalar one in the last bits, and §33 does not permit that.sample. Same arithmetic, same order, same
special cases. Positions and velocities are xyz at stride 3, valid
for [0, 3 · count). Read, never write.sample: no clock, no Math.random.A field that omits this is not penalised: the system falls back to ForceField.sample for that field alone, in the same registration order, with the same result.
OptionalsampleOptional angular channel (PH-8 remainder, 2026-09-06). Torque in newton-metres at the same sample point ForceField.sample uses.
§27's sample stays one linear vector so a ParticleForceField remains
assignable without an adapter. Torque is a second, optional method:
"acceleration" reading would need the inertia tensor, which a
field does not have and which is not a scalar.out rules as ForceField.sample. Do not
mutate position, velocity, or angularVelocity.
§27's
ForceField, transcribed member-for-member.Structurally identical to
@fourjs/particles'ParticleForceField, so a field written for either pillar works in both (module header). Contract for an implementation, restated from §27 and the particle transcription so that a reader of this package alone has all of it:positionorvelocity. They are the caller's scratch copies of the body's live state.outwhen it is supplied and return it — the system always supplies one, and doing so is what keeps the step allocation-free (§7b). Returning a different vector is legal (the caller reads the return value, neverout), but that vector must stay valid until the next call.outis not zeroed by the caller. Write every component.time, in seconds. NoMath.random— take aSeededRandomat construction if the field is procedural.A field that returns a non-finite component poisons the body it is sampled at; nothing here checks, for the same reason nothing checks in the particle path — the check would run per body per field per step, and §85's place for it is the field's own constructor.
ForceField.sampleAll is the optional §27 batch fast path (R-34's particle spelling, reused here so a field written for either pillar keeps one identity). ForceFieldSystem calls it when a field offers it; ForceField.sample stays the required §27 entry point.