I am trying to convert the orientation of an OpenVR controller that I have stored as a glm::vec3
of Euler angles into a glm::fquat
and back, but I get wildly different results and the in-game behavior is just wrong (hard to explain, but the orientation of the object behaves normally for a small range of angles, then flips in weird 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 expect eulerAnglesInDegrees
and result
to either be the same or equivalent representations of the same orientation, but that is apparently not the case. These are some example values I get printed out:
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 orientation ranges the conversion is correct, but for others it is completely different.
What am I doing wrong?
I've looked at existing questions and attempted a few things, including trying out every possible rotation order listed here, conjugating the quaternion, and other random things like flipping pitch/yaw/roll. Nothing gave me the expected result.
How can I convert euler angles to quaternions and back, 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 final computed
results, but it doesn't seem like there's one easy to identify.
GIF + video of the behavior:
Visual representation of my intuition/current understanding:
32.7636 144.849 44.3845 -147.236 35.1512 -135.616
Those are the same. Left 33 or right 147. You are 180 from each other. Now look up 145 - that's past up that's 35 from horizon, your back is arched. Now roll to get your back to the sky.
If you need to use Euler, try to keep pitch in -90 to +90, and roll in -180 to +180;
if (pitch > 90) {
pitch -= 90;
yaw += 180;
roll += 180;
}
if (roll > 180) {
roll = 360 - roll;
}
or something like that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With