Reputation: 1860
Is it possible to extract the yaw, pitch and roll information from the glm::mat4
?
(That is a world transformation matrix with the translation, rotation and scale already applied)
Here is some code that I'm experimenting with:
float yawDeg = 0;
float pitchDeg = 20;
float rollDeg = 80;
glm::mat4 transform = glm::eulerAngleYXZ(glm::radians(yawDeg), glm::radians(pitchDeg), glm::radians(rollDeg));
glm::quat rotation(transform); // Is this a correct way?
// glm::quat rotation(glm::quat_cast(transform)); // Gives the same results.
printf("pitch: %f\n", glm::degrees(glm::pitch(rotation))); // Output: 3.616443
printf("yaw: %f\n", glm::degrees(glm::yaw(rotation))); // Output: -19.683496
printf("roll: %f\n", glm::degrees(glm::roll(rotation))); // Output: 79.372414
But I'm getting some strange results, here are some values:
yawDeg=92, pitchDeg=0, rollDeg=0
results yaw: 88.0, pitch: 180.0, roll: 180.0
yawDeg=0, pitchDeg=92, rollDeg=0
results yaw: 0.0, pitch: 92.0, roll: 0.0
- Looks ok.
yawDeg=0, pitchDeg=0, rollDeg=92
results yaw: 0.0, pitch: 0.0, roll: 92.0
- Looks ok.
yawDeg=0, pitchDeg=10, rollDeg=92
results yaw: -9.993845, pitch: -0.352578, roll: 92.030830
I think maybe my glm::mat4
to glm::quat
conversion is incorrect?
Upvotes: 0
Views: 4442
Reputation: 51
Did you try using glm::eulerAngleYXZ
? (YXZ instead of XYZ). That way the rotation construction is returned in the same order as your input eulerAngles.
Upvotes: 0
Reputation: 11
There is one thing I'd like to add. Yaw degree from GLM is actually between −90°~90°. It's because GLM get the yaw angle from arcsine, and −90°~90° is the range of usual principal value you can get from that.
Here you can see a snippet of the code from the github of GLM, https://github.com/g-truc/glm/blob/master/glm/gtc/quaternion.inl#L41
Upvotes: 1
Reputation: 1860
The reason why I was getting those unexpected values was because in certain angles GLM is internally applying it's own angles. I.e for:
Input yawDeg=60, pitchDeg=0, rollDeg=0
we'll get yaw: 60.0, pitch: 0.0, roll: 0.0
- as expected.
And for:
Input yawDeg=92, pitchDeg=0, rollDeg=0
we'll get yaw: 88.0, pitch: 180.0, roll: 180.0
- modified!
If you would look visually at the 3D object with those transformations applied - all rotations should look ok even if GLM have modified the values internally.
Another thing I've noticed is that Euler angles returned by GLM are always in the range of -180, 180 degrees for all axis.
Regarding the glm::mat4
to glm::quat
conversion. I was doing everyting ~ok. The important thing to note here is that if you're using scaling in your transformation matrix, you need to normalize your quaternion!
glm::quat rotation = glm::normalize(glm::quat_cast(matrix));
Another thing I found was that GLM has a function called glm::extractEulerAngleXYZ
. So if you just want to extract Euler angles from your transformation matrix, you don't really need to do any conversion to the quaternion.
I'm still not fully satisfied, because I did not find any way to convert GLM's Euler angle values back to the original values that were provided by the user.
Upvotes: 0