fbx -> gltf

by Matt

HTML

<base href="https://rawcdn.githack.com/mrdoob/three.js/r153/examples/" />
<script async src="https://cdn.jsdelivr.net/npm/[email protected]/dist/es-module-shims.js"></script>
<script type="importmap">
{
		"imports": {
			"three": "https://cdn.jsdelivr.net/npm/[email protected]/build/three.module.js",
			"three/addons/": "https://cdn.jsdelivr.net/npm/[email protected]/examples/jsm/"
		}
}
</script>

CSS

canvas {
	position: fixed;
	inset: 0;
}

JavaScript

import * as THREE from 'three'
import { GLTFExporter } from 'three/addons/exporters/GLTFExporter.js'
import { FBXLoader } from 'three/addons/loaders/FBXLoader.js'
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'

main()

async function main() {

	const fbxLoader = new FBXLoader()
	const gltfLoader = new GLTFLoader()
  const gltfExporter = new GLTFExporter()
  
  console.log("starting load")
  
  const fbx = await fbxLoader.loadAsync("models/fbx/Samba Dancing.fbx")
  console.log("finished load")
  
  // verify fbx contains skinned mesh
  
  const fbxSkinnedMesh = fbx.getObjectByProperty('isSkinnedMesh', true)
  
  if (!fbxSkinnedMesh) throw new Error()
  
  
  // export to gltf
  
  const glbBuffer = await gltfExporter.parseAsync(fbx, { binary: true, animations: fbx.animations })
  
  
  const glbFile = new File([glbBuffer], "converted.glb")
  const glbUrl = URL.createObjectURL(glbFile)
  
  
  // load gltf
  
  const gltf = await gltfLoader.loadAsync(glbUrl)
  
  // verify gltf contains skinned mesh
  const gltfSkinnedMesh = gltf.scene.getObjectByProperty('isSkinnedMesh', true)
  
  if (!gltfSkinnedMesh) throw new Error()
  
  
  // download link
  
  const a = document.createElement("a")
  a.href = glbUrl
  a.download = glbFile.name
  a.innerText = glbFile.name
  document.body.appendChild(a)
  
  console.log(gltf)
}