How to fix scale for fbx programmatically?

Hi, To import the fbx, I have used the following code:

// model
var loader = new FBXLoader();
loader.load( 'models/fbx/Samba Dancing.fbx', function ( object ) {
mixer = new THREE.AnimationMixer( object );
var action = mixer.clipAction( object.animations[ 0 ] );
action.play();
object.traverse( function ( child ) {
	if ( child.isMesh ) {
			child.castShadow = true;
			child.receiveShadow = true;
	}
} );
scene.add( object );

Of course, it works fine.
What is the problem?
Here is my fbx file: SC_021.fbx (1.1 MB)
If import the fbx, it is shown very smallest.


So, I have test on three.js editor: https://threejs.org/editor/
It seems to scale correctly.

As you know, each fbx file are difference in size(scale).
How can add any fbx in right scale?

1 Like

You will often encounter this when loading models created in different programs and by different artists.

The model may have been created using centimeters, meters, inches, feet, or no units at all. Usually I start by scaling in factors of ten to see if it’s just cm -> m or the reverse. Trying scaling the loaded FBX object like this:

// scale down by factor of ten
object.scale.multiplyScalar(0.1); 

// OR
// scale up by factor of ten 
object.scale.multiplyScalar(10); 
4 Likes

Thanks for your reply.
I’d like to know the way how to dynamically fix the scale of various FBX .
If i try to add concurrently both my SC_021.fbx and Samba Dancing.fbx with this code:

object.scale.multiplyScalar(10); 

then SC_021.fbx are showed in correct, but Samba Dancing.fbx are showed in large.
Please explain me, how to dynamically controls scale of each object.

You need to scale each model differently:

loader.load( 'models/fbx/Samba Dancing.fbx', function ( object ) {
   // 1 is default scale (100%)
   const scaleFactor = 1; 
   object.scale.multiplyScalar(scaleFactor);  

   mixer = new THREE.AnimationMixer( object );
   var action = mixer.clipAction( object.animations[ 0 ] );
   action.play();
   object.traverse( function ( child ) {
	if ( child.isMesh ) {
			child.castShadow = true;
			child.receiveShadow = true;
	}
   } );
   scene.add( object );
}

loader.load( 'SC_021.fbx', function ( object ) {

    // adjust this until your model matches the Samba model
   const scaleFactor = 10;

   object.scale.multiplyScalar(scaleFactor); 

   mixer = new THREE.AnimationMixer( object );
   var action = mixer.clipAction( object.animations[ 0 ] );
   action.play();
   object.traverse( function ( child ) {
	if ( child.isMesh ) {
			child.castShadow = true;
			child.receiveShadow = true;
	}
   } );
   scene.add( object );

}
1 Like

If I have a lot of fbx, the above way is incorrect, I think.
I’d like to know the way to fit scale of any fbx dynamically.
Thanks.

Could you do something like:

object.updateMatrixWorld();
let box = new THREE.Box3().setFromObject(object);
const size = box.getSize(new THREE.Vector3()).length();
const scalar = 1; // Change this to set the general size for each object
object.scale.set(scalar/size,scalar/size,scalar/size);

Changing the scalar value will increase/decrease the size, but all models imported should scale correctly.
The next problem is you may need to center the pivots of the models…

2 Likes

Good coding.
Did you test using above code with my sample fbx: SC_021.fbx
I have test your code with my sample fbx.

object.updateMatrixWorld();
let box = new THREE.Box3().setFromObject(object);
const size = box.getSize(new THREE.Vector3()).length();
const scalar = 1; // Change this to set the general size for each object
object.scale.set(scalar/size,scalar/size,scalar/size);
console.log(size); // 7085.044623234223
console.log(Math.max(scalar/size,scalar/size,scalar/size)); // 0.00014114237145672543

So, scale value is 0.00014114237145672543 and smallest.
But, three.js editor showed clearly.
How about think?
Please show me sample code with SC_021.fbx
Regards

Sorry, but im not setting up a sample project for you.

If you set up a sample project using jsfiddle or similar, im happy to look into debugging it for you

I have detect really model body about SC_021.fbx.
i.e. it is

var body = object.children[2].children[1];
var box = new THREE.Box3().setFromObject(body);
var size = box.getSize(new THREE.Vector3()).length();
console.log(size); // 6.79
object.scale.multiplyScalar(size); // It seems good about scale.

How can decide the scale size programmatically?

1 Like