OBJ exported scene rotated 180º around up axis


I might have found an issue with the OBJExport.OBJ output.

To reproduce

Use this simple playground: https://playground.babylonjs.com/#JTLL3M#3

  • Enable the debuguer and export the scene as a GLB file
  • Open devtool of your browser, and copy the .obj file that is logged to the console by BABYLON.OBJExport.OBJ() and save it to test.obj

You should get those two files:

If you import them on blender for example

  • you get this for the .GLB:

  • you get this for the .OBJ:

The OBJ file is rotate 180º around the up axis

I am not sure how to fix this ? or workaround it ? I would like to have consistent exports between OBJ and GLB

Thanks a lot for the help

I don’t think so. I think the obj file is correct. It’s your glb/gltf that once imported in blender using the right-handed system of blender, displays mirrored. I never tried the export, so I don’t know whether this is a bug or just unhandled behavior on export. On import, BJS creates a parent and fixes the transform through a minus scaling on the Z-axis and Math.PI on the Y- axis to face the camera/scene. On export, probably it doesn’t, I didn’t check on it. But apparently, from your screenshot, it doesn’t.
The workaround would be to apply the conversion manually before export I believe. May be this export thingy can be improved somehow. May be you’ll have to wait a little because 1)it’s sunday 2) there’s a code freeze until the launch of v7.
Meanwhile, enjoy your weekend :sunglasses:

cc @bghgary.

AFAIK, there is no forward convention specified in OBJ, so there isn’t a right way to export an OBJ, but we should try to be consistent with the ecosystem if possible. Does the OBJ import into Babylon sandbox in the same orientation?


Thanks a lot for the quick replies.

I did a few more test with this playground: https://playground.babylonjs.com/#JTLL3M#11 , adding the axis as tube to see a bit better what it happening, the shorter tube is the X axis, the bigger one is the Z axis in babylonjs coordinates system

Here are the two files exported from Babylon.js as GLB and OBJ

Then imported in blender:

  • OBJ file: The X axis is the same as in babylon.js, and the Z and Y axis has been swapped , the object is the same, but the camera is from the other side

  • GLB file: X, Y and Z axis are different… the object is the same and the camera is from the same side

Opening in 3D Viewer on windows:

  • OBJ file : object is the same and camera is from the same side

  • GLB file: object is correct but camera is 180 degree the other side like when importing in the sandbox.

importing them back on the babylon.js sandbox playground

  • OBJ file , here the object seems to be mirrored (not the same), there is some issue with import OBJ

  • GLB file: The object look correct but the camera is reversed from the export

I am not sure what to think of all this to be honest:

  • I am wondering why when you export in GLB with babylonjs and then open it again in the sandbox the camera is reversed ?

  • Might have a bug with the OBJ import that mirror the model ?

  • regarding consistency between OBJ and GLB exports (what I am looking for), I could either rotate the scene 180 before exporting in GLB or in OBJ and I think I would reach what I want… maybe we could add an option in the exporter to follow some convention or not ?

Thanks a lot for the help and the work on babylon.js

There are a lot of conventions to consider:

  1. Right-handed vs left-handed coordinates system. In Babylon.js terms, the scene defaults to left-handed. You can change it to right-handed by doing this scene.useRightHandedSystem = true. Both glTF and OBJ are right-handed. It appears the obj exporter in Babylon.js converts to right-handed by only inverting Z position, which I don’t think is going to work for all cases, but I think it is okay for your case.
  2. Babylon.js is Y-up. glTF is Y-up. OBJ, AFAICT, does not specify which way is up. Blender, IIRC, is Z-up. This might have some implications on what’s going on with the axes.
  3. Forward convention (i.e., which way is front). glTF is the only one that specifies, but Babylon.js also implicitly defines this in order for the exporters to know what to do.

This is a combination of the handedness and forward convention.

Possibly, but we should rule out some of the problems. Maybe try doing everything with Babylon.js in right-handed system to see if we can at least rule that one out?

Try with right-handed first and then we’ll see.

Thanks for the reply.

  • If I set my scene to useRightHandedSystem = true the exports are consistent. Importing in blender both GLB scene and OBJ scene result to the same scene.

I used this code to convert all my meshes after setting: useRightHandedSystem = true :

this._scene.meshes.map((mesh) => {
      const scaleMatrix = BABYLON.Matrix.Scaling(1, 1, -1);

And I get the same scene with the rightHanded coordinate system.

  • I do think there is a bug with the import OBJ function in the playground, because when importing back the scene (exported with useRightHanded) in the playground , I get the object mirrored on the X axis

Here is the playground with useRightHanded : https://playground.babylonjs.com/#JTLL3M#12

And the exports in GLB and OBJ

And the results in the sandbox:

  • OBJ:

  • GLB:

My takeaways for now are:

  • If you want consistent import from a babylon.js exported scene in GLB and OBJ, do use a useRightHandedSystem = true in your scene

  • There might be a bug in the code that imports a scene from an .OBJ file in the sandbox

Thanks a lot

Interesting. It does appear the obj loaded into Babylon.js is inverted compared to other viewers. I will investigate.


It appears our OBJ importer and exporter had many issues with handedness since it was written. I’ve attempted to fix most of the issues in this PR.

Fix obj loader and exporter to support handedness correctly by bghgary · Pull Request #14884 · BabylonJS/Babylon.js (github.com)


I hope this is not going to mess with my current settings, is it? I’m not using the exporter but I do import lots of OBJ and I wouldn’t like my scene breaking just before the imminent launch (because it says ‘breaking change’) :sweat_smile:

This will probably break your scene, as the objects will be mirrored (maybe not if you use scene.useRightHandedSystem = true). You should stick to one version before the PR is merged for your release, and update your code afterwards.

1 Like

I don’t use right-handed. OBJ is my standard and else everything from my demos are pure BJS (left-handed) :smiley:
I can’t say I like this answer but thanks a lot for the warning :hugs:.
I will retrieve the latest version library and link my scenes to this until I find the time to conform them to new.
Good thing is that with the launch of v7 I was going to do this anyway.
Bad thing is that, meanwhile, I will not be developing sync with latest :cry:

Have a great day :sunglasses:

@RaananW @sebavan and I debated this a bunch. If this is messing up your workflow, we can introduce a flag to put it back to the old (wrong) behavior.

So where do we stand with this? I mean, I know it’s not my role and I have also been warned (by @Evgeni_Popov) that there’s a risk of breaking everything related to .obj import. But that’s just me. If this is really going to happen, shouldn’t you Guys make an announcement to warn the community? Just thinking :thinking: (sorry to interfere) :pray:

Hey @bghgary will this resolve GltfExport - flipped camera ?

I did a temporary fix on my project where I wrapped the models under a transform node and to fix the camera rotation (when it’s animated) I had to create a temporary animation group and multiplied the rotation with 180 on both z and y.

Well, that’s basically what I imagined when I told the poster

but that’s just a fix on export. The way I understand it is that everything is wrong from this handling. Eventually, only a breaking change will let us return to ‘normal condition’. At least, that’s my understanding of this.

Totally agree,
We won’t know for sure what procedure we need to undo to follow this fix.
As you said, an announcement would be great

1 Like

No, unfortunately not. I am refactoring the serializer to make this work properly. This won’t make the 7.0 release.

I think if people are concerned by this change, we should add a flag to revert to the old behavior but keep the default the hopefully correct behavior. We are guessing not a lot of people are using obj files since this has been wrong since it was written.

Yes, a breaking change is required to get the default to the correct behavior.

We can announce something if we suspect many people will be affected. @Deltakosh @sebavan Any thoughts?