Geom
The small geometry kitchen the fire temple is cut from. Pure functions that return raw geometry — flat `positions` / `indices` / `normals` / `uvs` arrays, exactly the shape `asset.create("mesh", name, g)` takes — so the meshes under `game/temple/meshes` can be re-cut from source…
Geom
The small geometry kitchen the fire temple is cut from. Pure functions that
return raw geometry — flat positions / indices / normals / uvs arrays,
exactly the shape asset.create("mesh", name, g) takes — so the meshes under
game/temple/meshes can be re-cut from source at any time.
local Geom = require("game.temple.Geom")
asset.create("mesh", "bowl", {
folder = "game/temple/meshes",
positions = g.positions, indices = g.indices, normals = g.normals, uvs = g.uvs,
})
What it makes
| Call | Shape |
|---|---|
Geom.lathe(profile, opts) | anything turned about +Y — the stepped plateau and its ridge skirt, brazier bowls, fluted altar drums, the well's bronze collar, votive jars, torch cups |
Geom.block(w, h, d, opts) | a cut stone: a box that tapers toward its top with its corners pushed around, so a wall of them never repeats |
Geom.rock(radius, seed, rough) | a boulder — the lathe with its radius roughened and every face left flat, so each plane catches the ember light differently |
Geom.smoothNormals(positions, indices) | area-weighted vertex normals; a degenerate triangle contributes nothing |
Geom.facet(geometry) | split every triangle onto its own vertices and give each the face's own normal |
Geom.rng(seed) | a deterministic stream, so the same seed cuts the same stone on every machine and every rebuild |
The profile convention
A profile is a list of { radius, y } turned about +Y. The normal a segment
gets is (dy, -dr) read in the (radial, y) plane, so a closed solid is
written by walking the silhouette anticlockwise in that half-plane: start on the
axis at the bottom, run OUTWARD along the underside, climb the outer wall, then
run back INWARD across the top. Written that way every face points out of the
solid and nothing needs a cap.
-- a brazier bowl: up the outside, over the lip, down the inside
Geom.lathe({
{ 0.00, 0.00 }, { 1.30, 0.02 }, { 1.55, 0.30 }, { 1.62, 0.62 },
{ 1.66, 0.74 }, { 1.50, 0.80 }, { 1.38, 0.72 }, { 1.20, 0.34 },
{ 0.55, 0.20 }, { 0.00, 0.18 },
}, { segments = 44 })
opts carries segments, flutes + fluteDepth (a cosine channel cut round
the circumference — the altar drums), jitter and yJitter (radius and height
roughening, keyed off the ring and segment indices so both ends of the seam
agree), seed, and flat to facet the result.
Scoped to this part · feeds back into the world's score.