Skip to content

Instantly share code, notes, and snippets.

@donmccurdy
Last active September 27, 2022 04:22
Show Gist options
  • Save donmccurdy/32fb3bfcb5365a557c5dff8bb34dd4c2 to your computer and use it in GitHub Desktop.
Save donmccurdy/32fb3bfcb5365a557c5dff8bb34dd4c2 to your computer and use it in GitHub Desktop.
Example Node.js script using glTF-Transform to extract geometry from a glTF document and create a geometry-only three.js scene graph.
import { NodeIO } from '@gltf-transform/core';
import { KHRONOS_EXTENSIONS } from '@gltf-transform/extensions';
import draco3d from 'draco3dgltf';
// set up I/O
const io = new NodeIO()
.registerExtensions(KHRONOS_EXTENSIONS)
.registerDependencies({'draco3d.decoder': await draco3d.createDecoderModule()});
const document = await io.read('path/to/file.glb');
const scene = document.getRoot().listScenes()[0];
const group = new THREE.Group();
// traverse the scene, adding only nodes with geometry
scene.traverse((node) => {
if (node.getMesh()) {
group.add(createGroup(node));
}
});
/**
* Creates THREE.Group for a glTF-Transform Node. Considers only vertex positions,
* other vertex attributes and materials are ignored. For a 'full' implementation,
* see https://github.com/donmccurdy/glTF-Transform-View.
*/
function createGroup(node) {
const group = new THREE.Object3D();
const matrix = new THREE.Matrix4()
.fromArray(node.getWorldMatrix());
matrix.decompose(
group.position,
group.quaternion,
group.scale
);
for (const prim of node.getMesh().listPrimitives()) {
const position = prim.getAttribute('POSITION');
const indices = prim.getIndices();
const geometry = new THREE.BufferGeometry();
geometry.setAttribute(
'position',
new THREE.BufferAttribute(
position.getArray(),
position.getElementSize(),
position.getNormalized()
)
);
if (indices) {
geometry.setIndex(new THREE.BufferAttribute(indices.getArray(), 1));
}
group.add(new THREE.Mesh(geometry));
}
return group;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment