Inverted objects when exporting with Sandbox, glTF to babylon?

So i uploaded a glTF file to the sandbox and exported it as babylon file.

Then later i noticed when loading the babylon file the X/Y-Coordinates got inverted.
I checked it several times and the blender exporter works fine. There it loads corecctly.
Here i loaded both babylon files to show the difference:

You should probably set scene.useRightHandedSystem = false because .babylon files work in left handed mode. scene.useRightHandedSystem = true is normally used only for .glTF files, which define vertex coordinates in a right-handed mode.

Yeah i thought about that but it didn’t matter. It doesn’t change anything in the outcome. Only the axes of the axesviewer are obviously switched then… But the object still appears in that opposite corner

It’s not easy to compare the two models, as one is made up of 8 meshes while the other is a single mesh. Can you have the same structure for the models (either a single mesh, or 8) for comparison purposes?

One thing that’s different is that one of the models has the __root__ node, which is created when a glTF file is loaded. I think this model comes from the sandbox, as you’d expect this node to be exported because it exists in the scene.

What you might want to do is delete this node. The easiest way to do this is to set the parent of Cut_XXX meshes to null:

This way, the transformation matrices (the identity) are the same as for the single-mesh model. As it is not positioned in the same place, this means that the vertices are not the same… I’m not sure why the .babylon export would change the mesh vertices, though. Can you share the original .gltf/.glb file, before conversion to .babylon?

So Blender the blender exporter just made one mesh while exporting and the sandbox just made 8 meshes and the root node… idk how to change the exporting behavior so that the sandbox only exports one or blender makes 8.

I did some clean up and rename of my files so you may can better tell which is which. I renamed them so have that in mind that the playground file names have to be updated…

If you look at the .gltf file in a text editor and look at the min/max values for the cube vertex buffers, you can see that for the Z coordinate, min=-0.01 and max=0.0 :

    {
      "bufferView": 0,
      "byteOffset": 0,
      "componentType": 5126,
      "count": 4,
      "max": [0.0, 0.01, 0.0],
      "min": [0.0, 0.0, -0.01],
      "type": "VEC3"
    },
    {
      "bufferView": 0,
      "byteOffset": 48,
      "componentType": 5126,
      "count": 4,
      "max": [0.01, 0.01, 0.0],
      "min": [0.0, 0.0, 0.0],
      "type": "VEC3"
    },
    {
      "bufferView": 0,
      "byteOffset": 96,
      "componentType": 5126,
      "count": 36,
      "max": [0.01, 0.01, 0.0],
      "min": [0.0, 0.01, -0.01],
      "type": "VEC3"
    },
    {
      "bufferView": 0,
      "byteOffset": 528,
      "componentType": 5126,
      "count": 4,
      "max": [0.01, 0.01, -0.01],
      "min": [0.0, 0.0, -0.01],
      "type": "VEC3"
    },
    {
      "bufferView": 0,
      "byteOffset": 576,
      "componentType": 5126,
      "count": 4,
      "max": [0.01, 0.0, 0.0],
      "min": [0.0, 0.0, -0.01],
      "type": "VEC3"
    },
    {
      "bufferView": 0,
      "byteOffset": 624,
      "componentType": 5126,
      "count": 4,
      "max": [0.01, 0.01, 0.0],
      "min": [0.01, 0.0, -0.01],
      "type": "VEC3"
    },
    {
      "bufferView": 0,
      "byteOffset": 672,
      "componentType": 5126,
      "count": 75,
      "max": [0.007, 0.01, -0.003],
      "min": [0.003, 0.005, -0.007],
      "type": "VEC3"
    },
    {
      "bufferView": 0,
      "byteOffset": 1572,
      "componentType": 5126,
      "count": 41,
      "max": [0.007, 0.005, -0.0030014676378983804],
      "min": [0.003005868397632519, 0.005, -0.0069985323621016199],
      "type": "VEC3"
    },

So what the sandbox/PG displays is correct. If it’s different in Blender, it means that Blender is exporting modified data when you export to .gltf: perhaps there are options at export time that you can change to avoid this?

Ok, thank you for your research. Then probably my export as gltf went wrong. Because it should be positive. And idk why but blender somehow did it wrong again but then it was right again.

Also how do you view gltf files in this layout? Like when i order it i only get one long line or one long line under another… Or have you sorted it by yourself?

I use the code formatting option in VSCode (shift+alt+F).

1 Like

Okay i have ran into more problems with this that i don’t understand.
So in your snippet from my gltf file is only the Z-Coordinate negative. and the rest ist positive, my babylon export then changes them to the opposite. So XY are negative and Z is positive… That is also what i get to see when i load the model.
Now i thougth ok, so far so bad, but i can work with it. I know use the getBoundingInfo().maximum function to get the max values of the meshes… but if i do that by still using my babylon file that has the inverted XY and Z values it now shows the original values from the gltf file… idk why and yeah, i will try now to somehow detect if it’s an inverted file or not but i’m not sure if that’s stored in the file, but it has to be, otherwise babylon wouldn’t know either right?

