LeCodesdocs

Geometry

Raw mesh data — vertex, normal, index and UV buffers — plus the primitive builders behind Mesh.box() and friends. Reach for it to tweak a primitive before wrapping it (scale, shifted pivot, tiled UVs) or to build fully procedural meshes. A Geometry renders via Mesh.from(); it is not a node itself.

At a glance

TypeScript
// a box whose pivot is at its BOTTOM face (so y = 0 puts it on the floor)
const geo = Geometry.box().scale(1, 2, 1).translate(0, 1, 0)
const pillar = Mesh.from(geo, { material: Material.lit({ color: '#ccc' }) })
scene.add(pillar)

Primitives

TypeScript
Geometry.box(): Geometry                       // unit cube, centered on the origin
Geometry.sphere(options?: {
  radius?: number          // default 0.5
  widthSegments?: number   // default 32
  heightSegments?: number  // default 32
}): Geometry
Geometry.cylinder(options?: {
  radius?: number          // default 0.5 (both caps)
  radiusTop?: number       // default = radius (0 makes a cone)
  radiusBottom?: number    // default = radius
  edges?: number           // default 32
  smooth?: boolean         // default true — smooth side normals; false = faceted
}): Geometry
Geometry.plane(options?: {
  normal?: Vec3Like        // facing direction; default [0, 0, 1]
}): Geometry

All primitives are unit-sized (1 world unit ≈ 1 m across, height 1 for the cylinder), centered on the origin, with normals and UVs filled in. The plane is a 1×1 quad perpendicular to normal.

Buffers

TypeScript
geo.vertices   // Float32Array — x,y,z triplets
geo.normals    // Float32Array — x,y,z triplets (per vertex)
geo.indices    // Uint16Array — triangle (or edge/point) indices
geo.uv         // Float32Array — u,v pairs (per vertex)

new Geometry(vertices, normals, indices, uv)

Build procedural meshes by filling the buffers yourself and constructing directly.

Note

indices are Uint16Array, so a single geometry tops out at 65 536 vertices.

Transforming the data

TypeScript
geo.translate(x, y, z): this     // shift every vertex — moves the pivot
geo.scale(x, y, z): this         // scale every vertex
geo.scaleUV(x, y): this          // tile/stretch the texture coordinates

These mutate the buffers in place (chainable). Baking a transform into the geometry is different from node.scale: physics shapes and child transforms see the baked size, and normals are not recomputed — non-uniform scale skews lighting slightly.

Draw mode

TypeScript
geo.kind = 'triangles' | 'edges' | 'vertices'    // default 'triangles' (write-only)

'edges' renders the index pairs as lines, 'vertices' as points — for wireframe/debug looks.

Pitfalls

TypeScript
// ✗ editing a Geometry after a Mesh was built from it
mesh.geometry.translate(0, 1, 0)     // buffers already uploaded — the mesh doesn't change
// ✓ finish the geometry first, then Mesh.from(geo)

See also

  • MeshMesh.from(geometry) and the primitive factory shortcuts
  • Material — what the surface looks like
  • 3D physics & shapes — auto-shapes read the node's geometry