Is there a decent fbx loader and exporter to be used with babylon.js?

On this topic I’ve started working on an FBX loader plugin using @jeremy-coleman 's reference

I just created the repo so it’s still in draft mode

1 Like

Good beginning!
You definitely need more FBX test files, to check how it works.

1 Like

Thanks,
It definitely is a good beginning

It can definitely be improved, the one issue I’m struggling with is making sure the behaviors are the same as for GLTFLoader or OBJloader…

2 Likes

I can only be admirative of your efforts to try revive one of the most cumbersome historical exchange format in the history of 3D :stuck_out_tongue_winking_eye:May be one day we’ll open a museum and we’ll feature your art :grin:

By the way, the link which I’ve mentioned a year ago, works again (it changed the name and URL) - Character Animation Combiner

@Benjythebee this is super coool !!! @PirateJC will like this :slight_smile:

1 Like

This is all what I’ve got after npm run start. Seems the Object (the model) is there but it is not visible.

There is some additional fbx related stuff here that may be helpful babylonjs-editor-quixel-plugin/src/fbx at master · julien-moreau/babylonjs-editor-quixel-plugin · GitHub

Fwiw, There is also a wasm version of assimp that works pretty well. I tested it a while ago and it worked perfectly for fully contained files, but it had issues with rebasing texture paths if they were separated out into their own files.

Also, i think its worth exploring using three’s loaders then reexport as gltf and import that into babylon. Getting that working would give us importers for usdz and many other formats

1 Like

yeah I’ve had this issue before, should make an issue on the github;
@jeremy-coleman oh that’s pretty insightful! thanks! I’ll look into it!

EDIT: I’ve just looked at Moreau’s code and it’s true that it’s a bit glitchy (see image for example). It seems to me that it also only outputs geometries ?
image

EDIT 2: I’m tempted to try out the threejs + babylonjs combo but I’ll have to watch out for package weight

EDIT 3: Spent the day trying the threejs + babylonjs option and it didn’t go so well. THREE.GLTFExporter would crash on ‘parseTexture’ (A classic property of undefined error). I tried different FBX files and always had the same result. I then tried OBJExporter before importing in babylon and while it didn’t crash it didn’t really give me the desired result (and scraped all materials and textures)

So it seems to me that continuing to work with the BABYLON.Editor’s code is something to pursue

3 Likes

Oh man @Benjythebee! This is AWESOME! I can’t wait to see how this develops! .FBX support is definitely going to interest a LOT of folks!

Keep us updated on your progress! Super pumped about this!

This deserves a big round of applause.

Way to dive into the depts of fbx.

2 Likes

Does this actually work?

If you were to get this to work just without any texture support, it would still be incredibly useful for combining animations from mixamo into a single glb/gltf file.

There is also this new CLI tool out:

If someone were to create a wasm script that invokes it, that would be awesome. Not sure how to do that myself atm.

2 Likes

Did you try this? - Character Animation Combiner

1 Like

Yes, using that for now, ofc I found this thread (and that link) only after I built my own version that works with gltf and glb files lol. But really I’m after a more complete solution that exists in babylon.js alone.

GitHub - kovacsv/assimpjs: The emscripten interface for the assimp library that allows you to import 40+ 3D file formats in the browser. is worth checking out too. it works. the only issue is that when it remaps the file paths in gltf format, the paths to external files such as textures are wrong. its manually fixable or regexp fixable if you’re crafty. overall, i think if you’re looking to spend some time on something, assimp is likely a better use of time .

also fwiw, from my limited knowledge on the fbx format, it seems it has changed over time so some old files may not load correctly if not using the fbx sdk , but i dont think that really matters as long as stuff from sketchfab and mixamo work (for test cases). so, i’d be sure when testing, the fbx is a recent one to make sure ur not pounding ur head against a wall to no avail

2 Likes

This is awesome!

However, I’m having trouble getting this set up in my babylon.js project.

The assimpjs.js code makes a fetch request to this endpoint:
http://localhost:3000/client/static/js/assimpjs.was
to fetch the wasm binary but that’s not actually where it lives, I have no idea how to fix that other than teaking the assimpjs.js code itself

Is that after bundling with webpack/other? I made a transform stream for it and just used from the command line, but that was a while ago. Also, is the file extension really .was and not .wasm? That could cause issues with serving the file because static node servers basically all do the same thing and look up mime type from a json document from the npm package “mime-types” and .was wouldnt be handled

1 Like

Yeah to that end I followed some steps and added this file config-overrides.js:

const webpack = require('webpack')
const path = require('path')

module.exports = function override(config) { 
	const fallback = config.resolve.fallback || {}; 
	Object.assign(fallback, { 
    'crypto': require.resolve('crypto-browserify'), 
    'stream': require.resolve('stream-browserify'), 
    'assert': require.resolve('assert'), 
    'http': require.resolve('stream-http'), 
    'https': require.resolve('https-browserify'), 
    'os': require.resolve('os-browserify'), 
    'url': require.resolve('url'),
    'path': require.resolve('path-browserify'),
    'fs': require.resolve('path-browserify')
  }) 
  config.resolve.fallback = fallback; 
  config.plugins = (config.plugins || []).concat([ 
   	new webpack.ProvidePlugin({ 
    	process: 'process/browser', 
      Buffer: ['buffer', 'Buffer'] 
    }) 
  ])
  const wasmExtensionRegExp = /\.wasm$/
  config.resolve.extensions.push('.wasm')

  config.module.rules.forEach(rule => {
    (rule.oneOf || []).forEach(oneOf => {
      if (oneOf.loader && oneOf.loader.indexOf('file-loader') >= 0) {
        // make file-loader ignore WASM files
        oneOf.exclude.push(wasmExtensionRegExp)
      }
    })
  })

  // add a dedicated loader for WASM
  config.module.rules.push({
    test: wasmExtensionRegExp,
    include: path.resolve(__dirname, 'src'),
    use: [{ loader: require.resolve('wasm-loader'), options: {} }]
  })
  return config
}