torqueCars meshkit: the geometry core the car body and wheel generators are
built on. Pure Luau, deterministic, no engine calls except in `M.write`.
local K = require("torqueCars.meshkit")
local m = K.new()
K.box(m, { center = vector.create(0, 1, 0), half = vector.create(1, .5, 2), round = .1, col = K.C.paint })
local g = K.finalize(m, { angle = 40, normalise = true }) -- { positions, normals, colors, uvs, indices, center, size, tris }
Colours are { r, g, b, partCode } where the part code (alpha) tells the
`carBody` shader which finish to use: 1 paint, .85 glass, .7 chrome,
.55 gloss plastic, .4 trim/rubber, .25 front lamp, .1 tail lamp.
clamp(x: number, a: number, b: number) → number
| arg | type | description |
|---|
| x | number | |
| a | number | |
| b | number | |
lerp(a: number, b: number, t: number) → number return a
| arg | type | description |
|---|
| a | number | |
| b | number | |
| t | number | |
smooth(e0: number, e1: number, x: number) → number
| arg | type | description |
|---|
| e0 | number | |
| e1 | number | |
| x | number | |
tri(m: Mesh, a: vector, b: vector, c: vector, col: any) → void
| arg | type | description |
|---|
| m | Mesh | |
| a | vector | |
| b | vector | |
| c | vector | |
| col | any | |
quad(m: Mesh, a: vector, b: vector, c: vector, d: vector, col: any) → void
a, b, c, d counter-clockwise seen from the front side.
| arg | type | description |
|---|
| m | Mesh | |
| a | vector | |
| b | vector | |
| c | vector | |
| d | vector | |
| col | any | |
quadOut(m: Mesh, a: vector, b: vector, c: vector, d: vector, col: any, out: vector) → void
The same, turned so its front faces `out`.
| arg | type | description |
|---|
| m | Mesh | |
| a | vector | |
| b | vector | |
| c | vector | |
| d | vector | |
| col | any | |
| out | vector | |
triOut(m: Mesh, a: vector, b: vector, c: vector, col: any, out: vector) → void
| arg | type | description |
|---|
| m | Mesh | |
| a | vector | |
| b | vector | |
| c | vector | |
| col | any | |
| out | vector | |
samples(musts: { number }, spacing: number) → void
Sorted samples over [-1, 1] that hit every value in `musts` and fill the
gaps at about `spacing`.
| arg | type | description |
|---|
| musts | { number } | |
| spacing | number | |
bandMusts(list: { number }, r: number, segs: number) → void
Musts that split the rounding band [1-r, 1] into `segs` pieces, both ends.
| arg | type | description |
|---|
| list | { number } | |
| r | number | |
| segs | number | |
roundP(a: number, b: number, c: number, ra: number, rb: number, rc: number) → void
| arg | type | description |
|---|
| a | number | |
| b | number | |
| c | number | |
| ra | number | |
| rb | number | |
| rc | number | |
gridBox(m: Mesh, A: { number }, B: { number }, C: { number }, opts: any) → void
The surface of the cube [-1,1]^3 sampled at A (x), B (y), C (z), rounded by
(ra, rb, rc) in cube units, mapped through opts.map(a, b, c, vert) -> vector,
optionally adjusted by opts.post(verts), and emitted with opts.colour(q)
per quad. q = { face, a, b, c (cube centre), center, normal, verts }.
Vertex records carry .a .b .c (cube), .ra .rb .rc (rounded), .pos, .nb.
| arg | type | description |
|---|
| m | Mesh | |
| A | { number } | |
| B | { number } | |
| C | { number } | |
| opts | any | |
getV(a: number, b: number, c: number) → void
| arg | type | description |
|---|
| a | number | |
| b | number | |
| c | number | |
box(m: Mesh, o: any) → void
A box (optionally rounded, optionally rotated by axes ex/ey/ez).
o: center, half (vector, metres), ex/ey/ez, round (metres), cell (metres),
segs (rounding segments), col (colour or fn(q)).
| arg | type | description |
|---|
| m | Mesh | |
| o | any | |
list(hh: number) → void
| arg | type | description |
|---|
| hh | number | |
map(a: ?, b: ?, c: ?) → void
| arg | type | description |
|---|
| a | ? | |
| b | ? | |
| c | ? | |
frame(dir: vector) → void
A frame (ex, ey, ez) whose ez is `dir`.
| arg | type | description |
|---|
| dir | vector | |
tube(m: Mesh, p0: vector, p1: vector, o: any) → void
A cylinder from p0 to p1. o: r (or r0/r1), sides, col, caps (bool), capCol, phase.
| arg | type | description |
|---|
| m | Mesh | |
| p0 | vector | |
| p1 | vector | |
| o | any | |
tubePath(m: Mesh, pts: { vector }, o: any) → void
A polyline of tubes with matching joints (spheres-free; joints overlap).
| arg | type | description |
|---|
| m | Mesh | |
| pts | { vector } | |
| o | any | |
ellipsoid(m: Mesh, c: vector, rad: vector, o: any) → void
An ellipsoid (or part of one) around c with radii rad in axes ex/ey/ez.
o: segU (around), segV (pole to pole), latMin/latMax (radians), col (colour
or fn(localDir) -> colour), ex/ey/ez.
| arg | type | description |
|---|
| m | Mesh | |
| c | vector | |
| rad | vector | |
| o | any | |
P(i: number, j: number) → void
| arg | type | description |
|---|
| i | number | |
| j | number | |
lathe(m: Mesh, prof: { { number } }, o: any) → void
A surface of revolution around the X axis. prof = { {x, r}, ... } walked
with the outside on the right of the direction of travel in (x, r).
o: seg, col (colour or fn(k, x, r) for the segment k..k+1), phase.
| arg | type | description |
|---|
| m | Mesh | |
| prof | { { number } } | |
| o | any | |
P(x: number, r: number, i: number) → vector
| arg | type | description |
|---|
| x | number | |
| r | number | |
| i | number | |
qk(v: vector, s: number) → string
| arg | type | description |
|---|
| v | vector | |
| s | number | |
finalize(m: Mesh, opts: any) → any
Turn the triangle soup into mesh arrays. opts: flat (face normals), angle
(smoothing threshold in degrees), normalise (fit the unit box and report
center/size in the soup's units).
| arg | type | description |
|---|
| m | Mesh | |
| opts | any | |