physics自动生成
分类:包 · 清单:use "kernels/";
平面上的刚体圆与盒子:下落、碰撞、静止、滑动、弹跳;网格宽相与子步求解。
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.
Kernel
Section titled “Kernel”| Kernel | 执行模式 | 简述 |
|---|---|---|
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. |
类型与结构体
Section titled “类型与结构体”| 名称 | 写法 |
|---|---|
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; } |
| 名称 | 接口 | 说明 |
|---|---|---|
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 说明
Section titled “Kernel 说明”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.
| 执行模式 | map |
| 需要能力 | field.read, field.write |
| 输入 | manifolds: Rows<Manifold>, bodies: Rows<Body>, shared: Rows<Int> |
| 参数 | threshold: Float = 1.0 |
| 输出 | result: Rows<Manifold> |
| 源码 | 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.
| 执行模式 | map |
| 需要能力 | field.read, field.write |
| 输入 | bodies: Rows<Body> |
| 参数 | dt: Float = 0.0166667, margin: Float = 0.02, origin: Vec2 = [0.0, 0.0], cell: Float = 1.0, columns: Int = 64, rows: Int = 64 |
| 输出 | result: Rows<Bounds> |
| 源码 | packages/physics.entpkg/kernels/broad_phase.ent |
physics.cell_counts@1
Section titled “physics.cell_counts@1”How many entries each cell holds.
| 执行模式 | scatter into input 1 with sum |
| 需要能力 | field.read, field.write |
| 输入 | keys: Rows<Int>, zeros: Rows<Int> |
| 参数 | — |
| 输出 | result: Rows<Int> |
| 源码 | 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.
| 执行模式 | map |
| 需要能力 | field.read, field.write |
| 输入 | owners: Rows<Int>, spans: Rows<Int>, ends: Rows<Int>, bounds: Rows<Bounds> |
| 参数 | columns: Int = 64 |
| 输出 | result: Rows<Int> |
| 源码 | 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.
| 执行模式 | map |
| 需要能力 | field.read, field.write |
| 输入 | pairs: Rows<Pair>, bodies: Rows<Body>, held: Rows<Manifold> |
| 参数 | dt: Float = 0.0166667, margin: Float = 0.02 |
| 输出 | result: Rows<Manifold> |
| 源码 | 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.
| 执行模式 | map |
| 需要能力 | field.read, field.write |
| 输入 | bodies: Rows<Body> |
| 参数 | dt: Float = 0.0166667, substeps: Int = 8, gravity: Vec2 = [0.0, -10.0], damping: Float = 0.0 |
| 输出 | result: Rows<Body> |
| 源码 | 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.
| 执行模式 | map |
| 需要能力 | field.read, field.write |
| 输入 | bodies: Rows<Body> |
| 参数 | dt: Float = 0.0166667, substeps: Int = 8 |
| 输出 | result: Rows<Body> |
| 源码 | 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.
| 执行模式 | map |
| 需要能力 | field.read, field.write |
| 输入 | — |
| 参数 | — |
| 输出 | result: Rows<Manifold> |
| 源码 | packages/physics.entpkg/kernels/query.ent |
physics.no_counts@1
Section titled “physics.no_counts@1”A zero for each body.
| 执行模式 | map |
| 需要能力 | field.read, field.write |
| 输入 | bodies: Rows<Body> |
| 参数 | — |
| 输出 | result: Rows<Int> |
| 源码 | packages/physics.entpkg/kernels/contact.ent |
physics.no_entries@1
Section titled “physics.no_entries@1”A zero for each entry.
| 执行模式 | map |
| 需要能力 | field.read, field.write |
| 输入 | order: Rows<Int> |
| 参数 | — |
| 输出 | result: Rows<Int> |
| 源码 | packages/physics.entpkg/kernels/broad_phase.ent |
physics.no_pairs@1
Section titled “physics.no_pairs@1”Pairs of nothing, to be filled.
| 执行模式 | map |
| 需要能力 | field.read, field.write |
| 输入 | total: Rows<Int> |
| 参数 | — |
| 输出 | result: Rows<Pair> |
| 源码 | packages/physics.entpkg/kernels/broad_phase.ent |
physics.no_pushes@1
Section titled “physics.no_pushes@1”No push for each body.
| 执行模式 | map |
| 需要能力 | field.read, field.write |
| 输入 | bodies: Rows<Body> |
| 参数 | — |
| 输出 | result: Rows<Vec3> |
| 源码 | packages/physics.entpkg/kernels/contact.ent |
physics.owners@1
Section titled “physics.owners@1”The body each entry is.
| 执行模式 | map |
| 需要能力 | field.read, field.write |
| 输入 | total: Rows<Int>, ends: Rows<Int> |
| 参数 | — |
| 输出 | result: Rows<Int> |
| 源码 | 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.
| 执行模式 | map |
| 需要能力 | field.read, field.write |
| 输入 | 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> |
| 参数 | columns: Int = 64 |
| 输出 | result: Rows<Int> |
| 源码 | 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.
| 执行模式 | scatter into input 12 with max |
| 需要能力 | field.read, field.write |
| 输入 | 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> |
| 参数 | columns: Int = 64 |
| 输出 | result: Rows<Pair> |
| 源码 | packages/physics.entpkg/kernels/broad_phase.ent |
physics.places@1
Section titled “physics.places@1”Where each entry is in the sorted order.
| 执行模式 | scatter into input 1 with max |
| 需要能力 | field.read, field.write |
| 输入 | order: Rows<Int>, zeros: Rows<Int> |
| 参数 | — |
| 输出 | result: Rows<Int> |
| 源码 | 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.
| 执行模式 | map |
| 需要能力 | field.read, field.write |
| 输入 | bodies: Rows<Body>, pushes: Rows<Vec3> |
| 参数 | — |
| 输出 | result: Rows<Body> |
| 源码 | packages/physics.entpkg/kernels/solve.ent |
physics.pushes@1
Section titled “physics.pushes@1”The pushes the manifolds give each body, summed.
| 执行模式 | scatter into input 1 with sum |
| 需要能力 | field.read, field.write |
| 输入 | manifolds: Rows<Manifold>, zeros: Rows<Vec3> |
| 参数 | — |
| 输出 | result: Rows<Vec3> |
| 源码 | packages/physics.entpkg/kernels/solve.ent |
physics.ray@1
Section titled “physics.ray@1”The nearest body each ray meets: sensors are passed through.
| 执行模式 | map |
| 需要能力 | field.read, field.write |
| 输入 | rays: Rows<Ray>, bodies: Rows<Body> |
| 参数 | — |
| 输出 | result: Rows<Hit> |
| 源码 | 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.
| 执行模式 | scatter into input 1 with sum |
| 需要能力 | field.read, field.write |
| 输入 | manifolds: Rows<Manifold>, zeros: Rows<Int> |
| 参数 | — |
| 输出 | result: Rows<Int> |
| 源码 | 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.
| 执行模式 | map |
| 需要能力 | field.read, field.write |
| 输入 | manifolds: Rows<Manifold>, bodies: Rows<Body>, shared: Rows<Int> |
| 参数 | 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 |
| 输出 | result: Rows<Manifold> |
| 源码 | packages/physics.entpkg/kernels/solve.ent |
physics.spans@1
Section titled “physics.spans@1”How many cells each body’s box covers.
| 执行模式 | map |
| 需要能力 | field.read, field.write |
| 输入 | bounds: Rows<Bounds> |
| 参数 | — |
| 输出 | result: Rows<Int> |
| 源码 | 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.
| 执行模式 | map |
| 需要能力 | field.read, field.write |
| 输入 | manifolds: Rows<Manifold>, bodies: Rows<Body>, shared: Rows<Int> |
| 参数 | by: Float = 1.0 |
| 输出 | result: Rows<Manifold> |
| 源码 | packages/physics.entpkg/kernels/solve.ent |
many.replay, motion.replay, pile.replay, rest.replay, roll.replay, wide.replay

