Confirming coordinate system transformation with scene.useRightHandedSystem

There’s a debate with my team on whether or not Babylon is flipping the x axis or the z axis when switching to a right handed system.

When I use scene.useRightHandedSystem in playground, it seems to flip the x axis. The sphere that was on the right hand side of the screen is now on the left.
https://www.babylonjs-playground.com/#S84MWJ#2

However, I believe this is happening because the camera is always facing down the positive z due to camera.setTarget(new BABYLON.Vector3(0, 0, 1)) and the sphere’s z is positive. This creates the illusion that it was flipped across the x.

The forum mods are saying that it is “effectively reversing Z”, read here: [SOLVED]Coordinates with right hand rule

Help us end this debate. Thanks!

1 Like

I found these in different locations in the Babylon.js code:

var forward = this._scene.useRightHandedSystem ?
                 new Vector3(0, 0, -1) : new Vector3(0, 0, 1);
...
if (this._mesh && this._mesh.getScene().useRightHandedSystem) {
    this._deviceRoomPosition.z *= -1;
}
...
defines.REFLECTIONMAP_OPPOSITEZ = this.getScene().useRightHandedSystem ? 
            !reflectionTexture.invertZ : reflectionTexture.invertZ;
...
if (!this._scene.useRightHandedSystem) {
    currentRig.position.z *= -1;
    currentRig.rotationQuaternion.z *= -1;
    currentRig.rotationQuaternion.w *= -1;
}

So it seems it is the z axis that is reversed in RHS.

1 Like

Thanks for the confirmation!

It depends. Note that a flip in Z with a 180° rotation is mathematically equivalent to a flip in X.

The engine itself flips Z (I believe). But for glTF, we flip Z and rotation by 180°.

True, you could flip any coordinate in a LFS to make it RHS. We just want to make sure we understand exactly what Babylon is doing in the LFS to RHS conversion. Thanks Gary.

1 Like

Apologies for bumping up this older topic. I am experimenting with importing from a RHS format. Does scene.useRightHandedSystem=true impact normal generation ? From the code search above it does not seem to, and when I use it I seem to get inside-out normals when using MeshBuilder. I think normals may be generated as if still in a LHS system but then displayed in a RHS system ?
The glTF2 loader does scale by 1,1,-1 and then rotate around Y? [0,1,0,0] . Is this intended to work for light directions and cameras as well ?
What is the purpose of the option to force useRightHandedSystem=true in the glTF loader ?

I think it turned out to be not a normals issue but a DirectionalLight issue:

https://playground.babylonjs.com/#6XIT28#887

It turns out that with useRightHandedSystem=true the Z component of the direction of a directional light needs to be flipped after loading a .babylon scene, serialized from a RH=true scene.

https://playground.babylonjs.com/#6XIT28#889 shows that flipping is not necessary when just generating meshes in RH mode.

So it is probably more an issue from serializing or loading .babylon formats when in RH mode.

Summary results:

LH .babylon into LH scene: correct
LH .babylon into RH scene: inside-out
RH .babylon into LH scene: mostly black but some lighting
RH .babylon into LH scene, flipped light direction: → inside-out
RH .babylon into RH scene: mostly black but some lighting,
RH .babylon into RH scene, flipped light direction: → correct lighting

Of course, only LH into LH and RH into RH are expected to work.

@Evgeni_Popov could you have a quick look ? as I know you worked a bit with handedness and I am always overly confused by it :slight_smile:

Thanks. Well, who isn’t ? :upside_down_face:

1 Like

Well, I could say I’m confused as well :slight_smile:

I generally just try one way or the other (setting scene.useRightHandedSystem = true or false), and when the rendering is ok then it means the code is ok :slight_smile:

I don’t reproduce the problem with this PG:
https://playground.babylonjs.com/#6XIT28#890

?

2 Likes

Thanks for looking into this. I tried a few more things with your PG and also could not reproduce until I parented the directional light to the camera, for a head light effect:

https://playground.babylonjs.com/#6XIT28#893

It appears that in RH mode the forward=look direction of the camera is (0,0,-1) in the local coordinate system while in LH mode it is (0,0,1). In RH mode this then requires the direction of the light to also be in this orientation.

This difference may or may not be intended or helpful. I am undecided but it is certainly a source of further confusion.

Yes, it is a difference betwwen LH and RH modes, the forward direction in camera space is (0,0,-1) in RH and (0,0,1) in LH. Maybe it’s something that should be documented somewhere(?)

1 Like

Yes, I could not find documentation on the useRightHandedSystem option and its effects, on meshes, cameras, physics etc.

Adding @PirateJC for the doc :slight_smile:

This is a legacy option for backwards compatibility. In almost all cases now, there is no need to set this flag. If you want to use right handed system, it’s better to set the flag on the scene before loading a model.

3 Likes

For a doc update, what specifically would we wanted added?

Happy to do the update, just want to be super clear on what we should add.

Thoughts?

Probably side effects on other components for this setup ?

@andreasplesch any thoughts ?

Yes, exactly. What kind of effect does the option have on components ? I think there were quite a few forum questions as well.

  • forward direction in camera space flips
  • loading LH models into RH scene: probably not expected to make sense but clarify if there is automatic adjustment, or other options.
  • normals: how does the option affect winding order ? Example ?
  • the goal: make scenes and models designed as right-handed just work ? Or allow LH models to work in RH scenes ?
  • I think I saw a physics question

Ok thanks.

I’ll compile some info and do a doc update to warn folks about this. Thanks!

2 Likes

I came across another RH system question.

In a RH scene, for a CubeTexture, how is the _pz image, or the third extension or file, interpreted ? I would have expected as the back face, in the RH positive Z direction, but it appears it is interpreted as the front face of the cube, essentially ignoring the RH option.
I should make a PG to demonstrate.