glm combine rotation and translation

Jubei picture Jubei · Mar 29, 2012 · Viewed 22k times · Source

I have an object which I first want to rotate (about its own center) then translate it to some point. I have a glm::quat that holds the rotation and a glm::vec3 that holds the point to which it needs to be translated.

glm::vec3 position;
glm::quat orientation;
glm::mat4 modelmatrix; <-- want to combine them both in here

modelmatrix = glm::translate(glm::toMat4(orientation),position);

Then at my render function, I do.

pvm = projectionMatrix*viewMatrix*modelmatrix;
glUniformMatrix4fv(pvmMatrixUniformLocation, 1, GL_FALSE, glm::value_ptr(pvm));

..and render...

Unfortunately, the object just orbits around the origin when I apply a rotation (the farther the "position" from the origin, the larger the orbit).

When I apply for only the position it translates fine. When I apply only the rotation it stays at the origin and rotates about its center (as expected). So why does it go weird when I apply them both? Am I missing something basic?

Answer

Nicol Bolas picture Nicol Bolas · Mar 29, 2012

Because you're applying them in the wrong order. By doing glm::translate(glm::toMat4(orientation),position), you are doing the equivalent of this:

glm::mat4 rot = glm::toMat4(orientation);
glm::mat4 trans = glm::translate(glm::mat4(1.0f), position);
glm::mat4 final = rot * trans;

Note that the translation is on the right side of the matrix, not the left. This means that the translation happens first, then the rotation happens relative to the translation. So rotation happens in the space after translation.

You want the rotation to happen first. So reverse the order of the matrix multiplication.