Babylon.RotationGizmo: all rotation's attributs change when moving the gizmo

Hello, I use BABYLON.RotationGizmo to rotate object in scene. When I move xGizmo for example, mesh.rotation.y and mesh.rotation.z change.
I make useEulerRotation = true when I create the gizmo
I want just change mesh.rotation.x value and keep the old values of mesh.rotation.y and mesh.rotation.z when moving xGizmo.

Hello and welcome to the community !!!

Adding @Cedric our Gizmo mastermind who can probably help with that :slight_smile:

Hi @mkhanfir can you please provide a playground that highlights your issue? It’s easier to debug :slight_smile:

1 Like

Hi, here is the url of the playground: https://www.babylonjs-playground.com/#4TBMBR#46
When I move xGizmo, mesh.rotation.x, mesh.rotation.y and mesh.rotation.z change.
I need to have the new value of mesh.rotation.x without changing mesh.rotation.y and mesh.rotation.zrotation

This has to do with the order of rotation. object matrix is computed by transforming the object with a serie of rotation on the 3 axis in a particular order (x,y,z). But if you change rotation on axis x, the rotation on following axis will change.
To preserve the same values for nonmodified axis, we have to change the order of rotations multiplication.
So, when you rotation on axis X, the reference for orientation on axis Y and Z are also reoriented.
For example, in this PR:
https://www.babylonjs-playground.com/#4TBMBR#47
I only log the rotation for zAxis. And rotation x and y are preserved because the rotation on axisZ happens at the end of matrix computation.

But everything is not lost :slight_smile: If you want to know the delta rotation that’s been applied on a particular axis, you can do a dot product of that particular axis ( cosine angle = dot(world axis before transform, world axis after transform) )

This can be great for display information about the operation. I’m nor sure you will be able to reuse that operation to build a matrix easily.

Can you elaborate on your use case maybe I can help finding a solution ?

Thank you :slight_smile:
Yes this is what I try to do to get the delta rotation, use a particular axis and calculate the dot product: https://www.babylonjs-playground.com/#4TBMBR#50
But sometime it return also a bad value, for example:


rotation2

I’m more used to dot product instead of ‘produitScalaire’ now :slight_smile:

Anyway, I changed the PG to get the angle on X axis:
https://www.babylonjs-playground.com/#4TBMBR#51
The idea is to keep the original matrix and project current matrix’s axis onto the previous one.
This dot product is the cosine of the angle.
But that’s half the work because arc cosine range is (0, pi), so we need to do the same with another axis.
Once done, you have the cosine and the sine of that angle. With an arc tangent, you get the angle delta since the drag started.

It’s easier, thank you :slightly_smiling_face:
But how can I do that if I have gizmo.updateGizmoRotationToMatchAttachedMesh = false?
https://www.babylonjs-playground.com/#4TBMBR#55
The axes of rotation become the axes of the scene.
So how can I get the delta rotation that’s been applied on the X axis of the scene when moving the xGizmo for example?

Thank you in advance :slight_smile: :slight_smile:

It’s almost the same.
Except that the computation is in worldspace. when getting rotMatrix from the mesh world matrix, compute it’s inverse. That matrix will be used to convert from worldspace to localspace.
Then in ondrag observable, multiply the mesh world matrix by that inverse.
The resulting matrix will be the delta transformation.
The dot product computation will be simplified because of worlspace so you can compute the atan2 directly from the axis of that delta matrix.

Like in this PR: https://www.babylonjs-playground.com/#4TBMBR#58 ?

Looks good to me :slight_smile:

Thank you :slight_smile: :slight_smile:

Hello, I have a problem when I apply a rotation along the Z axis before moving xGizmo. It doesn’t give the right angle.
PG : https://www.babylonjs-playground.com/#4TBMBR#59
Without a rotation along the Z axis:

With a rotation along the Z axis:

I wrapped my head around. I think it should be:

var angle = Math.atan2(mult.m[6], mult.m[1]);

You mean: var angle = Math.atan2( mult.m[ 6 ], mult.m[ 10 ]) ; ?

Hello, I try also with :

  var angle = Math.atan2( mult.m[ 9 ], mult.m[ 5 ]) ;

but it doesn’t work.

The rotation is around X axis, so we can use Y axis to get the angle.
Posing Y’ the new axis after the rotation. Y’ represented by the second column of the matrix “mult” so :

Y' = { x : mult.m[ 1 ], y : mult.m[ 5 ], z: mult.m[ 9 ] }

We project Y’ on Y to get the cosine = mult.m[ 5 ] and on Z to get the sine = mult.m[ 9 ]

It’s wrong ??

After some tests, it looks like [6] and [5] are correct but the matrix multiplication is not

https://www.babylonjs-playground.com/#4TBMBR#60

mult.m[6] is the second column third row of the matrix ?

3rd column of 2nd row