How to (correctly) import gltf and add physics

Hey all!

I just got started with babylon.js and I’m having a great time, thanks for work and the community!

I’m having a bit of trouble trying to understand what is the best way to import a scene (from Blender) and rig it with physics imposters.

Here’s my set up so far: Babylon.js Playground. It works, but I’m confused.

Two questions:

  1. Why do I need to invert the y scaling? From what I understand, blender has a different coordinate system and the gltf is imported with a __root__ mesh with a negative z scaling. Why is this? When I call .addChild() to set the correct parent for the floor mesh, why is this suddenly making the y scaling negative?
  2. If I open the babylon inspector and, in the debug tab, enable the physics wireframe, it looks like the physics imposter is not scaled correctly. However, the test box is supported properly by the floor imposter. Is this a bug in the inspector or am I missing something?

Thanks a lot!

Hey @wilcoschoneveld Welcome to the Babylon Family! So great to have you here!!!

Good questions.

I’m bringing in @bghgary to correct me if I’m wrong about some of this.

Blender is a z-up right handed world.

Babylon is a y-up left handed world.

To complicate things, .gltf is also a right handed coordinate system.

Because the coordinate systems are different, there has to be conversion that happens between them.

This happens on the Babylon gltf importer. Whenever you import a .gltf object, Babylon automatically puts in a root node with the scaling you need to make your object work in the y-up left handed world.

SOOOO…what I usually recommend that people do, is to import the .gltf file, and then set the parent of the object to be null instead of the root node. if you use the .setParent() helper method, it will also do the conversion to set the scaling properly to the Babylon world. Ok confusing I know…here’s an example:

https://playground.babylonjs.com/#0IRV8X

If you check out lines 62-65, you’ll see that after importing a snowball .gltf object. we take the first “mesh” object of the snowball asset (which in this case is the root node that the Babylon .gltf importer creates for you) and assigns that to the snowBallParent variable.

Next we return the first child mesh of that parent object and assign that to a “snowBall” variable.

Next is the magic line. We take the snowball variable and use the .setParent(null) method where we tell the Babylon engine that we want this object to have no parent. This helper method will magically copy all transforms to the snowball.

Then finally we dispose of the original parent root node.

let snowBallParent = snowBall.meshes[0];
snowBall = snowBallParent.getChildMeshes()[0];
snowBall.setParent(null);
snowBallParent.dispose();

When you do this method, it means that you’ll have a clean hierarchy without any strange transforms between your object and the world. As you can probably guess, this is pretty important because the physics engines are going to calculate math based on the Babylon coordinate system.

It’s possible to do without this step, but I think you’ll find it quite a bit easier to go this way.

Hope this helps nudge you in the right direction.

P.S. - I used this specific playground as an example because there’s quite a bit of physics fun happening in this scene that you can reference.

I love the magic. :mage: I’m a lot less impressed about the reasons why this magic had to be invented in the first place :wink:

1 Like

Hey @PirateJC! Thanks a lot for the warm welcome and the answers to my questions! I have found that the .setParent(null) trick works really well.

When importing from blender to babylonjs there will always be an axis reversed (e.g. scaling.y = -1) since the mesh needs to be converted from a right-handed system to a left-handed system (right?). Physics (like BoxImposter) does not (yet) work nicely with this, so I still have to inverse the scaling of the object in order to make the physics work properly. This works fine for simple cases but more complicated meshes are misaligned.

I’ve created a minimal repro and I’m currently looking to provide a fix for this myself with a PR. Thanks a lot!

1 Like

Awesome! So stoked to hear you’ve identified a problem and are working on your own fix! That’s the brilliance of Open Source!

I’ve figured out that there is a way to work around the negative scaling issue by baking the scaling into the mesh, like so: https://playground.babylonjs.com/#TWVYMQ#6

Otherwise I’m looking into supporting negative scaling out of the box in this pull request: Fix PhysicsImposter for negatively scaled mesh by wilcoschoneveld · Pull Request #10259 · BabylonJS/Babylon.js · GitHub

2 Likes

Hey @wilcoschoneveld thanks for posting this! I’m running into the same issue when importing gltf and I’m trying the workaround you showed by baking the scaling into the mesh. Have you gotten this working if the initial scaling isn’t (1, -1, 1)?

For example: Box test bake scaling | Babylon.js Playground (babylonjs.com)

Here I’m scaling the incoming __root__ mesh by 0.5 after importing. I thought this would be okay because the 0.5 scale would also be baked into the box vertices, but the result is an impostor that is too large (not scaled by 0.5).

Hey @nonexplosive!

I ended up not using baking since, like you mention, it’s not really robust. I actually figured out that you can use scene.useRightHandedSystem = true to eliminate any trouble with importing gltfs. With this, you won’t have any negative scaling.

Like this: https://playground.babylonjs.com/#TWVYMQ#16

More info here: Issue with loading mesh and colliders and adding physics - #11 by wilcoschoneveld