Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FBX Binary format not supported? #9860

Closed
3 of 12 tasks
RicoLiu opened this issue Oct 14, 2016 · 100 comments
Closed
3 of 12 tasks

FBX Binary format not supported? #9860

RicoLiu opened this issue Oct 14, 2016 · 100 comments

Comments

@RicoLiu
Copy link

RicoLiu commented Oct 14, 2016

Description of the problem

qq 20161014151051

FBXLoader only supports FBX text format?

Three.js version
  • Dev
  • r81
  • ...
Browser
  • All of them
  • Chrome
  • Firefox
  • Internet Explorer
OS
  • All of them
  • Windows
  • Linux
  • Android
  • IOS
Hardware Requirements (graphics card, VR Device, ...)
@Mugen87
Copy link
Collaborator

Mugen87 commented Oct 14, 2016

Yes. Right now FBXLoader only supports ASCII format in version 7.

@RicoLiu
Copy link
Author

RicoLiu commented Oct 14, 2016

Three.js version : r77

qq 20161014175807

Why?

@Mugen87
Copy link
Collaborator

Mugen87 commented Oct 14, 2016

/ping @yamahigashi

@makc
Copy link
Contributor

makc commented Oct 14, 2016

Why?

because there is no reference open-source implementation? if you know one, I would be curious to see it.

@makc
Copy link
Contributor

makc commented Oct 14, 2016

Ah, wait, I thought it was about binary. For ASCII FBX below v7, I had the code here and a bunch of test models somewhere in my hard drive.

@takahirox
Copy link
Collaborator

takahirox commented Oct 16, 2016

Anyone here who has made or is making binary FBX parser?
If not, I'm feeling like trying to make that...

@makc
Copy link
Contributor

makc commented Oct 17, 2016

you have to love reverse engineering stuff to do this ) and, you may be lucky if it is simple tags, but if they serialize every data type uniquely, you are properf-ed: you're facing tweaking one number per model and saving it to see what has changed, at a time.

@takahirox
Copy link
Collaborator

Thanks for the advice.
I've achieved to make a FBX binary parser by seeing this site now.

https://code.blender.org/2013/08/fbx-binary-file-format-specification/

I'll try to make ObjectParser which makes an object
from the result of the binary parser next.

@makc
Copy link
Contributor

makc commented Oct 17, 2016

oh wow, someone already went through the hell ,and there are specs )

@yamahigashi
Copy link
Contributor

https://banexdevblog.wordpress.com/2014/06/23/a-quick-tutorial-about-the-fbx-ascii-format/
I think this link also is great stuff for to do that.

@Mugen87
Copy link
Collaborator

Mugen87 commented Oct 17, 2016

@takahirox It would be great if the new parser would have a similar structure like THREE.PLYLoader. This implementation uses an uniform logic for creating the THREE.BufferGeometry object after parsing the data from an ASCII or Binary input (see usage of method handleElement).

@takahirox
Copy link
Collaborator

takahirox commented Oct 17, 2016

ok I'll try. And I'm thinking if I also can use that for MMDLoader.

BTW does anyone here know if FBX binary format remains the same even below version 7?

@RicoLiu
Copy link
Author

RicoLiu commented Oct 18, 2016

I have no idea.

Maybe @mrdoob knows?

@makc
Copy link
Contributor

makc commented Jan 11, 2017

@takahirox did you share your binary fbx parser anywhere?

@takahirox
Copy link
Collaborator

Not yet... I'll do soon!

@jmsaulnier
Copy link

@takahirox Any updates :) ? Thanks!

@takahirox
Copy link
Collaborator

Sorry I've been busy lately... but soon soon!

@jmsaulnier
Copy link

jmsaulnier commented Feb 28, 2017

@takahirox Awesome \o/

@takahirox
Copy link
Collaborator

I'm gonna start to work on FBX binary parser again from April.
LMK if anyone is in hurry.

@avaer
Copy link

avaer commented Apr 17, 2017

@takahirox Do you have something rough to share? We're doing a presentation at the end of the week and could really use FBX binary loading for the demo.

@adam-clarey
Copy link

Hi @takahirox I'm actually in a hurry, is there any update on this? I can help where able, but this is all still new to me.

@takahirox
Copy link
Collaborator

I'm just starting to work on that again.
At least, I still need some weeks to share that.

@adam-clarey
Copy link

How many weeks do you think?

