Skip to content

Meshes

A Mesh contains one or more primitives (draw calls), each with its own vertex data and material.

local mesh = scene:create_mesh("Box")
mesh:add_primitive({
positions = { 0,0,0, 1,0,0, 1,1,0, 0,1,0 }, -- flat vec3
indices = { 0,1,2, 0,2,3 }, -- triangles
normals = { 0,0,1, 0,0,1, 0,0,1, 0,0,1 }, -- flat vec3 (optional)
uvs = { 0,0, 1,0, 1,1, 0,1 }, -- flat vec2 (optional)
uvs2 = { ... }, -- second UV set (optional)
colors = { 1,0,0,1, 0,1,0,1, 0,0,1,1, 1,1,1,1 }, -- RGBA (optional)
tangents = { ... }, -- flat vec4 (optional, auto-generated)
material = my_material, -- Material reference (optional)
})
-- Attach to a node
node:set_mesh(mesh)

If normals or tangents are omitted, they are generated automatically.

mesh.name -- string (r/w)
mesh:get_primitive_count() -- number
mesh:get_vertex_count() -- total across all primitives
mesh:get_bounds() -- { min = vec3, max = vec3 } axis-aligned bounding box

Add named morph targets (blend shapes) for facial animation or deformation.

mesh:add_morph_target("smile", {
position_deltas = { ... }, -- flat vec3, same vertex count
normal_deltas = { ... }, -- flat vec3 (optional)
})
mesh:get_morph_target_names() -- { "smile", "blink_L", ... }

Control weights on the node:

local face = scene:find_node("Face")
face:set_morph_weight("smile", 0.8)
face:get_morph_weight("smile") -- 0.8
face:get_morph_weights() -- { smile = 0.8, ... }
face:get_morph_target_names() -- { "smile", "blink_L", ... }

Built-in shape generators for quick prototyping:

local box = pl.mesh.box(1, 1, 1) -- width, height, depth
local sphere = pl.mesh.sphere(0.5, 32) -- radius, segments
local plane = pl.mesh.plane(10, 10) -- width, height
local cylinder = pl.mesh.cylinder(0.5, 2, 24) -- radius, height, segments

These return Mesh objects that can be attached to nodes.

For skeletal animation, primitives include joint indices and weights:

mesh:add_primitive({
positions = { ... },
indices = { ... },
joints = { 0,1,0,0, 1,2,0,0, ... }, -- 4 joint indices per vertex (u16)
weights = { 0.8,0.2,0,0, 0.5,0.5,0,0 }, -- 4 weights per vertex (sum = 1.0)
})