trackBuilder/proceduralPrimitives - Procedural 3D Primitive Generators
Reference for `extensions/util/trackBuilder/proceduralPrimitives.lua`. Generates mesh data (vertices, normals, UVs, faces) for primitive 3D shapes used as track obstacles.
Reference for extensions/util/trackBuilder/proceduralPrimitives.lua. Generates mesh data (vertices, normals, UVs, faces) for primitive 3D shapes used as track obstacles.
Exports
| Key | Signature | Description |
|---|---|---|
createRing | (radius, thickness, material?) → mesh | Torus/ring shape |
createCylinder | (radius, height, material?) → mesh | Cylinder with top/bottom caps |
createCube | (size, material?, uvStyle?) → mesh | Box with configurable UV layout |
createCone | (radius, height, material?) → mesh | Cone with flat bottom |
createBump | (length, width, height, upperLength, upperWidth, material?) → mesh | Trapezoidal bump |
createRamp | (width, len, hei, thinning, attack, twist, material?) → mesh | Ramp with configurable taper and curve |
Internals
Mesh Format
All functions return a table with:
verts:{{x,y,z}, ...}- vertex positionsnormals:{{x,y,z}, ...}- normal vectorsuvs:{{u,v}, ...}- texture coordinatesfaces:{{v=idx, n=idx, u=idx}, ...}- triangle faces (0-indexed)material: string - material name (default'track_editor_A_border')
Shape Details
- Ring: Generates a torus by sweeping an inner circle around an outer circle. Segment counts adapt to radius/thickness.
- Cylinder: Side faces, top cap, and bottom cap. UV repeats based on height.
- Ramp: Segmented along length with per-segment thinning and power-curve attack angle. Includes front/back end caps.
- Bump: 8-vertex frustum shape (bottom rect → top rect) with analytical face normals.
- Cone: Radial fan faces converging to apex plus flat bottom cap.
- Cube: Two UV styles available (style 1 = standard, style 2 = rotated side UVs).
The module also contains an unexported createIcosphere function for debugging (creates and registers a ProceduralMesh directly).
How It Works
Each generator computes geometry analytically, with adaptive segment counts clamped to reasonable ranges. The mesh tables are consumed by ProceduralMesh:createMesh().
local prims = require('util/trackBuilder/proceduralPrimitives')
-- Create a ring obstacle
local ringMesh = prims.createRing(2, 0.5, 'track_editor_A_border')
-- Create a ramp: 5m wide, 10m long, 2m high, slight taper
local rampMesh = prims.createRamp(5, 10, 2, 0.5, 1.5, 0, 'track_editor_B_border')
-- Use with ProceduralMesh
local proc = createObject("ProceduralMesh")
proc:registerObject('myObstacle')
proc:createMesh({{ringMesh}})Additional Exports
M.createBump- (undocumented)M.createCone- (undocumented)M.createCube- (undocumented)M.createCylinder- (undocumented)M.createRamp- (undocumented)M.createRing- (undocumented)
trackBuilder/pieces - Track Piece Geometry Generation
Reference for `extensions/util/trackBuilder/pieces.lua`. Converts abstract track piece descriptions (forward, curve, spiral, loop, bezier) into concrete segment data with positions, headings, and cont
trackBuilder/quickraceSetup - Quick Race Track Loader
Reference for `extensions/util/trackBuilder/quickraceSetup.lua`. Loads a saved track and sets up checkpoints/vehicle positioning when a quick race scenario starts.