@takahirox
Copy link
Collaborator

Hm, maybe two or three weeks?

@adam-clarey
Copy link

Just out of curiosity, could this be done in a week or so if i were able to sponsor some of the dev work?

@takahirox
Copy link
Collaborator

Well, I can't promise but I'll try.
Do you have any specific models data you can share?
Wanna work with them as reference.

@adam-clarey
Copy link

testfile.fbx.zip
This is similar to what we need if it helps

@mrdoob
Copy link
Owner

mrdoob commented Apr 28, 2017

In the meantime...

For https://with.in/watch/under-neon-lights/ we used plain-text FBX but we changed the extension to .fbx.txt so the server would gzip it. I also optimised quite a lot the FBXLoader2. It ended up being a pretty decent workflow.

I wonder if there is anythingFBXLoader supports that FBXLoader2 doesn't or we can replace it already...

@Kyle-Larson?

@Mugen87
Copy link
Collaborator

Mugen87 commented Apr 28, 2017

Side note: The FBX example already uses FBXLoader2, too.

@hmtri1011
Copy link

Hi! I'm also getting this error when trying to load an external .fbx model which is export from Autodesk. Can anyone give me a solution for this

Thank you!

@RicoLiu
Copy link
Author

RicoLiu commented May 10, 2017

https://github.com/takahirox/three.js/blob/FixLoaderBinaryParser/examples/js/loaders/FBXLoader2.js
Note that this's very temporal.
I need to clean up and optimize the code.
And functionality could be broken right now.

@hmtri1011

@hmtri1011
Copy link

hmtri1011 commented May 10, 2017

@RicoLiu This is what I got when used THREE.FBXLoader. I implemented a loader_fbx example by replacing the URL of the model.

And when I used THREE.FBXLoader2 I got the error THREE.FBXLoader2 is not a constructor

image

@jostschmithals
Copy link
Contributor

jostschmithals commented May 10, 2017

You can use the webgl_loader_fbx.example:

  1. load https://github.com/takahirox/three.js/blob/FixLoaderBinaryParser/examples/js/loaders/FBXLoader2.js
    instead of the FBXLoader2.js of the current threejs branch,
  2. use THREE.FBXLoader (without the version number 2 !),
  3. (deactivate the animations, if there are no animations in your model),

and it should work.

@hmtri1011
Copy link

@jostschmithals I follow your step then getting a new error Zlib is not defined

@jostschmithals
Copy link
Contributor

Seems that your model file is compressed?

@hmtri1011
Copy link

image
Full Error what I get

@takahirox
Copy link
Collaborator

Add this line in your example.

	<script src="js/libs/zlib_and_gzip.min.js"></script>

@hmtri1011
Copy link