To reproduce: change the file in line 30 to “NewCube.babylon” and “SandBoxCube.babylon” and inspect the side to see the values in console.

I don’t know why you use Math.abs to compute the max values (?), it leads to wrong results when values are negative. Also, you inverted maxY/maxZ in the code and the maxX/maxY/maxZ values should be initialized with a very small values and not 0, in case the max value is negative or null (which is the case for SandBoxCube and the Z axis).

Here’s a fixed PG, which also computes the minimum values:

For NewCube:

  • min: -0.0005, 0, -0.0005
  • max: 0.01, 0.0105, 0.01

For SandBoxCube (I rounded the values):

  • min: 0, 0, -0.01
  • max: 0.01, 0.01, 0

Regarding the SandBoxCube, you exported to .babylon after loading the .glb, which means the special node (__root__) that convert to left-handed mode is there. This node is doing a 180° rotation around Y and mirrors the Z component. If you remove this node, you get:

Which corresponds to the min/max values above: the cube is on the positive axis for X and Y and the negative axis for Z.

Ok thank you, i had to re-read this a few times but i think i understood it.

So why does the SandBox add that __root__node? Can i set something to not get that node which converts to left handed mode? Or how do i remove the root node on importmesh? Like sure i can edit the file on my own, but i need it to be loaded without the root node.

Main problem is definitely the .gltf file that somehow has negative z values. But that’s an export problem, not a babylon one

It’s not the Sandbox per see, it’s because the scene is created in left-handed mode, so the glTF loader creates this node to account for the rhs=>lhs transformation. cc @bghgary, I don’t think we can make the Sandbox creates a right-handed scene (would that be useful)?

See my post above where I explained how to remove this node at import time:

Okay, i may be annoying with this. But i currently think that the sandbox from babylon imports/exports gltf-files wrong.

So i made a new playground: Babylon.js Playground

I made a basic scene and an axesViewer to see how babylon does interpret the scene and coordinates… I then exported it to gltf/glb-file and imported it into CAD-Programs and also Blender.
They all showed a different scene/orientation as babylon does, but they all show the same “wrong” orientation. This is what they show:

Ok blender uses a right-handed coordinate system, so i added line 6…
Then it rotated but still nor right:

So i do understand that there are conversions for left and right handed etc. but somehow other software tool do interpret the gltf files the same, but babylon kinda messes something up.
While import and export. Or am i missing something?

Like i don’t wanna blame babylon, i love working with it, everything else really works pretty good and i learn a lot of stuff. So maybe i’m wrong. but the idk why other tools save/open the gltf files the same and babylon doesn’t.

Also maybe there is a problem with the coordinate systems in generral? Blender does use XZY and babylon does use XYZ- So the up-vector is changed. But babylon and the others get it done to transform/rotate everything so that the models still appear upwards. I have seen in the files that there are parameters like “upvector: (0,0,1)” so probably tells them which vector is the up-vector so that works fine, but maybe that causes problems for the main problem here…

Activating the right-handed mode in Babylon.js will not make the coordinate axes coincide with those of Blender (or any other DCC tool for that matter). There are many ways to create a right-handed (or left-handed) coordinate system.

In Babylon, when you switch to right-handed mode, X now goes left, Y is always up and Z is always “inside the screen”. This is not the coordinate system used by Blender, but both are right-handed.

I don’t know what you expect from the second screenshot when you say it’s still wrong?

You’ll never see the same coordinate axis (in the top right-hand corner) in Blender as the one we use in Babylon.js - they’re simply different. What counts is that the display (rendering) is the same, which is the case here.

Yeah, i’m aware that i won’t see the same coordinate system as in blender. But in the Playground i made in my last post, the sphere and ground are moved into positve x/z direction. Then i export to gltf and in blender it appears in negative x/y-coordinates or in only y-negative when using right handed system.

Blender performs transformations at loading time when you import a .glb file.

For eg, take this PG:

I baked the transformation matrix of the cube so that the vertices of the cube are transformed and are in the 3.5-4.5 range for X/Z and 0.5/1.5 for Y.

If you look at the data inside the .glb file when exported by Babylon.js, you can see:

    {
      "name": "position - box",
      "bufferView": 0,
      "componentType": 5126,
      "count": 24,
      "type": "VEC3",
      "min": [
        3.5,
        0.5,
        3.5
      ],
      "max": [
        4.5,
        1.5,
        4.5
      ],
      "byteOffset": 0
    },

You can see that the min/max values for X/Z are 3.5/4.5 and 0.5/1.5 for Y, which is what you’d expect from the code and what you see in Babylon :

Now, when loaded into Blender :

Since the Z axis goes upwards and the X axis to the left, Blender modified the vertex coordinates at the time of loading, otherwise you wouldn’t see the scene this way.

3 Likes

Ok, Thank you for your efforts and patience to explain and show me what I misunderstood.