Unexpected behaviour when rotating a Mesh in World Space

Hello Community,

I attempted to rotate a mesh, either a parent or a child mesh, in World Space and noticed that mesh.rotate() was not behaving as expected. :thinking:

Based on the documentation, I should be able to specify whether the rotation should occur in WORLD or LOCAL Coordinates. However, when rotating a child node, the rotation seems to be in a different direction.

After conducting some research on this forum, I came across a similar issue to mine. The solution mentioned that I need to use the right-handed coordinate system instead of the default left-handed system that BJS uses

But I’m a bit confused here, why doesn’t the rotate method automatically adapt to the used coordinate system? and what if I’m not willing to switch to the right-handed system ? Are there any alternative solutions available ?

I’ve created two playground demonstrating the behaviour :

Thanks!

When loading a gltf/glb file in left-handed mode (default), we need to create a special __root__ node to account for the right-handed-to-left-handed conversion. This node adds a 180° rotation around Y and a negative scale on Z. So, if you apply transformations to the child nodes of this node, they will also undergo the root transformation and you won’t get the same thing as if you were in right-handed mode in the first place (in which case __root__ is still created but with an identity transformation).

If you don’t want to set the scene to right-handed mode, you should simply take into account that there is this additional transformation when you apply a transformation to a child node.

I am totally aware of the intention behind adding the root, but i feel like having the space prop in the rotate function is a little bit misleading, since it doesn’t adapt to the coordinate system.

shouldn’t we need to update the function and take into account the additional transformations ?

also correct me if I’m wrong, in order to convert a world rotation of a child node back to a local rotation, I need to multiply the inverse of the parent’s world rotation with the child’s world rotation ?

Thanks

There isn’t really an additional coordinate system at the scene graph level: it’s simply an additional node with a specific transformation.

Some nodes may have a parent node with this transformation and others may not, so it’s not easy at first glance to know whether a given node is in a hierarchy of “right-handed” or “left-handed” nodes. You’d have to go up the entire hierarchy for each calculation to obtain this information, which isn’t possible for performance reasons. What’s more, I’m not taking into account the fact that we could also have a node with a Y rotation of 180° and a Z scaling of -1 that would be a true regular node and not one that converts from rhs to lhs!

As far as your question is concerned, you need to use the inverse transformation of the child’s world to move from world to local (child’s) space.

I kept this on hold since august and I’ve been working on and off, testing and trying to figure it out.

I was inspired by the gizmos and how we can rotate objects in world space. basing myself on the source code. I created a new rotate function, which seems to solve the issue I talked about from the beginning.

if it’s legit, I think we should update the current rotate function, the code is basically the same for rotation gizmos onDragEnd.

This should fix it Fix transform node world space rotation when parent has negative world matrix determinant by sebavan · Pull Request #14467 · BabylonJS/Babylon.js · GitHub

2 Likes

That’s awesome !
thanks @sebavan :heart_eyes:

glad I pushed this through to be eventually fixed ! :smile:

1 Like