physicsGenerated
Category: Packages · Manifest: use "kernels/";
Rigid circles and boxes in the plane that fall, collide, rest, slide and bounce.
Description
Section titled “Description”Rigid circles and boxes in the plane that fall, collide, rest, slide and bounce: pairs found through a grid, manifolds solved all at once over substeps.
Layer: Simulation. Uses: parallel.
use "physics.entpkg";Kernels
Section titled “Kernels”kernels/body.ent— Rigid bodies in the plane.kernels/broad_phase.ent— Finding pairs. Kernels:physics.bounds@1,physics.spans@1,physics.owners@1,physics.cells@1,physics.cell_counts@1,physics.places@1,physics.no_entries@1,physics.pair_counts@1,physics.no_pairs@1,physics.pairs@1.kernels/contact.ent— Colliding. Kernels:physics.collide@1,physics.shared@1,physics.no_counts@1,physics.no_pushes@1.kernels/query.ent— Asking the world. Kernels:physics.ray@1,physics.no_contacts@1.kernels/solve.ent— Solving. Kernels:physics.warm@1,physics.solve@1,physics.bounce@1,physics.pushes@1,physics.push@1,physics.fall@1,physics.move@1.
Graph presets
Section titled “Graph presets”graphs/step.esn— One step of a world of bodies,dtlong.graphs/substep.esn— One substep ofstep.esn.
tests/ holds scenes and their replays, run on every backend:
many.replay, motion.replay, pile.replay, rest.replay,
roll.replay, wide.replay. Every Kernel of the package is reached by
one of them.
Used by the physics example.
Kernels
Section titled “Kernels”| Kernel | Mode | Brief |
|---|---|---|
physics.bounce@1 |
map | Each manifold’s bounce: the points that closed faster than threshold and push, given back the restitution of what they closed at. |
physics.bounds@1 |
map | Each body’s box, grown by margin and by how far it may move in the step. |
physics.cell_counts@1 |
scatter into input 1 with sum | How many entries each cell holds. |
physics.cells@1 |
map | The cell each entry is, a body’s cells in rows. |
physics.collide@1 |
map | Each pair’s manifold. A pair keeps points up to margin apart and as far as the two may close in the step; a sensor’s only where they touch. A point starts from the impulses the pair’s point there held in the last step, held, so a resting stack is pushed as hard as it was a step ago. |
physics.fall@1 |
map | Each moving body pulled by gravity for a substep and slowed by damping a second. |
physics.move@1 |
map | Each body moved by its velocity and turned by its spin for a substep. |
physics.no_contacts@1 |
map | No manifolds: what a world’s held starts from. |
physics.no_counts@1 |
map | A zero for each body. |
physics.no_entries@1 |
map | A zero for each entry. |
physics.no_pairs@1 |
map | Pairs of nothing, to be filled. |
physics.no_pushes@1 |
map | No push for each body. |
physics.owners@1 |
map | The body each entry is. |
physics.pair_counts@1 |
map | How many pairs each body is the higher of. |
physics.pairs@1 |
scatter into input 12 with max | The pairs, each body’s in its part of the list, so the list is in order of the higher body: the walk physics.pair_counts@1 counts. |
physics.places@1 |
scatter into input 1 with max | Where each entry is in the sorted order. |
physics.push@1 |
map | Each body with its pushes: its velocity and spin changed by them. |
physics.pushes@1 |
scatter into input 1 with sum | The pushes the manifolds give each body, summed. |
physics.ray@1 |
map | The nearest body each ray meets: sensors are passed through. |
physics.shared@1 |
scatter into input 1 with sum | How many manifolds push each body, among which its mass is split. |
physics.solve@1 |
map | Each manifold solved against its copies of its bodies: the normal impulses, pushing apart what overlaps unless relax, then friction; with ahead, the impulses it then holds pushed again for the next substep. |
physics.spans@1 |
map | How many cells each body’s box covers. |
physics.warm@1 |
map | Each manifold’s push with by times the impulses it holds: once to warm a step’s first substep, once less to take back the warm its last substep gave a substep that does not come. A pass of its own, so every body is pushed by every manifold before the next pass reads it. |
Methods
Section titled “Methods”Types and structs
Section titled “Types and structs”| Name | Syntax |
|---|---|
BodyShape |
type BodyShape = enum { Circle, Box }; |
Body |
struct Body |
Bounds |
struct Bounds { lo: Vec2; hi: Vec2; first: IVec2; last: IVec2; } |
Pair |
struct Pair { a: Int; b: Int; } |
Counted |
struct Counted { at: Int; value: Int; } |
Contact |
struct Contact |
Manifold |
struct Manifold |
Push |
struct Push { at: Int; value: Vec3; } |
Ray |
struct Ray { origin: Vec2; direction: Vec2; length: Float; mask: Int; } |
Hit |
struct Hit { body: Int; fraction: Float; point: Vec2; normal: Vec2; } |
Touch |
struct Touch { normal: Vec2; count: Int; c1: Vec2; s1: Float; c2: Vec2; s2: Float; } |
Clipped |
struct Clipped { v0: Vec2; v1: Vec2; n: Int; } |
Copy |
struct Copy { velocity: Vec2; spin: Float; mass: Float; inertia: Float; share: Float; } |
Both |
struct Both { a: Copy; b: Copy; } |
Solved |
struct Solved { point: Contact; both: Both; } |
Graph presets
Section titled “Graph presets”| Name | Interface | Description |
|---|---|---|
step |
input bodies: Rows<Body>input held: Rows<Manifold>param dt: Float = 0.0166667param substeps: Int = 8param gravity: Vec2 = vec2(0.0, -10.0)param damping: Float = 0.0param margin: Float = 0.02param hertz: Float = 30.0param ratio: Float = 10.0param speed: Float = 3.0param threshold: Float = 1.0param origin: Vec2 = vec2(-32.0, -32.0)param cell: Float = 1.0param columns: Int = 64param rows: Int = 64param bits: Int = 12output result <- bounced.resultoutput contacts <- bounce.result |
One step of a world of bodies, dt long: node none: physics.no_contacts@1 { domain = 1; } node world: graph “physics.entpkg/graphs/step.esn” { bodies <~ world.result from start.result; held <~ world.contacts from none.result; } result is the bodies stepped and contacts the manifolds that stepped them, whose touching says what touches what; a world is given its last step’s as held, which each step starts from. The grid of columns by rows cells of side cell from origin should cover where the bodies are, a cell about the size of a common body; one outside it is entered in the edge cells. bits is enough for columns * rows, which the graph requires. substeps are the passes a step takes, more for a pile many bodies deep that lands at once; hertz is how stiff a contact is, higher for a deep pile to sink into itself less. A step finds contacts where the bodies are at its start, so a box turning much of a turn in one step (150 radians a second at 30 m/s) may pass through a thin wall a corner swings across. |
substep |
input bodies: Rows<Body>input manifolds: Rows<Manifold>input shared: Rows<Int>input zeros: Rows<Vec3>param dt: Float = 0.0166667param substeps: Int = 8param gravity: Vec2 = vec2(0.0, -10.0)param damping: Float = 0.0param hertz: Float = 30.0param ratio: Float = 10.0param speed: Float = 3.0output moved <- relaxed.resultoutput held <- relax.result |
One substep of step.esn: gravity, the manifolds solved, the bodies moved, and the manifolds solved once more without pushing apart, the impulses they then hold pushed again to warm the next substep. |
Kernel descriptions
Section titled “Kernel descriptions”physics.bounce@1
Section titled “physics.bounce@1”Each manifold’s bounce: the points that closed faster than threshold and push, given back the restitution of what they closed at.
| Mode | map |
| Requires | field.read, field.write |
| Inputs | manifolds: Rows<Manifold>, bodies: Rows<Body>, shared: Rows<Int> |
| Params | threshold: Float = 1.0 |
| Outputs | result: Rows<Manifold> |
| Source | packages/physics.entpkg/kernels/solve.ent |
physics.bounds@1
Section titled “physics.bounds@1”Each body’s box, grown by margin and by how far it may move in the step.
| Mode | map |
| Requires | field.read, field.write |
| Inputs | bodies: Rows<Body> |
| Params | dt: Float = 0.0166667, margin: Float = 0.02, origin: Vec2 = [0.0, 0.0], cell: Float = 1.0, columns: Int = 64, rows: Int = 64 |
| Outputs | result: Rows<Bounds> |
| Source | packages/physics.entpkg/kernels/broad_phase.ent |
physics.cell_counts@1
Section titled “physics.cell_counts@1”How many entries each cell holds.
| Mode | scatter into input 1 with sum |
| Requires | field.read, field.write |
| Inputs | keys: Rows<Int>, zeros: Rows<Int> |
| Params | — |
| Outputs | result: Rows<Int> |
| Source | packages/physics.entpkg/kernels/broad_phase.ent |
physics.cells@1
Section titled “physics.cells@1”The cell each entry is, a body’s cells in rows.
| Mode | map |
| Requires | field.read, field.write |
| Inputs | owners: Rows<Int>, spans: Rows<Int>, ends: Rows<Int>, bounds: Rows<Bounds> |
| Params | columns: Int = 64 |
| Outputs | result: Rows<Int> |
| Source | packages/physics.entpkg/kernels/broad_phase.ent |
physics.collide@1
Section titled “physics.collide@1”Each pair’s manifold. A pair keeps points up to margin apart and as far as the two may close in the step; a sensor’s only where they touch. A point starts from the impulses the pair’s point there held in the last step, held, so a resting stack is pushed as hard as it was a step ago.
| Mode | map |
| Requires | field.read, field.write |
| Inputs | pairs: Rows<Pair>, bodies: Rows<Body>, held: Rows<Manifold> |
| Params | dt: Float = 0.0166667, margin: Float = 0.02 |
| Outputs | result: Rows<Manifold> |
| Source | packages/physics.entpkg/kernels/contact.ent |
physics.fall@1
Section titled “physics.fall@1”Each moving body pulled by gravity for a substep and slowed by damping a second.
| Mode | map |
| Requires | field.read, field.write |
| Inputs | bodies: Rows<Body> |
| Params | dt: Float = 0.0166667, substeps: Int = 8, gravity: Vec2 = [0.0, -10.0], damping: Float = 0.0 |
| Outputs | result: Rows<Body> |
| Source | packages/physics.entpkg/kernels/solve.ent |
physics.move@1
Section titled “physics.move@1”Each body moved by its velocity and turned by its spin for a substep.
| Mode | map |
| Requires | field.read, field.write |
| Inputs | bodies: Rows<Body> |
| Params | dt: Float = 0.0166667, substeps: Int = 8 |
| Outputs | result: Rows<Body> |
| Source | packages/physics.entpkg/kernels/solve.ent |
physics.no_contacts@1
Section titled “physics.no_contacts@1”No manifolds: what a world’s held starts from.
| Mode | map |
| Requires | field.read, field.write |
| Inputs | — |
| Params | — |
| Outputs | result: Rows<Manifold> |
| Source | packages/physics.entpkg/kernels/query.ent |
physics.no_counts@1
Section titled “physics.no_counts@1”A zero for each body.
| Mode | map |
| Requires | field.read, field.write |
| Inputs | bodies: Rows<Body> |
| Params | — |
| Outputs | result: Rows<Int> |
| Source | packages/physics.entpkg/kernels/contact.ent |
physics.no_entries@1
Section titled “physics.no_entries@1”A zero for each entry.
| Mode | map |
| Requires | field.read, field.write |
| Inputs | order: Rows<Int> |
| Params | — |
| Outputs | result: Rows<Int> |
| Source | packages/physics.entpkg/kernels/broad_phase.ent |
physics.no_pairs@1
Section titled “physics.no_pairs@1”Pairs of nothing, to be filled.
| Mode | map |
| Requires | field.read, field.write |
| Inputs | total: Rows<Int> |
| Params | — |
| Outputs | result: Rows<Pair> |
| Source | packages/physics.entpkg/kernels/broad_phase.ent |
physics.no_pushes@1
Section titled “physics.no_pushes@1”No push for each body.
| Mode | map |
| Requires | field.read, field.write |
| Inputs | bodies: Rows<Body> |
| Params | — |
| Outputs | result: Rows<Vec3> |
| Source | packages/physics.entpkg/kernels/contact.ent |
physics.owners@1
Section titled “physics.owners@1”The body each entry is.
| Mode | map |
| Requires | field.read, field.write |
| Inputs | total: Rows<Int>, ends: Rows<Int> |
| Params | — |
| Outputs | result: Rows<Int> |
| Source | packages/physics.entpkg/kernels/broad_phase.ent |
physics.pair_counts@1
Section titled “physics.pair_counts@1”How many pairs each body is the higher of.
| Mode | map |
| Requires | field.read, field.write |
| Inputs | bodies: Rows<Body>, spans: Rows<Int>, span_ends: Rows<Int>, order: Rows<Int>, places: Rows<Int>, keys: Rows<Int>, owners: Rows<Int>, cell_counts: Rows<Int>, cell_ends: Rows<Int>, bounds: Rows<Bounds> |
| Params | columns: Int = 64 |
| Outputs | result: Rows<Int> |
| Source | packages/physics.entpkg/kernels/broad_phase.ent |
physics.pairs@1
Section titled “physics.pairs@1”The pairs, each body’s in its part of the list, so the list is in order of the higher body: the walk physics.pair_counts@1 counts.
| Mode | scatter into input 12 with max |
| Requires | field.read, field.write |
| Inputs | bodies: Rows<Body>, counts: Rows<Int>, ends: Rows<Int>, spans: Rows<Int>, span_ends: Rows<Int>, order: Rows<Int>, places: Rows<Int>, keys: Rows<Int>, owners: Rows<Int>, cell_counts: Rows<Int>, cell_ends: Rows<Int>, bounds: Rows<Bounds>, slots: Rows<Pair> |
| Params | columns: Int = 64 |
| Outputs | result: Rows<Pair> |
| Source | packages/physics.entpkg/kernels/broad_phase.ent |
physics.places@1
Section titled “physics.places@1”Where each entry is in the sorted order.
| Mode | scatter into input 1 with max |
| Requires | field.read, field.write |
| Inputs | order: Rows<Int>, zeros: Rows<Int> |
| Params | — |
| Outputs | result: Rows<Int> |
| Source | packages/physics.entpkg/kernels/broad_phase.ent |
physics.push@1
Section titled “physics.push@1”Each body with its pushes: its velocity and spin changed by them.
| Mode | map |
| Requires | field.read, field.write |
| Inputs | bodies: Rows<Body>, pushes: Rows<Vec3> |
| Params | — |
| Outputs | result: Rows<Body> |
| Source | packages/physics.entpkg/kernels/solve.ent |
physics.pushes@1
Section titled “physics.pushes@1”The pushes the manifolds give each body, summed.
| Mode | scatter into input 1 with sum |
| Requires | field.read, field.write |
| Inputs | manifolds: Rows<Manifold>, zeros: Rows<Vec3> |
| Params | — |
| Outputs | result: Rows<Vec3> |
| Source | packages/physics.entpkg/kernels/solve.ent |
physics.ray@1
Section titled “physics.ray@1”The nearest body each ray meets: sensors are passed through.
| Mode | map |
| Requires | field.read, field.write |
| Inputs | rays: Rows<Ray>, bodies: Rows<Body> |
| Params | — |
| Outputs | result: Rows<Hit> |
| Source | packages/physics.entpkg/kernels/query.ent |
physics.shared@1
Section titled “physics.shared@1”How many manifolds push each body, among which its mass is split.
| Mode | scatter into input 1 with sum |
| Requires | field.read, field.write |
| Inputs | manifolds: Rows<Manifold>, zeros: Rows<Int> |
| Params | — |
| Outputs | result: Rows<Int> |
| Source | packages/physics.entpkg/kernels/contact.ent |
physics.solve@1
Section titled “physics.solve@1”Each manifold solved against its copies of its bodies: the normal impulses, pushing apart what overlaps unless relax, then friction; with ahead, the impulses it then holds pushed again for the next substep.
| Mode | map |
| Requires | field.read, field.write |
| Inputs | manifolds: Rows<Manifold>, bodies: Rows<Body>, shared: Rows<Int> |
| Params | dt: Float = 0.0166667, substeps: Int = 8, relax: Bool = False, ahead: Bool = False, hertz: Float = 30.0, ratio: Float = 10.0, speed: Float = 3.0 |
| Outputs | result: Rows<Manifold> |
| Source | packages/physics.entpkg/kernels/solve.ent |
physics.spans@1
Section titled “physics.spans@1”How many cells each body’s box covers.
| Mode | map |
| Requires | field.read, field.write |
| Inputs | bounds: Rows<Bounds> |
| Params | — |
| Outputs | result: Rows<Int> |
| Source | packages/physics.entpkg/kernels/broad_phase.ent |
physics.warm@1
Section titled “physics.warm@1”Each manifold’s push with by times the impulses it holds: once to warm a step’s first substep, once less to take back the warm its last substep gave a substep that does not come. A pass of its own, so every body is pushed by every manifold before the next pass reads it.
| Mode | map |
| Requires | field.read, field.write |
| Inputs | manifolds: Rows<Manifold>, bodies: Rows<Body>, shared: Rows<Int> |
| Params | by: Float = 1.0 |
| Outputs | result: Rows<Manifold> |
| Source | packages/physics.entpkg/kernels/solve.ent |
many.replay, motion.replay, pile.replay, rest.replay, roll.replay, wide.replay

