Why does Box3 based on XBot.glb and similar does not match rendered size and how to programmatically adjust?

Hi All,

I’m working on an app which involves people uploading glb models and scale them to a specific size so that they fit in a show room environment where they can be viewed by potential buyers.

I’m using the threejs example models to test the various formats that can be imported. Almost all are scaling correct apart from the Xbot.glb file used in this example: three.js examples

The first step I’m taking using to scale the object is to use the following code to get the original size of the model:
meshBounds = new THREE.Box3().setFromObject( obj3D );
let lengthMeshBounds = {
x: Math.abs(meshBounds.max.x - meshBounds.min.x),
y: Math.abs(meshBounds.max.y - meshBounds.min.y),
z: Math.abs(meshBounds.max.z - meshBounds.min.z)
};

I use this to create a bounding boxmesh and to check it works correctly I add the model and the transparent bounding boxmesh to the scene.

For obj3D I have tried using:

  • The Group which is at the top level of the object heirarchy and immediately within the Scene.
  • The first child of the group which is called “Armature” and I belive is the root of the skeleton.

Using either method the box created is tiny and certainly does not contain the whole model. (see image).

A designer that is testing the system also had the same issue with another similar model created with blender and mixamo which also uses a skeleton.

Could anyone please advise me as to why the xbot.glb file produces this strange result and let me know if there is another way to scale the model that I could try?

Many thanks in advance.

[Update]

After reading this post ([HELP] FBXLoader SkinnedMesh does not scale with the model? - #2 by ViniciusFranciscoXavier) I tried setting the scale of the group after I had created the bounding box:

obj3D.scale.set(.01, .01, .01);

This now matches the size of the bounding box:

image

I also have a similar model with this issue and used obj3D.scale.set(.01, .01, .01);

The dimensions of the second model also matched the bounding box when I scaled it down like this, however it’s orientation did not match.

So it seems that however xbot.glb was produced, the scale does not match of the Box3 size.

Does anyone know the reason for this? It cant be a coincidence that the two models are incorrectly scaled by the same amount.

Ideally I’m looking for:

  • the reason behind this issue
  • a method to detect it
  • a method to automatically re-align / re-scale

I could even ask our users to manually scale and reorient the object and resave it in our UI but if if anyone else has an idea for an automated solution I’d be very grateful for any pointers.

Do you call computeBoundingBox on the geometry before creating the box3 from the model? three.js docs
What sizes do you get if you console log your lengthMeshBounds object?

1 Like

Hi - thanks so much for the fast reply and suggestions.

I have just tried to see if I can call computeBoundingBox anywhere before I create the Box3 but neither the Group or the “Armeture” Object3D in this file have a geometry so there is nothing to call it on.

The sizes I get back when creating my Box3 very small and are the same whether I try to measure the Group or Armeture

Box3 for Group:
max: Object { x: 0.009025660551510883, y: 0.018060490681369057, z: 0.0017695815465692821 }
min: Object { x: -0.009025659359418015, y: -0.00003231170049358082, z: -0.0014373925006972432 }

Giving size:
x: 0.018051319910928898
y: 0.018092802381862637
z: 0.0032069740472665254

Box3 for Armature (Children[0] of the group)

max: Object { x: 0.009025660551510883, y: 0.018060490681369057, z: 0.0017695815465692821 }
min: Object { x: -0.009025659359418015, y: -0.00003231170049358082, z: -0.0014373925006972432 }

Giving size:
x: 0.018051319910928898
y: 0.018092802381862637
z: 0.0032069740472665254

Just guessing here but it seems the Group is giving the size of the root of the skeleton which consists of Bone and Skinned Mesh components, but isnt giving me the size of a model as a whole. :thinking:

It’s common with skinned meshes because the bones sometimes interfere with the scale of the mesh, another side-effect is grouping: adding the whole gltf.scene behave very differently than adding extracted gltf.scene.children (rotation and scaling may change).

I would recommend to use the whole gltf.scene and keep the group intact (if possible) for more consistent results with skinned meshes. And manually resize your meshes using (random down-sizing exemple): object.scale.set(0.1, 0.1, 0.1) It should work with animation and keep everything working.

1 Like

Hi @Oxyn - thanks!

The manual scaling seems to work. (I think you were replying as I was updating my question to include this.)

Do you have any idea if there is a way I could automatically detect that this issue has occurred and how much to scale down by?

object.scale.set(0.1, 0.1, 0.1) absolutely works - the same scale 0.1 on both models but I have no idea why there is that specific size difference. It cant be a coincidence… :thinking:

This is a mystery I need to solve on my side too (random X10 scale just happening)
But the culprits can be everywhere on my workflow chain, could be not related to Three or GLTF loader at all. Sorry to not be able to help further, I’m interested if anyone has more info on this.

1 Like

Yes, I dont think its necessarily a ThreeJS issue.

It seems to be occurring with animated avatars in all cases which I think are using mixamo animations.

Can I ask if you experienced this when using mixamo or other types of animations or on static objects too?

1 Like

Yes my animations are coming from mixamo too.
Could it be related to their bones configuration? (Despite I’m still tweaking them heavily inside a 3D app before exporting) :thinking: interesting