geom
An accumulator you push faces into, and the shapes the salt flat is made of. Everything here is pure geometry: it produces flat position / index / normal / uv arrays, and `Geom.upload` hands them to `renderer.mesh.create`.
greensky/pan/geom — mesh building for the pan
An accumulator you push faces into, and the shapes the salt flat is made of.
Everything here is pure geometry: it produces flat position / index / normal
/ uv arrays, and Geom.upload hands them to renderer.mesh.create.
Used only by greensky/pan.
Winding
renderer.mesh.create reads a triangle's front face as the one where
cross(v1 - v0, v2 - v0) points out of it. Geom.quad takes its four
corners in that order and emits (0,1,2) + (0,2,3), so every builder below
states its corners front-face-first and no face needs cull = "none".
The surface
local Geom = require("greensky.pan.geom")
local a = Geom.acc() -- an empty accumulator
Geom.vert(a, x,y,z, nx,ny,nz, u,v) -- one vertex, returns its index
Geom.tri(a, i0, i1, i2)
Geom.quad(a, p0, p1, p2, p3, nx, ny, nz, uvScale) -- a flat quad, planar UVs
Geom.box(a, x0,y0,z0, x1,y1,z1, uvScale, skipBottom?) -- an axis-aligned box
Geom.disc(a, cx, y, cz, radii, segs, uvScale) -- a horizontal disc, ring radii inner to outer
Geom.plate(a, cx, cz, r, y, sides, rot, yBase?, uvScale) -- a flat polygon with an optional skirt
Geom.field(a, cx, cz, sizeX, sizeZ, nx, nz, fn, uvScale) -- a height field, fn(x, z) in world space
Geom.upload(a) -- -> MeshHandle
Geom.stats(a) -- { verts, tris }
Geom.rng(seed) -- :next() 0..1, :range(lo, hi)
uvScale is metres per UV unit. Geom.field takes its normal from four
neighbouring samples of fn, so a wave shades correctly without the caller
differentiating it.
Geom.rng is a plain LCG. The film has to be byte-identical run to run, so
nothing in the pan may reach for math.random.
Note on runtime meshes
A mesh made by renderer.mesh.create from raw geometry is not CPU-resident,
so renderer.mesh.setVertices refuses it — renderer.mesh.update with whole
geometry is the way to change one after the fact, and it costs about 5 ms for
9,400 vertices. The pan builds static geometry once and animates it by moving
and scaling the entity instead.
Scoped to this part · feeds back into the world's score.