I am (still) writing a CAD-Program (Computer Aided Design) using JME and it works fine.
But there is still one thing that makes me crazy.
All my rotations are extrinsic.
Every object has a rotation in degrees over the angles x,y and z that are done one after the other with the following method (which works fine):

Quaternion quatLocal = new Quaternion(); // actual local rotation
Quaternion quatRotation = new Quaternion(); // rotation to add
// the extrinsic rotations round X, Y und Z-Axis are done one afther the other
quatLocal = this.node.getLocalRotation(); // actual rotation
quatRotation.fromAngleAxis(FastMath.DEG_TO_RAD * this.getRotX(), Vector3f.UNIT_X);
quatLocal = quatRotation.mult(quatLocal);
quatRotation.fromAngleAxis(FastMath.DEG_TO_RAD * this.getRotEwY(), Vector3f.UNIT_Y);
quatLocal = quatRotation.mult(quatLocal);
quatRotation.fromAngleAxis(FastMath.DEG_TO_RAD * this.getRotZ(), Vector3f.UNIT_Z);
quatLocal = quatRotation.mult(quatLocal);
node.setLocalRotation(quatLocal);

the problem is, that when I try to read the actual rotation from an existing node I get angles back in a different system.

node.getLocalRotation
float[] angles = node.getLocalRotation().toAngles(angles);
float x = Math.toDegrees(angles[0]);
float y = Math.toDegrees(angles[1]);
float z = Math.toDegrees(angles[2]);

I think itâ€™s because JME ist rotating in xzy-order and not in xyz-order like I do.
Thatâ€™s why i have to do the rotation axis after axis and can not use the method node.setLocalRotation()

For example in my system the rotation is (0,30,270)
But when I read the rotation from the node I get (150,180,90).

I would be very very happy if somebody would know a method how to transform the (150,180,90)(JME-system) into the (0,30,270)(my system).
It doesnâ€™t even matter if the result is different as long it fits into my system (because there are always several ways to get the same result when rotating.)

No. Itâ€™s because euler-style angles are ambiguous and quaternions are compact rotations. Every quaterion is unique (excluding the negative form) but euler-style angles are not unique. You can never really expect to get the same angle-triple back out of a quaternion that you put into it. Itâ€™s just part of the math.

Order does also come into play but thatâ€™s inherent in the quaterionâ€¦ where there is no order. Itâ€™s a compact rotation in axes at once.

Especially in an example like this. If you are already allowing angles to be something other than +/- 180 then you are going to have an infinite variation in what angle-triple can produce a particular quaternion. And even in that case, you can imagine how 0, 180, 0 could be the same as 180, 0, 180. Both would produce the same quaternion.

If you need the original angle-triple then you will have to keep the angle-triple and then never use JME to transform the rotationâ€¦ always reconstruct that rotation from your own. You lose the ability to compose rotations using Quaterions, though.

My description was wrong. Im not using 0Â°â€¦360Â° but -180Â°â€¦+180Â°.
But my problem stays the same.
It would be ok for me if I get back 0,180,0 or 180,0,180.
But I think the mathematics would be very complicated to transform that.
At the Moment I just use a table with which I translate the JME values into â€śmyâ€ť values.
Gladly I only need values in 15Â° or 30Â° steps. Example:

Okay, so youâ€™re applying the angles extrinsically in X,Y,Z order and you want to find some angles that would reproduce a given quaternion. The simple solution would be to store the angles alongside the quaternion, for instance in the nodeâ€™s user data:

Then you can get the angles back using (Float)node.getUserData("xDegrees") and so on.

But letâ€™s assume you have some reason not to do it that way. To avoid doing a ton of trigonometry, my next suggestion would be to convert the quaternion to an equivalent 3x3 rotation matrix, then use textbook formulas to find suitable angles: