pgmesh
The rockhopper's geometry, written as numbers. Four builders make every part of the bird and hand back flat-array `Geom` tables — the shape `renderer.mesh.create` and `asset.create("mesh", ...)` both take, with smooth normals accumulated from the faces and UVs that run around a p…
pgmesh
The rockhopper's geometry, written as numbers. Four builders make every part of
the bird and hand back flat-array Geom tables — the shape
renderer.mesh.create and asset.create("mesh", ...) both take, with smooth
normals accumulated from the faces and UVs that run around a part in u and
along it in v.
Nothing here touches engine state, spawns anything or draws anything. It is
arithmetic. luteway.penguin.pgart turns what it returns into live meshes,
paints the wear maps against these UVs, and hangs the parts on an entity.
Exports
M.builder() -> Builder,M.vert,M.tri,M.quad,M.finish(b) -> Geom— the accumulator every builder is written on.finishcomputes the smooth normals.M.lathe(rings, segments) -> Geom— a profile swept about Y. A ring'sarcis its HALF angle measured from+Z(the direction the bird faces):math.picloses the ring, anything less leaves an open patch, which is how the white bib narrows towards the throat.zoff,rxandrzmove and squash a ring.M.ribbon(spec) -> Geom— a tapered blade swept along a curve, with thickness. The crest plumes and the yellow brow.M.lens(spec) -> Geom— an elliptical cross-section swept down a curve. The flippers and the white trailing margin on them.M.prism(outline, thickness) -> Geom— a flat outline in the XZ plane given thickness in Y. The webbed feet and the tail fan. The outline runs clockwise plotted with X right and Z up, so the top face's normal points at+Y.M.noise2/M.noise3/M.fbm2— deterministic value noise. Every intermediate stays inside 2^53, so the same numbers come out on every machine and every boot.M.roughen(g, amp, freq)/M.renormalize(g)— displace along the normals, then rebuild them. The hash reads the position, so two vertices standing at the same point (a UV seam) move together and the surface stays welded.M.sampleProfile(rings, y)— a profile's radius at an arbitrary height, which is how the bib finds the body it sits a hair outside of.M.penguin() -> { [string]: Geom }— every mesh the bird is made of:body,belly,head,beak,billrim,eye,pupil,brow,plume,flipper,flipperEdge,foot,shank,tail,lute.M.ANCHOR— where each part hangs.pgartbuilds the entity tree from it, so the geometry and the rig cannot drift apart.
Usage
local PM = require("luteway.penguin.pgmesh")
local parts = PM.penguin()
local handle = renderer.mesh.create(parts.body)
entity.find("bird").component.add("Model", { model = handle, material = "…" })
Notes
- Feet at
y = 0, facing+Z, symmetric about X. About 1.05 units to the crown and 0.63 across the shoulders — the size the bird stands at in the game. - The bill is built up its own
+Yand stood forward by a 90 degree pitch on the rig, so a positivezoffon a bill ring is the hook bending DOWN. - Building every part costs about 60 ms once.
pgartcaches the result for the session.
Scoped to this part · feeds back into the world's score.