gltf
stableBuild and inspect glTF/GLB 3D scene data: parse binary headers, create meshes, materials, nodes, and 4x4 transform matrices.
use plugin gltf::{parse_gltf_header, create_mesh, create_material, …} Functions (13)
- parse_gltf_header Parse magic, version, length from GLB bytes
- create_mesh Build a mesh descriptor from vertices and indices
- create_material Build a PBR material descriptor
- transform_identity Return a 4x4 identity matrix
- parse_glb_chunks List JSON and BIN chunks inside a GLB file
- create_node Build a scene node with optional transform and mesh
- create_scene Build a scene descriptor from a name and node list
- create_accessor_info Build a glTF accessor descriptor
- create_buffer_view Build a glTF bufferView descriptor
- transform_translate Build a translation matrix
- transform_scale Build a scale matrix
- transform_rotate_y Build a Y-axis rotation matrix
- multiply_transforms Multiply two 4x4 column-major matrices
Overview
gltf is a toolkit for constructing and inspecting glTF/GLB 3D scene data
without pulling in a full asset library. Every builder function returns a plain
table that mirrors the glTF JSON schema (nodes, scenes, meshes, materials,
accessors, bufferViews), so the values are easy to inspect, serialize, or feed
into a renderer. There is no hidden state or opaque handle: a transform is just a
16-element table holding a column-major 4x4 matrix, and a mesh is a table of
counts plus flat vertex and index lists.
Reach for it in two situations: when you need to read the binary structure of a
.glb file (parse_gltf_header and parse_glb_chunks decode the magic, version,
and JSON/BIN chunk layout), and when you are assembling scene data by hand. The
transform_* and multiply_transforms helpers let you compose translation,
rotation, and scale into a single matrix that you can attach to a node.
Common patterns
Build a mesh, wrap it in a node, and collect the nodes into a scene:
use plugin gltf::{create_mesh, create_node, create_scene}
let verts = [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.5, 1.0, 0.0]
let mesh = create_mesh(verts, [0, 1, 2])
let node = create_node("Triangle", [0.0, 0.0, 0.0], nil, [1.0, 1.0, 1.0], 0)
let scene = create_scene("Main", [node])
print("{scene["name"]} has a mesh with {mesh["vertex_count"]} vertices")
Compose a transform by multiplying translate, rotate, and scale matrices:
use plugin gltf::{transform_translate, transform_rotate_y, transform_scale, multiply_transforms}
let t = transform_translate(0.0, 2.0, 0.0)
let r = transform_rotate_y(1.5708)
let s = transform_scale(2.0, 2.0, 2.0)
let world = multiply_transforms(multiply_transforms(t, r), s)
print("translation x lives at index 12: {world[12]}")
Decode a GLB binary header and walk its chunks:
use plugin gltf::{parse_gltf_header, parse_glb_chunks}
let header = parse_gltf_header(file_bytes)
print("{header["magic"]} v{header["version"]} ({header["length"]} bytes)")
let chunks = parse_glb_chunks(file_bytes)
for chunk in chunks {
print("{chunk["type"]} chunk at {chunk["offset"]}, {chunk["length"]} bytes")
}
Parse magic, version, length from GLB bytes
Reads the first 12 bytes of a GLB binary and returns a table with magic ("glTF" or hex string), version, and length.
use plugin gltf::{parse_gltf_header}
let header = parse_gltf_header(file_bytes)
print("{header["magic"]} v{header["version"]}, {header["length"]} bytes")
A non-"glTF" magic comes back as a hex string, which makes it easy to reject
files that are not valid GLB binaries:
use plugin gltf::{parse_gltf_header}
let header = parse_gltf_header(file_bytes)
if header["magic"] != "glTF" {
print("not a GLB file (magic was {header["magic"]})")
}
Build a mesh descriptor from vertices and indices
Packages a flat list of XYZ vertex coordinates and a list of integer indices into a mesh descriptor table with vertex_count, index_count, vertices, and indices fields.
use plugin gltf::{create_mesh}
let verts = [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.5, 1.0, 0.0]
let idx = [0, 1, 2]
let mesh = create_mesh(verts, idx)
print("vertices: {mesh["vertex_count"]}")
The returned table keeps the flattened vertices and indices lists, so you can
read individual components back out by index:
use plugin gltf::{create_mesh}
let mesh = create_mesh([0.0, 1.0, 2.0], [0])
print("first vertex x/y/z: {mesh["vertices"][0]}, {mesh["vertices"][1]}, {mesh["vertices"][2]}")
print("index count: {mesh["index_count"]}")
Build a PBR material descriptor
Creates a PBR material descriptor with base color RGBA (0.0–1.0) and metallic/roughness factors.
use plugin gltf::{create_material}
let mat = create_material("steel", 0.8, 0.8, 0.9, 1.0, 0.9, 0.2)
print(mat["name"])
The factors are stored as metallic, roughness, and the four base_color_*
fields, which you can read back when emitting glTF material JSON:
use plugin gltf::{create_material}
let gold = create_material("gold", 1.0, 0.84, 0.0, 1.0, 1.0, 0.1)
print("metallic: {gold["metallic"]}, roughness: {gold["roughness"]}")
print("red channel: {gold["base_color_r"]}")
Return a 4x4 identity matrix
Returns a 16-element table representing the 4x4 column-major identity matrix. Use as a starting point for composing transforms.
use plugin gltf::{transform_identity}
let m = transform_identity()
print(m[0])
List JSON and BIN chunks inside a GLB file
Iterates the chunk list in a GLB binary (skipping the 12-byte header) and returns a table of chunks, each with type ("JSON" or "BIN"), offset, and length.
use plugin gltf::{parse_glb_chunks}
let chunks = parse_glb_chunks(file_bytes)
print(chunks[0]["type"])
print(chunks[0]["length"])
Each chunk records the offset just past its 8-byte sub-header, so you can find the
embedded binary buffer by scanning for the "BIN" chunk:
use plugin gltf::{parse_glb_chunks}
let chunks = parse_glb_chunks(file_bytes)
for chunk in chunks {
if chunk["type"] == "BIN" {
print("binary payload starts at byte {chunk["offset"]}")
}
}
Build a scene node with optional transform and mesh
Creates a glTF scene node table. Translation is [x, y, z], rotation is a quaternion [x, y, z, w], scale is [x, y, z]. Pass nil for fields you want to omit.
use plugin gltf::{create_node}
let node = create_node("Cube", [0.0, 1.0, 0.0], nil, [1.0, 1.0, 1.0], 0)
print(node["name"])
Omitted fields simply do not appear on the table, so a bare node carries only its name:
use plugin gltf::{create_node}
let empty = create_node("Empty", nil, nil, nil, nil)
print(empty["name"])
Build a scene descriptor from a name and node list
Wraps a name and a list of node references into a glTF scene descriptor table.
use plugin gltf::{create_node, create_scene}
let node = create_node("Box", nil, nil, nil, 0)
let scene = create_scene("Main", [node])
print(scene["name"])
Build a glTF accessor descriptor
Builds a glTF accessor descriptor. component_type is a GL constant (e.g. 5126 for FLOAT), type_name is "VEC3" or "SCALAR", etc.
use plugin gltf::{create_accessor_info}
let acc = create_accessor_info(5126, "VEC3", 3, 0, 0)
print(acc["type"])
Build a glTF bufferView descriptor
Builds a glTF bufferView descriptor pointing into a buffer at a given offset and length.
use plugin gltf::{create_buffer_view}
let bv = create_buffer_view(0, 0, 36, 12, 34962)
print(bv["byteLength"])
Build a translation matrix
Returns a 4x4 column-major translation matrix for the given X, Y, Z offsets.
use plugin gltf::{transform_translate}
let m = transform_translate(0.0, 2.5, 0.0)
print(m[12])
Build a scale matrix
Returns a 4x4 column-major scale matrix.
use plugin gltf::{transform_scale}
let m = transform_scale(2.0, 2.0, 2.0)
print(m[0])
Build a Y-axis rotation matrix
Returns a 4x4 column-major rotation matrix around the Y axis. angle is in radians.
use plugin gltf::{transform_rotate_y}
let m = transform_rotate_y(3.14159)
Multiply two 4x4 column-major matrices
Multiplies two 4x4 column-major matrices together. Use to compose translation, rotation, and scale into a single transform.
use plugin gltf::{transform_translate, transform_rotate_y, multiply_transforms}
let t = transform_translate(1.0, 0.0, 0.0)
let r = transform_rotate_y(1.5708)
let combined = multiply_transforms(t, r)
Because the result is itself a 4x4 matrix table, calls chain to build a full transform stack:
use plugin gltf::{transform_identity, transform_scale, transform_translate, multiply_transforms}
let m = multiply_transforms(transform_identity(), transform_scale(2.0, 2.0, 2.0))
let placed = multiply_transforms(transform_translate(0.0, 5.0, 0.0), m)
print("scaled and lifted: y offset is {placed[13]}")