opengl: the GLM conversion of the angles from euler to quaternion and vice versa is not maintained

I am trying to convert the orientation of an OpenVR controller that I have stored as glm::vec3 of Euler's angles in a glm::fquat and back, but I get very different results and the behavior in the game is simply wrong (difficult to explain, but the orientation of the object behaves normally for a small range of angles, then rotates in strange axes).

This is my conversion code:

// get `orientation` from OpenVR controller sensor data

const glm::vec3 eulerAnglesInDegrees{orientation(PITCH), orientation(YAW), orientation(ROLL)};
debugPrint(eulerAnglesInDegrees);

const glm::fquat quaternion{glm::radians(eulerAnglesInDegrees)};
const glm::vec3 result{glm::degrees(glm::eulerAngles(quaternion))};
debugPrint(result);

// `result` should represent the same orientation as `eulerAnglesInDegrees`

I would wait eulerAnglesInDegrees Y result be equal or equivalent representations of the same orientation, but apparently that is not the case. These are some example values ​​that print me:

39.3851 5.17816 3.29104 
39.3851 5.17816 3.29104 

32.7636 144.849 44.3845 
-147.236 35.1512 -135.616 

39.3851 5.17816 3.29104 
39.3851 5.17816 3.29104 

32.0103 137.415 45.1592 
-147.99 42.5846 -134.841 

As you can see above, for some targeting ranges, the conversion is correct, but for others it is completely different.

What am I doing wrong?

I have examined the existing questions and tried some things, including the test of each possible order of rotation listed here, to conjugate the quaternion and other random things like flipping the tone / yaw / roll. Nothing gave me the expected result.

How can I convert Euler's angles into quaternions and vice versa, representing the original orientation, using glm?


Some more examples of discrepancies:

original:      4; 175;   26; 
computed:   -175;   4; -153; 
difference:  179; 171;  179; 

original:     -6; 173;   32; 
computed:    173;   6; -147; 
difference: -179; 167;  179; 

original:      9; 268;  -46; 
computed:   -170; -88;  133; 
difference:  179; 356; -179; 

original:    -27; -73;  266; 
computed:    -27; -73;  -93; 
difference:    0;   0;  359; 

original:    -33; 111;  205; 
computed:    146;  68;   25; 
difference: -179;  43;  180; 

I tried to find a pattern to fix the end computed results, but there does not seem to be an easy one to identify.


GIF + behavior video:

Video excerpt


Visual representation of my current intuition / understanding:

Visual diagram

  • The image above shows a sphere, and I am in the center. When I point the weapon towards the green half of the sphere, the orientation is correct. When I point the weapon towards the red half of the sphere, it is incorrect: it seems that all the axes are inverted, but I am not 100% sure that it is so.