LeCodesdocs

Mesh

A renderable 3D node built from raw geometry — the primitive shapes (Mesh.box(), Mesh.sphere(), …) and Mesh.from() for a custom Geometry. Extends Node, so the full transform, hierarchy, events, and aspect surface apply. A GLB import is a different kind of node — see Model.load.

At a glance

TypeScript
const scene = new Scene()

const ground = Mesh.plane({
  material: Material.lit({ color: '#556655' }),
  normal: [0, 1, 0],                    // face up
  scale: 20,
  receiveShadows: true,
})
const crate = Mesh.box({
  material: Material.lit({ color: '#b5854b' }),
  size: [1, 1, 1],
  position: [0, 0.5, 0],
  castShadows: true,
})
scene.add(ground, crate)
scene.open()

Primitive factories

All factories share the same base options and return a ready Mesh:

TypeScript
type MeshOptions = {
  material?: Material          // default Material.unlit()
  position?: Vec3Like
  eulerAngles?: Vec3Like       // degrees
  scale?: Vec3Like | number    // number = uniform
  name?: string
  castShadows?: boolean
  receiveShadows?: boolean
}

Mesh.box(options?: MeshOptions & {
  size?: Vec3Like | number     // full edge lengths in world units; default 1 (unit cube)
})
Mesh.sphere(options?: MeshOptions & {
  radius?: number              // default 0.5 (unit diameter)
  widthSegments?: number       // default 32
  heightSegments?: number      // default 32
})
Mesh.cylinder(options?: MeshOptions & {
  radius?: number              // default 0.5; height is fixed at 1 (Y: -0.5..0.5)
  radiusTop?: number           // default = radius (cone: set 0)
  radiusBottom?: number        // default = radius
  edges?: number               // default 32
  smooth?: boolean             // default true — smooth side normals; false = faceted
})
Mesh.plane(options?: MeshOptions & {
  normal?: Vec3Like            // which way the 1×1 quad faces; default [0, 0, 1] (toward the camera)
})
  • Defaults are unit-sized: box 1×1×1, sphere diameter 1, cylinder height 1 / diameter 1, plane 1×1. Size them with size (box) or scale.
  • box.size is baked into the geometry buffers; scale is a node transform. Both draw the same, but a baked size is what the Shape auto-box measures — either works, since the auto-box also multiplies by world scale.
Note

a ground plane needs normal: [0, 1, 0] — the default quad stands upright facing +Z.

Custom geometry

TypeScript
new Mesh(geometry?: Geometry, material?: Material)
Mesh.from(geometry: Geometry, options?: MeshOptions): Mesh

Geometry holds raw buffers (vertices, normals, indices, uv). Build one from the primitive builders (Geometry.box(), .sphere(opts), .cylinder(opts), .plane(opts) — same options as the factories above) and reshape it, or construct it from your own Float32Arrays:

TypeScript
const geo = Geometry.cylinder({ radiusTop: 0, edges: 6 })   // a hex cone
  .scale(1, 3, 1)                                           // mutates the vertex buffer
  .translate(0, 1.5, 0)                                     // move the pivot to the base
const spike = Mesh.from(geo, { material, position: [2, 0, 0] })

geometry.kind = 'triangles' | 'edges' | 'vertices' switches the draw mode (wireframe / point cloud). Set it before constructing the Mesh.

TypeScript
mesh.geometry   // Geometry | undefined — the buffers this mesh was built from

The geometry getter is what Shape's auto-box measures for a collision shape (see physics).

Materials

TypeScript
mesh.material                                  // slot 0 — get/set
mesh.setMaterial(material, index = 0): this    // chainable, any slot
mesh.getMaterial(index = 0): Material | null   // null if the slot is empty

Primitives have one material slot. Passing no material to a factory gives a default Material.unlit() (flat, unlit, no lighting response). See Material.

Render flags

TypeScript
mesh.castShadows = true      // write-only
mesh.receiveShadows = true   // write-only
mesh.culling = false         // write-only; disable frustum culling (always draw)
Note

these are setters only — there is no readback. Set them at creation (the factory options) or keep your own flag.

Pitfalls

TypeScript
// ✗ expecting the plane to lie flat by default
Mesh.plane({ scale: 10 })                      // stands upright, facing +Z
// ✓ point the normal up for a floor
Mesh.plane({ scale: 10, normal: [0, 1, 0] })

// ✗ mutating a transform copy (value semantics — see conventions)
crate.position.y = 2
// ✓
crate.y = 2

See also

  • Node — transform, hierarchy, events (inherited)
  • Material — lit/unlit/video materials
  • Model — GLB imports (the other renderable node kind)
  • Physics & shapesShape auto-boxes from mesh.geometry
  • Conventions — units, degrees, value semantics