image
Done, and another error appeared.... :(

@jostschmithals
Copy link
Contributor

As I wrote above, you have to deactivate the animation code (in the loading section and in the render loop), if you use the example code with a model file that doesn't contain any animations.

@adam-clarey
Copy link

adam-clarey commented May 10, 2017

I'm experiencing a different issue, im sure is related to materials. My problem is that under certain conditions some fbx models render and some dont.

To reproduce:
in the webgl_loader_fbx.html example file, just inside init() place the following code to create an environment

 var loadSkyDomeAndGroundBowl = function(scene, onLoad, onProgress, onError) {
                var pathtop="path/to/top.jpg";
                var pathbot="path/to/bottom.jpg";
                var radius=40;
                var bottomtopfactor=0.1;
                var sinkin=0.05;

                var texturetop;
                var texturebot;

                var onTextureLoadTop=function(texture) {
                  console.log('onTextureLoadTop');
                  texturetop=texture;
                  onTextureLoaded();
                };
                var onTextureLoadBot=function(texture) {
                  console.log('onTextureLoadBot');
                  texturebot=texture;
                  onTextureLoaded();
                };

                var onTextureProgress=function(xhr) {
                  console.log('onTextureProgress');
                  if(onProgress)
                    onProgress('Loading sky dome / ground bowl texture');
                };
                var onTextureError=function(xhr) {
                  console.log('onTextureError');
                  if(onError)
                    onError('Error loading sky dome / ground bowl texture');
                };

                var onTextureLoaded=function() {
                  console.log('onTextureLoaded');
                  if(texturetop && texturebot) {
                    console.log('onTextureLoaded 2');
                    var geometrytop = new THREE.SphereGeometry( radius*10, 600, 400, 0, Math.PI*2, 0, Math.PI*0.5);
                    var materialtop = new THREE.MeshBasicMaterial();

                    materialtop.map = texturetop;
                    materialtop.side = THREE.BackSide;
                    var skydome = new THREE.Mesh( geometrytop, materialtop );
                    skydome.position.y=bottomtopfactor*radius+sinkin;
                    scene.add( skydome );

                    var geometrybot = new THREE.SphereGeometry( radius, 60, 40, 0, Math.PI*2, Math.PI*0.5, Math.PI*0.5);
                    var materialbot = new THREE.MeshBasicMaterial();
                    materialbot.map = texturebot;
                    materialbot.side = THREE.BackSide;
                    var groundbowl = new THREE.Mesh( geometrybot, materialbot );
                    groundbowl.scale.set(1,bottomtopfactor,1);
                    groundbowl.position.y=bottomtopfactor*radius+sinkin;
                    scene.add( groundbowl );

                    if(onLoad)
                      onLoad();
                  }
                };

                var loader=new THREE.TextureLoader();
                loader.load(pathtop, onTextureLoadTop, onTextureProgress, onTextureError);
                loader.load(pathbot, onTextureLoadBot, onTextureProgress, onTextureError);
              }

Which basically just adds a skydome and ground with 2 images.

Then after the scene is initialized, run: loadSkyDomeAndGroundBowl(scene);

You will see that the 2 fbx models load and render fine within this new environment.

Now, if you replace the xsi_man_skinning.fbx reference with the TestcudeWithImages.fbx (also comment out animation code) you will see that the code does not render at all.

I've noticed this with other fbx files too. Binary fbx files do not seem to be compatible with environments.

Or I could just be doing something wrong...
(and yes its using the latest FBXLoader2 file)

@hmtri1011
Copy link

hmtri1011 commented May 10, 2017

This is my example code:
`


three.js - FBXLoader test

<script src="../build/three.js"></script>

<script src="js/controls/OrbitControls.js"></script>

<script src="js/curves/NURBSCurve.js"></script>
<script src="js/curves/NURBSUtils.js"></script>
<script src="js/loaders/FBXLoader2.js"></script>

<script src="js/Detector.js"></script>
<script src="js/libs/stats.min.js"></script>
<script src="js/libs/zlib_and_gzip.min.js"></script>
<script>
	if (!Detector.webgl) Detector.addGetWebGLMessage();

	var container, stats, controls;
	var camera, scene, renderer, light;

	var clock = new THREE.Clock();

	var mixers = [];

	init();

	function init() {

		container = document.createElement('div');
		document.body.appendChild(container);

		camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000);

		scene = new THREE.Scene();

		// grid
		var gridHelper = new THREE.GridHelper(28, 28, 0x303030, 0x303030);
		gridHelper.position.set(0, - 0.04, 0);
		scene.add(gridHelper);

		// stats
		stats = new Stats();
		container.appendChild(stats.dom);

		// model
		var manager = new THREE.LoadingManager();
		manager.onProgress = function (item, loaded, total) {

			console.log(item, loaded, total);

		};

		var onProgress = function (xhr) {

			if (xhr.lengthComputable) {

				var percentComplete = xhr.loaded / xhr.total * 100;
				console.log(Math.round(percentComplete, 2) + '% downloaded');

			}

		};

		var onError = function (xhr) {

			console.error(xhr);

		};

		var loader = new THREE.FBXLoader(manager);
		loader.load('models/fbx/accient_2_full.fbx', function (object) {

			//object.mixer = new THREE.AnimationMixer(object);
			//mixers.push(object.mixer);

			//var action = object.mixer.clipAction(object.animations[0]);
			//action.play();

			scene.add(object);


		}, onProgress, onError);

		loader.load('models/fbx/nurbs.fbx', function (object) {

			scene.add(object);

		}, onProgress, onError);

		renderer = new THREE.WebGLRenderer();
		renderer.setPixelRatio(window.devicePixelRatio);
		renderer.setSize(window.innerWidth, window.innerHeight);
		renderer.setClearColor(0x000000);
		container.appendChild(renderer.domElement);

		// controls, camera
		controls = new THREE.OrbitControls(camera, renderer.domElement);
		controls.target.set(0, 12, 0);
		camera.position.set(2, 18, 28);
		controls.update();

		window.addEventListener('resize', onWindowResize, false);

		light = new THREE.HemisphereLight(0xffffff, 0x444444, 1.0);
		light.position.set(0, 1, 0);
		scene.add(light);

		light = new THREE.DirectionalLight(0xffffff, 1.0);
		light.position.set(0, 1, 0);
		scene.add(light);

		//animate();

	}

	function onWindowResize() {

		camera.aspect = window.innerWidth / window.innerHeight;
		camera.updateProjectionMatrix();

		renderer.setSize(window.innerWidth, window.innerHeight);

	}

	//

	function animate() {

		requestAnimationFrame(animate);

		if (mixers.length > 0) {

			for (var i = 0; i < mixers.length; i++) {

				mixers[i].update(clock.getDelta());

			}

		}

		stats.update();

		render();

	}

	function render() {

		renderer.render(scene, camera);

	}
</script>
`

@jostschmithals can you give me a correct solution for this. I'm also deactive the animate code

@jostschmithals
Copy link
Contributor

jostschmithals commented May 10, 2017

@adam-clarey I've tested it, and the reason that you can't see the cube is that it sits under the ground plane (if you orbit it with the camera you should see it). Besides this all is working fine for me with your code.

@jostschmithals
Copy link
Contributor

jostschmithals commented May 10, 2017

@takahirox: The mesh inside the group created by FBXLoader is translated and rotated, so that the pivot point is not placed in the center of the cube like in the original model, but in the center of its upper side. This seems to be a minor bug?

(the image is correctly displayed on top though ...)

@jostschmithals
Copy link
Contributor

jostschmithals commented May 10, 2017

@hmtri1011 You have deactivated your animate() function. Therefore your scene is not rendered at all 😉

(It should be sufficient in this case to deactivate only the lines you already commented out.)

@hmtri1011
Copy link

hmtri1011 commented May 11, 2017

@jostschmithals tks :D it works now

@adam-clarey
Copy link

Good spot @jostschmithals, thanks.

Should it matter what binary version the file is? I've got fbx files with version 7400 that render fine, but one with version 7500 and it errors out.

"FBXLoader: Unknown property type "
where the variable 'type' is an empty string

@jostschmithals
Copy link
Contributor

@adam-clarey I have no detailed knowledge of fbx. I only joined this thread because I found the question interesting whether/how image data could be baked into the model file. So I would like to forward this question to @takahirox.

@takahirox
Copy link
Collaborator

I know the specification of >=7500 is a bit different from < 7500, and
am working on that to support >= 7500.
Can you share the binary model data of version 7500 for the test?

@adam-clarey
Copy link

So after more testing, 7200 and 7500 seem to be fine.

However, 6100 and 7300 dont render.
house_fs.fbx.zip
DutchHouse.FBX.zip

@takahirox
Copy link
Collaborator

takahirox commented May 23, 2017

Would you share the ascii version files?
We can clarify if the issue is binary specific or not.

@takahirox
Copy link
Collaborator

And I hope we close this issue because FBXLoader supports binary now (maybe not perfect yet tho).
Let's make another issue for FBXLoader improvement.

@Mugen87
Copy link
Collaborator

Mugen87 commented May 23, 2017

@takahirox Sounds good!

@FishOrBear
Copy link
Contributor

FishOrBear commented Aug 15, 2017

@adam-clarey
I think i got this bug.

"FBXLoader: Unknown property type "
where the variable 'type' is an empty string

in FBXLoader.js <line 4010>
change to

			while ( ! this.endOfContent( reader ) ) {

				var node = this.parseNode( reader, version );
				if ( node !== null ) 
					allNodes.add( node.name, node );
				else
					break;

			}

#11956

@nxhoang
Copy link

nxhoang commented May 3, 2018

Hello everyone,
I noticed that FBXLoader just supports FBX file to be >= 7.0.
Now I want to load fbx file below 7.0, please tell how to do this?
Here is my fbx files https://github.com/nxhoang/Three.js-Fxb-and-Textures/tree/master/models/fbx
Thanks a lot.

@looeee
Copy link
Collaborator

looeee commented May 3, 2018

@nxhoang as we discussed here, we only support FBX versions above 6100 (Binary) or 7000 (ASCII).

If you need to use older FBX files you'll need to update them (best to load them into 3ds max or Maya to do this), or convert them to another format.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests