craterGeo
The crater as numbers. Every piece of geometry the place is made of, generated from a profile curve in (radius, height) swept around and pushed out of true by a warp field — the bowl and its five terraces, the retaining wall that holds each one up, the sunken pool and its steps,…
craterGeo
The crater as numbers. Every piece of geometry the place is made of, generated from a profile curve in (radius, height) swept around and pushed out of true by a warp field — the bowl and its five terraces, the retaining wall that holds each one up, the sunken pool and its steps, the natural crater wall and the rim, the ash mantle, the stone channels, and the rubble.
Nothing here touches the world. Every function returns flat geometry arrays in
the shape asset.create("mesh", …) takes, so the whole place can be built,
inspected and re-cut without a scene.
local geo = require("ashbloom.crater.craterGeo")
local bowl = geo.geometry(geo.bowl()) -- positions/indices/normals/uvs/colors
local y = geo.groundY(23.4, -0.35) -- the first terrace
local p = geo.surfaceAt(12.6, 2.16) -- a point on the garden floor
Where the ground is
groundY(r, th) and surfaceAt(r, th) read the same profile and the same warp
the meshes were cut from, so anything they place sits ON the stone. The garden's
plants, the effects' emitters and any camera set-up that must not end up inside
the rock ask here rather than guessing a height — a shot whose camera is inside
geometry renders a flat single-colour frame that every read-back reports as
correct.
Vertex colours carry meaning
The sweep writes what each surface IS into the mesh's colour channel, and both crater shaders read it back:
| channel | means |
|---|---|
r | ash affinity — 1 where ash can lie, 0 on a vertical face |
g | masonry — 1 on built stonework, 0 on natural rock |
b | height — 0 at the garden floor, 1 at the crater rim |
The warp
A crater is not a lathe. warp(r, y, th) pushes the radius and the height of
every ring around by a slowly-turning field whose amplitude grows with the
radius: the built terraces stay nearly true, the wall above them is ribbed and
gullied, and the crest is ragged enough to read as a silhouette. Both are pure
functions of the NOMINAL radius, which is what keeps a retaining wall plumb —
its foot and its top course share a radius and are therefore pushed identically.
The numbers
SEG 132 · RIM_RADIUS 96 · RIM_HEIGHT 34 · POOL_RADIUS 11 ·
POOL_BOTTOM −2.2 · FLOOR_RADIUS 14 · TERRACES {14, 2.6} {28.8, 5.8}
{43.6, 9.0} {58.4, 12.6} {73.2, 16.6} · TERRACE_OUTER 88 · ASH_DEPTH 0.34.
Scoped to this part · feeds back into the world's score.