Left and Right Handed shenanagins

BabylonJS is so cool I cannot sleep at night. But what is up with the coordinate system.

So I’m importing gltf models from Maya into Babylon scene. Setting up the camera I notice the coordinates seem to be backwards, but my models looks correct. Placing some GUI elements, same backwards coordinates. Hmmm…

So now I activate billboard mode on some of the imported mesh and they flip into this backwards coordinate system. ACK!

So I learn how to get the inspector in my scene and discover this weird “root” node with a negative Z scale. Ack again.

So now I learn about this lefthanded or righthanded system for gltf and my head is spinning.

Using the scene.useRightHandedSystem = true; switch makes my scene work EXCEPT I have to flip a few things that I added through code, which are now backwards. Not a big deal.

Did I do this the correct way, by using the scene.useRightHandedSystem = true ? The BILLBOARD seems to not work correctly in lefthanded mode, at least not with imported gltf models from Maya.

1 Like

It should work both ways as the intent of the root is actually to flip the model back.

You could set the useRightHandedSystem if you prefer to work as such but yes as long as there are no normalization of coordinates system it is a tough topic :slight_smile:

The mesh I’m affecting with the billboard is under the flipped root, causing it to flip in all 3 directions (I think all 3). I’ll setup a PG example when I can.

Adding onto that, I’ve had a similar issue while trying to import multiple GLBs which were previously arranged in Unity. My models were rotated wrong way round because I needed to apply the rotation to the root elements and thus was overwriting the right-hand left-hand rotation conversion.

Turns out the Unity GLTF plugin converts right-hand to left-hand by flipping the X axis and the Babylon GLTFLoader does that by flipping the Z axis and rotating 180 in Y.

Unity Khronos plugin

Babylon GLTF loader

Workaround
I managed to work around this issue by overwriting the root scaling vector with Vector3(-1,1,1) and overwriting the root rotation to the desired one or if no rotation was desired then resetting it to 0.

Simplified code is below and playground here.

const desiredRotation = new BABYLON.Quaternion(x,y,z,w);
const manager = new BABYLON.AssetsManager(scene);
const task = manager.addMeshTask("meshTask", "", "scenes/BoomBox/", "BoomBox.gltf");
    
task.onSuccess = () => {
    const mesh = task.loadedMeshes.find(mesh => mesh.id === '__root__');
    mesh.rotationQuaternion = desiredRotation ?? BABYLON.Quaternion.Identity();
    mesh.scaling = new BABYLON.Vector3(-1,1,1);
}

Question
Would it be possible to either change the behaviour of the GLTFLoader in such way that -X scaling is applied instead of the -Z scaling and Y rotation OR create a third case entry in the GLTFLoaderCoordinateSystemMode and handle the new case in the GLTFLoader?

I’m happy to help with implementation just wanted to get some input from contributors first :smiley:

1 Like

cc @bghgary

-Z scale and a 180 degree rotation is equivalent to -X scale. The reason it’s not -X scale is because I didn’t realize initially that -X scale is simpler and because of backwards compatibility. We can add an enum entry to change this, but you can also easily achieve what you want by using the correct math.

PG: https://playground.babylonjs.com/#NPZ0W1#1

1 Like

To me personally having that extra enum would be much more clear, I spent a fair amount of time trying to figure out why my rotations from Unity don’t produce the same result in Babylon.

Multiplying the quaternion works but the side effect of that is an ‘incorrect’ rotation in Y axis. Say I set the rotation to 45 degrees in Y, the resulting rotation of the root will be -135 degrees.

PG: https://playground.babylonjs.com/#NPZ0W1#2

Also adding extra info about this to the doc would be a lot of help for newbies like me :slight_smile:

If you are happy with this I will open an issue in GH

1 Like

This is all just conventions at the end of the day. If you really want it to be easy to understand, I suggest adding another transform node above the root to apply your transforms. The __root__ node is there to do the right-hand to left-hand conversion.

I’m not sure if you mean the doc or the code.

Fair enough :+1:

I meant both, but taking the above into account I guess the doc would be enough.

I see no problem with opening an issue on the docs repo, or if you’d like to add your own contribution to the docs it would be even more awesome!

There we go. Contribution to the doc, code or any twist is welcomed. But the real contribution we would need is to just stop the crap and have everyone on the same line. GL with this :wink: Anyone who will undertake this mission will instantly become my Hero :man_superhero: :smiley:

Sure! I will try get something proposed on the docs repo soon :smiley:

2 Likes

Wow, this likely saved me a ton of time and headaches. I was having trouble with an imported hand mesh. The hand would always be the left hand, even though I exported it in Blender as a right hand. Long story short, I got left and right hands by using the line “scene.useRightHandedSystem = true;” (turned both hands into right hands) and then for my left handed hand mesh I added a negative x value during scaling- leftControllerMesh.scaling = new BABYLON.Vector3(-0.0025, 0.0025, 0.0025);

Thanks Mati ! :beers: :smoking:

1 Like