How to import an .fbx object from Blender

blender
import
fbx-loader

#1

I’m using the THREE.FBXLoader from examples\js\loaders but the FBXLoader.load() function gives me an error that says: TypeError: Failed to execute ‘decode’ on ‘TextDecoder’: The provided value is not of type ‘(ArrayBuffer or ArrayBufferView)’. I assume the loader isn’t the problem since it works fine with the example and others seems to be able to get it to load their models so perhaps it’s a problem with my export settings in Blender?

I’ve left all settings as default except I checked “Selected objects” and “Mesh” since I’m only trying to export a simple mesh. (And yes I made sure to selected the mesh before exporting it.)

Anyone know what the problem is here?
Thanks


#2

I think the FBXLoader in r89 has some issues. Try with the version in dev:


#3

Yes, this issue was fixed a couple of days ago.


#4

Using the dev version and adding inflate.min.js as a dependency no longer gives errors however I can’t help but think something is still wrong because the .fbx object won’t show. Here is a minimal code example:

<html>
	<head>
		<title>Testing</title>
		<style>
			body { margin: 0; }
			canvas { width: 100%; height: 100% }
		</style>
	</head>
	<body>
		<script src="three.js"></script>
		<script src="inflate.min.js"></script>
		<script src="FBXLoaderDev.js"></script>
		<script>
			var scene = new THREE.Scene();
			scene.add(new THREE.AxesHelper());

			var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
			camera.position.set(5, 5, 5);
			camera.lookAt(new THREE.Vector3(0, 0, 0));

			var renderer = new THREE.WebGLRenderer();
			renderer.setSize( window.innerWidth, window.innerHeight );
			document.body.appendChild( renderer.domElement );

			var loader = new THREE.FBXLoader;
			loader.load("box.fbx", function(object) {
				console.log(object);
				object.material = new THREE.MeshBasicMaterial( { color: 0xff0000 } );
				scene.add(object);
			});

			function render() {
				requestAnimationFrame(render);
				renderer.render(scene, camera);
			};

			render();
		</script>
	</body>
</html>

box.fbx is the default cube when you create a new Blender file exported with the settings in the first post and it just won’t show up in the scene.

Any idea why?


#5

The object returned by FBXLoader is a Group. Try this instead:


object.traverse( function ( child ) {

    if( child.material ) {

        child.material = new THREE.MeshBasicMaterial( { color: 0xff0000 } );

     }

} );

Aside from that, make sure that you are also using three.js from the dev branch - files from /examples need to match the correct three.js version.


#6

Okay, I’m now using three.js and FBXLoader.js from the dev branch and your code posted. I didn’t see the returned object is a group so thanks for that. I noticed that the matrix data for the object was like 99.99999… so I moved the camera 200 units away and sure enough, there it was. To get a 1 to 1 scale is it appropriate to just make the scale option 0.01 in the Blender exporter, or is there a better way to do it? I’d rather not work with hundreds of units in three.js and I’d expect the data to be a clean 100 number but I guess there’s some floating point arithmetic in the export/import process that’s losing the clean numbers right?


#7

I’m not familiar with units in Blender, but in three.js the convention is that 1 unit = 1 metre.
So if you create a 1-metre cube in Blender, and export at a scale of 1, then you should get a 1x1x1 cube in three.js… assuming that the Blender exporter and the FBXLoader are both correct.

I’m planning to examine whether the FBXLoader is loading objects at the correct scale at some point. At the moment I have a suspicion that it is not, and I have no idea about the Blender exporter.

If you want to investigate and provide me with some data that would be great :slight_smile:


#8

After a quick test it appears the conversion from 1 meter to 1 three.js unit doesn’t work with Blender but it’s also possible the Blender FBX exporter just doesn’t include the units because there’s no difference between setting the units as “none” or “meters” either way the matrix for the default cube looks like this:

[100, 0, -0, 0, -0, -0.000016292067961387602, -99.99999999999868, 0, 0, 99.99999999999868, -0.000016292067961387602, 0, 0, 0, 0, 1]

Setting the scale to 0.01 in the exporter should suffice for now, thanks so much for your help!


#9

Yeah, it looks like there might be a scaling factor of 100 being applied in the loader, assuming the default blender cube is 1x1x1.

I’ll investigate further. Glad you got it working anyway :slight_smile:


#10

It’s actually a scale factor of 200. When importing the default 1x1x1 cube from Blender to three.js via FBX, the bounding box is 200x200x200.


#11

@darkf I suspect this is a problem with the Blender exporter. Perhaps you could raise an issue there?


#12

Default Blender cube is 2x2x2 not 1x1x1.