Mesh — a small merged-geometry builder for the hillside of FIRST LIGHT.
Every dressed thing on the hill (the dry-stone courses, the tilled beds,
the crop tufts, the shrine, the ridge) is stamped out of a handful of
primitives into ONE vertex buffer with a colour baked per vertex, and
handed to `renderer.mesh.create` as a single runtime mesh. The paint is in
the vertices, so the whole hill wears two or three materials rather than a
hundred, and every stone can still be its own colour.
local Mesh = require("game.world.Mesh")
local b = Mesh.new()
Mesh.box(b, 0, 0, 0, 1, 1, 1, 0, { 0.5, 0.4, 0.3 })
local handle = renderer.mesh.create(Mesh.geometry(b))
Winding: a face is wound counter-clockwise seen from the side its normal
points at, which is the side the engine draws.
new( ) → Builder
A fresh, empty builder.
vertexCount(b: Builder) → number
How many vertices the builder holds.
| arg | type | description |
|---|
| b | Builder | |
geometry(b: Builder) → void
The flat-array geometry `renderer.mesh.create` and `asset.create("mesh", …)`
both take. Nil when nothing was stamped, so a caller never builds an empty
mesh by accident.
| arg | type | description |
|---|
| b | Builder | |
hash(a: number, b: number, c: number) → number
Deterministic noise. The hill has to look the same on every machine and
after every reload, so nothing here reads `math.random`.
A stable 0..1 value for an integer triple.
| arg | type | description |
|---|
| a | number | |
| b | number | |
| c | number | |
signedHash(a: number, b: number, c: number) → number
A stable value in [-1, 1].
| arg | type | description |
|---|
| a | number | |
| b | number | |
| c | number | |
jitter(c: Color, amount: number, a: number, b: number, d: number) → Color
Multiply a colour by a stable per-position jitter — the painted variation
that keeps a hundred identical stones from reading as one flat plane.
| arg | type | description |
|---|
| c | Color | |
| amount | number | |
| a | number | |
| b | number | |
| d | number | |
mix(a: Color, b: Color, t: number) → Color
Blend two colours, `t` 0 → `a`, 1 → `b`.
| arg | type | description |
|---|
| a | Color | |
| b | Color | |
| t | number | |
pushVertex(b: Builder, x: number, y: number, z: number, nx: number, ny: number, nz: number, u: number, v: number, c: Color) → void
Primitives
| arg | type | description |
|---|
| b | Builder | |
| x | number | |
| y | number | |
| z | number | |
| nx | number | |
| ny | number | |
| nz | number | |
| u | number | |
| v | number | |
| c | Color | |
quad(b: Builder, p1: { number }, p2: { number }, p3: { number }, p4: { number }, c1: Color, c2: Color?, c3: Color?, c4: Color?) → void
One quad from four world-space corners given counter-clockwise seen from
the front. Each corner takes its own colour, so a face can carry a gradient.
| arg | type | description |
|---|
| b | Builder | |
| p1 | { number } | |
| p2 | { number } | |
| p3 | { number } | |
| p4 | { number } | |
| c1 | Color | |
| c2 | Color? | |
| c3 | Color? | |
| c4 | Color? | |
quad2(b: Builder, p1: { number }, p2: { number }, p3: { number }, p4: { number }, c1: Color, c2: Color?, c3: Color?, c4: Color?) → void
The same quad drawn from both sides — for a leaf, a blade or a mist card,
where back-face culling would otherwise leave half of it missing.
| arg | type | description |
|---|
| b | Builder | |
| p1 | { number } | |
| p2 | { number } | |
| p3 | { number } | |
| p4 | { number } | |
| c1 | Color | |
| c2 | Color? | |
| c3 | Color? | |
| c4 | Color? | |
rotY(x: number, z: number, yaw: number) → void
| arg | type | description |
|---|
| x | number | |
| z | number | |
| yaw | number | |
pt(sx: number, sz: number, y: number) → void
| arg | type | description |
|---|
| sx | number | |
| sz | number | |
| y | number | |
box(b: Builder, cx: number, cy: number, cz: number, sx: number, sy: number, sz: number, yaw: number, c: Color) → void
An axis-aligned box on a base centre, with a flat colour on top and a
slightly darker one down the sides.
| arg | type | description |
|---|
| b | Builder | |
| cx | number | |
| cy | number | |
| cz | number | |
| sx | number | |
| sy | number | |
| sz | number | |
| yaw | number | |
| c | Color | |
stone(b: Builder, cx: number, cy: number, cz: number, w: number, h: number, d: number, yaw: number, c: Color) → void
A rounded stone: a squat frustum whose top is pulled in, with the whole
thing leaned by a small angle so a course of them never reads as a row of
bricks.
| arg | type | description |
|---|
| b | Builder | |
| cx | number | |
| cy | number | |
| cz | number | |
| w | number | |
| h | number | |
| d | number | |
| yaw | number | |
| c | Color | |
pyramid(b: Builder, cx: number, cy: number, cz: number, w: number, h: number, d: number, yaw: number, c: Color) → void
A four-sided pyramid on a base centre — a roof, a finial, a cairn top.
| arg | type | description |
|---|
| b | Builder | |
| cx | number | |
| cy | number | |
| cz | number | |
| w | number | |
| h | number | |
| d | number | |
| yaw | number | |
| c | Color | |
pt(sx: number, sz: number, y: number) → void
| arg | type | description |
|---|
| sx | number | |
| sz | number | |
| y | number | |
face(p: { number }, q: { number }, cp: Color, cq: Color) → void
q before p: wound the other way round the base ring, every side of the
pyramid points its normal inward and the whole roof culls from outside.
| arg | type | description |
|---|
| p | { number } | |
| q | { number } | |
| cp | Color | |
| cq | Color | |
blade(b: Builder, x: number, y: number, z: number, h: number, w: number, leanX: number, leanZ: number, bottom: Color, top: Color) → void
One blade of a crop: a tapered, double-sided strip leaning out of the
soil. `lean` is how far the tip drifts from the base, in metres.
| arg | type | description |
|---|
| b | Builder | |
| x | number | |
| y | number | |
| z | number | |
| h | number | |
| w | number | |
| leanX | number | |
| leanZ | number | |
| bottom | Color | |
| top | Color | |
head(b: Builder, x: number, y: number, z: number, h: number, w: number, c: Color) → void
A grain head: a small spindle of four leaves at the top of a stem.
| arg | type | description |
|---|
| b | Builder | |
| x | number | |
| y | number | |
| z | number | |
| h | number | |
| w | number | |
| c | Color | |
card(b: Builder, cx: number, cy: number, cz: number, w: number, d: number, c: Color, edge: Color) → void
A horizontal card in the XZ plane, drawn from both sides — for mist.
| arg | type | description |
|---|
| b | Builder | |
| cx | number | |
| cy | number | |
| cz | number | |
| w | number | |
| d | number | |
| c | Color | |
| edge | Color | |
ridge(b: Builder, x0: number, x1: number, z: number, baseY: number, heights: { number }, top: Color, bottom: Color) → void
A ridgeline: a run of triangles along X whose top follows `heights`,
dropping to `baseY`. The silhouette on the far side of the valley.
| arg | type | description |
|---|
| b | Builder | |
| x0 | number | |
| x1 | number | |
| z | number | |
| baseY | number | |
| heights | { number } | |
| top | Color | |
| bottom | Color | |