Quaternion-to-matrix identity rotated
📽 Optimized OpenGL/Graphics Math (glm) for C
Brought to you by:
recp
Originally created by: winduptoy
I'm seeing the following behavior for quaternion to matrix conversion.
versor rotation = GLM_QUAT_IDENTITY_INIT;
fprintf(stderr, "-- Quaternion --\n%.4f %.4f %.4f %.4f\n\n", rotation[0], rotation[1], rotation[2], rotation[3]);
mat4 rotMatrix = GLM_MAT4_IDENTITY_INIT;
glm_quat_mat4(rotation, rotMatrix);
fprintf(stderr, "-- Matrix --\n%.4f %.4f %.4f %.4f\n%.4f %.4f %.4f %.4f\n%.4f %.4f %.4f %.4f\n%.4f %.4f %.4f %.4f\n", rotMatrix[0][0], rotMatrix[0][1], rotMatrix[0][2], rotMatrix[0][3], rotMatrix[1][0], rotMatrix[1][1], rotMatrix[1][2], rotMatrix[1][3], rotMatrix[2][0], rotMatrix[2][1], rotMatrix[2][2], rotMatrix[2][3], rotMatrix[3][0], rotMatrix[3][1], rotMatrix[3][2], rotMatrix[3][3]);
outputs
-- Quaternion --
0.0000 0.0000 0.0000 1.0000
-- Matrix --
-1.0000 0.0000 0.0000 0.0000
0.0000 -1.0000 0.0000 0.0000
0.0000 0.0000 1.0000 0.0000
0.0000 0.0000 0.0000 1.0000
The identity quaternion is what I expect, but the matrix seems to be flipped 180 degrees on X and Y. I noticed this because everything I render is flipped upside down. Shouldn't rotMatrix[0][0] and rotMatrix[1][1] equal positive 1 instead of negative 1 when using an identity quaternion? Or maybe I don't understand quaternions fully.
Platform:
Linux 64-bit
gcc v7.2.1
cglm v0.3.1
Originally posted by: winduptoy
@recp Any ideas on this?
Originally posted by: recp
@winduptoy sorry I didn't see this issue until now, fell free to ping me again
I think identity versor (GLM_QUAT_IDENTITY_INIT) is wrong.
gives {1.0f, 0.0f, 0.0f, 0.0f} so it must be
but
GLM_QUAT_IDENTITY_INIT {0.0f, 0.0f, 0.0f, 0.0f}also seems valid for your case. I'll fix this ASAP, but if you want to fix that, PR is welcome :)These functions also creates versor for you:
q is out parameter, I must change its name.
Addition
You don't have to initialize dest (or out) parameters. In your case you dont have to initialize
rotMatrixbecause it is dest/out parameter which means glm_quat_mat4 is already creating matrix for you. But [in, out] parameter may need to be initialized e.g.glm_vec_normalize(vec) vec is in and out, read the header file. I will add docs to quad header toowould be enough, but since function is inline I think compiler will ignore identity initialization (I hope)
Also I would use built-in print utils to print them, it would save you to write huge printf :)
Print matrix:
glm_mat4_print(rotMatrix, stderr);Print Versor:
glm_versor_print(rotation2, stderr);Print Vec3:
glm_vec3_print(vec, stderr)Print Vec4:
glm_vec4_print(vec, stderr)Important
Some resources / tools / libraries may use
x, y, z, worder but cglm usesw, x, y, zorder to represent quaternion: [angle, axis]So you may see Quaternion.Identity = [0, 0, 0, 1] in MSDN or Unity or somewhere else, but it is [1, 0, 0, 0] in cglm and some other libraries
I doesn't matter for me, if it must be x, y, z, w then we can change this.
Originally posted by: winduptoy
Ah thank you for pointing out the print functions! I must have missed those. I'd like to help you with documentation soon.
I did not realize that cglm used
w, x, y, z, I simply assumed it wasx, y, z, w. I don't really have a preference, but I think it would be important to document this in a very visible place.Thank you! Hope you had a good holiday wherever in the world you may be.
Originally posted by: recp
That would be wonderful
I'm confused now, probably most people may assume that is x, y, z, w. For C++ classes probably most people accessing those values by ctor or its name like quat->x, quat->w so it doesn't matter for them I think, but since we have stored them as array order is matter. versor is stored as vec4 (aligned) because it is perfectly fits with SIMD instuctions to optimize them. Maybe documentation would prevent any confusion here
Thank you very much, I hope you too.
Ticket changed by: recp
Originally posted by: recp
Fixed by: https://github.com/recp/cglm/pull/11