Created
August 4, 2022 09:06
-
-
Save andrewmunro/8955526d109dd1b8562cbf220ee4f8a5 to your computer and use it in GitHub Desktop.
Merge threejs GLTF/GLB geometries
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { BufferGeometryUtils } from 'three/examples/jsm/utils/BufferGeometryUtils'; | |
import { GLTFExporter } from 'three/examples/jsm/exporters/GLTFExporter'; | |
import { BufferGeometry, getMesh, LoadGLTF, Material, Mesh, MeshBasicMaterial } from '@milk-ecs/three'; | |
import { Blob, FileReader } from 'vblob'; | |
import { writeFileSync } from 'fs'; | |
// Some hacks to get GLTFExporter working in nodejs | |
global.window = global; | |
global.Blob = Blob; | |
global.FileReader = FileReader; | |
global.document = { | |
createElement: nodeName => { | |
if (nodeName !== 'canvas') throw new Error(`Cannot create node ${nodeName}`); | |
} | |
}; | |
const run = async () => { | |
const forest = await LoadGLTF('assets/golf/maps/forest.glb'); | |
const materials = new Map<string, Material>(); | |
const mats: Material[] = []; | |
const geometries: BufferGeometry[] = []; | |
forest.scene.updateMatrixWorld(true); | |
forest.scene.traverse(m => { | |
if (m instanceof Mesh) { | |
// Dedupe materials | |
if (!materials.has(m.material.name)) { | |
materials.set(m.material.name, m.material); | |
} | |
mats.push(materials.get(m.material.name) as Material); | |
// Bake position into geometry | |
// We need to clone it so children don't get matrixWorld applied multiple times. | |
const geom = m.geometry.clone() as BufferGeometry; | |
geom.applyMatrix4(m.matrixWorld); | |
geometries.push(geom); | |
} | |
}); | |
let geometry = BufferGeometryUtils.mergeBufferGeometries(geometries, true); | |
geometry = BufferGeometryUtils.mergeVertices(geometry); | |
const mesh = new Mesh(geometry, mats); | |
const exporter = new GLTFExporter(); | |
const options = { | |
trs: false, | |
onlyVisible: false, | |
truncateDrawRange: false, | |
binary: true, | |
maxTextureSize: 4096 | |
}; | |
exporter.parse( | |
mesh, | |
data => { | |
console.log(data); | |
writeFileSync('test.glb', Buffer.from(data as ArrayBuffer)); | |
}, | |
options | |
); | |
}; | |
run(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment