跳转到内容
查看源码

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/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.
  • graphs/step.esn — One step of a world of bodies, dt long.
  • graphs/substep.esn — One substep of step.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 执行模式 简述
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.
函数 简述
circle(position: Vec2, radius: Float, density: Float) -> Body A circle of density per unit area; no density makes it static.
box(position: Vec2, half: Vec2, angle: Float, density: Float) -> Body A box of half extents half, turned by angle, of density per unit area; no density makes it static.
touching(m: Manifold, slop: Float) -> Bool Whether a manifold’s bodies touch rather than only close on each other: a point within slop of touching.
turn(v: Vec2, angle: Float) -> Vec2
unturn(v: Vec2, angle: Float) -> Vec2
wedge(a: Vec2, b: Vec2) -> Float
swirl(w: Float, r: Vec2) -> Vec2
arm_angle(b: Body) -> Float
extent(b: Body) -> Float
sweep(b: Body, dt: Float) -> Float
cell_at(p: Vec2, origin: Vec2, cell: Float, columns: Int, rows: Int) -> IVec2
meets(a: Body, b: Body) -> Bool
paired(i: Int, j: Int, c: Int, bodies: Rows<Body>, bounds: Rows<Bounds>, columns: Int) -> Bool
before(e: Int, places: Rows<Int>, keys: Rows<Int>, cell_ends: Rows<Int>, cell_counts: Rows<Int>) -> IVec3
apart() -> Touch
circles(a: Body, b: Body) -> Touch
box_circle(a: Body, b: Body) -> Touch
clip(v0: Vec2, v1: Vec2, normal: Vec2, offset: Float) -> Clipped
incident(h: Vec2, p: Vec2, x: Vec2, y: Vec2, normal: Vec2) -> Clipped
boxes(a: Body, b: Body, margin: Float) -> Touch
touch(a: Body, b: Body, margin: Float) -> Touch
holding(a: Body, b: Body, c: Vec2, s: Float, n: Vec2) -> Contact
last_of(held: Rows<Manifold>, a: Int, b: Int) -> Int
carried(p: Contact, last: Manifold, n: Vec2, near: Float, round: Bool) -> Contact
solid(m: Manifold) -> Bool
ray_circle(o: Vec2, d: Vec2, c: Vec2, r: Float) -> Float
ray_box(o: Vec2, d: Vec2, h: Vec2) -> Vec3
copy_of(b: Body, shared: Rows<Int>, i: Int) -> Copy
pushed(c: Copy, p: Vec2, r: Vec2) -> Copy
closing(both: Both, ra: Vec2, rb: Vec2) -> Vec2
apply(both: Both, p: Vec2, ra: Vec2, rb: Vec2) -> Both
inverse_along(both: Both, ra: Vec2, rb: Vec2, d: Vec2) -> Float
unsplit(both: Both, ra: Vec2, rb: Vec2, d: Vec2) -> Float
softness(h: Float, hertz: Float, ratio: Float) -> Vec3
solve_normal(pt: Contact, both: Both, a: Body, b: Body, n: Vec2, h: Float, relax: Bool, soft: Vec3, speed: Float) -> Solved
solve_tangent(pt: Contact, both: Both, a: Body, b: Body, n: Vec2, friction: Float) -> Solved
warm(pt: Contact, both: Both, a: Body, b: Body, n: Vec2, by: Float) -> Both
warmed(m: Manifold, both: Both, a: Body, b: Body, by: Float) -> Both
bounce(pt: Contact, both: Both, a: Body, b: Body, n: Vec2, e: Float, threshold: Float) -> Solved
settled(m: Manifold, both: Both, a: Body, b: Body) -> Manifold
nothing(m: Manifold) -> Manifold
substep(dt: Float, substeps: Int) -> Float
名称 写法
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.0166667
param substeps: Int = 8
param gravity: Vec2 = vec2(0.0, -10.0)
param damping: Float = 0.0
param margin: Float = 0.02
param hertz: Float = 30.0
param ratio: Float = 10.0
param speed: Float = 3.0
param threshold: Float = 1.0
param origin: Vec2 = vec2(-32.0, -32.0)
param cell: Float = 1.0
param columns: Int = 64
param rows: Int = 64
param bits: Int = 12
output result <- bounced.result
output 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.0166667
param substeps: Int = 8
param gravity: Vec2 = vec2(0.0, -10.0)
param damping: Float = 0.0
param hertz: Float = 30.0
param ratio: Float = 10.0
param speed: Float = 3.0
output moved <- relaxed.result
output 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.

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

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

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

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

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

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

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

No manifolds: what a world’s held starts from.

执行模式 map
需要能力 field.read, field.write
输入 —
参数 —
输出 result: Rows<Manifold>
源码 packages/physics.entpkg/kernels/query.ent

A zero for each body.

执行模式 map
需要能力 field.read, field.write
输入 bodies: Rows<Body>
参数 —
输出 result: Rows<Int>
源码 packages/physics.entpkg/kernels/contact.ent

A zero for each entry.

执行模式 map
需要能力 field.read, field.write
输入 order: Rows<Int>
参数 —
输出 result: Rows<Int>
源码 packages/physics.entpkg/kernels/broad_phase.ent

Pairs of nothing, to be filled.

执行模式 map
需要能力 field.read, field.write
输入 total: Rows<Int>
参数 —
输出 result: Rows<Pair>
源码 packages/physics.entpkg/kernels/broad_phase.ent

No push for each body.

执行模式 map
需要能力 field.read, field.write
输入 bodies: Rows<Body>
参数 —
输出 result: Rows<Vec3>
源码 packages/physics.entpkg/kernels/contact.ent

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

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

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

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

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

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

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

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

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

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

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