Skip to content

Instantly share code, notes, and snippets.

@donmccurdy
Last active August 19, 2023 13:54
Show Gist options
  • Save donmccurdy/fed6c3a22159ab6a541dbfa145323f7d to your computer and use it in GitHub Desktop.
Save donmccurdy/fed6c3a22159ab6a541dbfa145323f7d to your computer and use it in GitHub Desktop.
Sample code for generating a torus-shaped GLB from scratch using glTF Transform.
import { Document, NodeIO } from '@gltf-transform/core';
function createTorus(radius = 1, tube = 0.4, radialSegments = 12, tubularSegments = 48, arc = Math.PI * 2) {
const indicesArray = [];
const positionArray = [];
const texcoordArray = [];
const vertex = [0, 0, 0];
// generate positions and uvs
for (let j = 0; j <= radialSegments; j++) {
for (let i = 0; i <= tubularSegments; i++) {
const u = (i / tubularSegments) * arc;
const v = (j / radialSegments) * Math.PI * 2;
// position
vertex[0] = (radius + tube * Math.cos(v)) * Math.cos(u);
vertex[1] = (radius + tube * Math.cos(v)) * Math.sin(u);
vertex[2] = tube * Math.sin(v);
positionArray.push(vertex[0], vertex[1], vertex[2]);
// uv
texcoordArray.push(i / tubularSegments);
texcoordArray.push(j / radialSegments);
}
}
// generate indices
for (let j = 1; j <= radialSegments; j++) {
for (let i = 1; i <= tubularSegments; i++) {
// indices
const a = (tubularSegments + 1) * j + i - 1;
const b = (tubularSegments + 1) * (j - 1) + i - 1;
const c = (tubularSegments + 1) * (j - 1) + i;
const d = (tubularSegments + 1) * j + i;
// faces
indicesArray.push(a, b, d);
indicesArray.push(b, c, d);
}
}
const document = new Document();
const buffer = document.createBuffer();
const material = document.createMaterial().setBaseColorHex(0x4285f4).setRoughnessFactor(1).setMetallicFactor(0);
// indices and vertex attributes
const indices = document
.createAccessor()
.setArray(new Uint16Array(indicesArray))
.setType('SCALAR')
.setBuffer(buffer);
const position = document
.createAccessor()
.setArray(new Float32Array(positionArray))
.setType('VEC3')
.setBuffer(buffer);
const texcoord = document
.createAccessor()
.setArray(new Float32Array(texcoordArray))
.setType('VEC2')
.setBuffer(buffer);
const prim = document
.createPrimitive()
.setMaterial(material)
.setIndices(indices)
.setAttribute('POSITION', position)
.setAttribute('TEXCOORD_0', texcoord);
const mesh = document.createMesh('MyMesh').addPrimitive(prim);
const node = document.createNode('MyNode').setMesh(mesh);
const scene = document.createScene('MyScene').addChild(node);
return document;
}
const document = createTorus();
const io = new NodeIO();
await io.write('./torus.glb', document);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment