Reputation: 3130
I have a generic OpenGL 3D world, centered on (0,0,0) at start. I implemented a standard trackball, based on this code. This implements rotations as small increments/transformations to the current modelview matrix,
// We need to apply the rotation as the last transformation.
// 1. Get the current matrix and save it.
// 2. Set the matrix to the identity matrix (clear it).
// 3. Apply the trackball rotation.
// 4. Pre-multiply it by the saved matrix.
glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *)objectXform);
glLoadIdentity();
glRotatef(rot_angle, rotAxis.x, rotAxis.y, rotAxis.z);
glMultMatrixf((GLfloat *)objectXform);
This part works perfectly. But then I wantes to implement translations, and I am doing this also as small increments to the modelview matrix,
glTranslatef(-dx, -dy, 0.f);
This also works as expected (no matter how the world is rotated, the translation goes along with the mouse, i.e., the model goes behind the mouse.
The problem comes when I try to rotate after the translation: I want the rotation to be around the world center, but that will not happen after user translations. I tried to store the absolute translation and compensate for it, but obviously it does not work. I did it as folows:
// Translation part, store absolute translation
m_mouseInfo.m_fTotalTranslationX -= dx;
m_mouseInfo.m_fTotalTranslationY -= dy;
glTranslatef(-dx, -dy, 0.f);
...
// Rotation, try to apply the rotation around (0,0,0)
glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *)objectXform);
glLoadIdentity();
// Try to compensate for the translation and do the rotation aroun (0,0,0) but won't work
glTranslatef(m_mouseInfo.m_fTotalTranslationX, m_mouseInfo.m_fTotalTranslationY, 0.f);
glRotatef(rot_angle, rotAxis.x, rotAxis.y, rotAxis.z);
glTranslatef(-m_mouseInfo.m_fTotalTranslationX, -m_mouseInfo.m_fTotalTranslationY, 0.f);
glMultMatrixf((GLfloat *)objectXform);
How can I store the absolute translation to compensate for it when I apply the rotation and therefore rotate the scene around the origin?
Or, in other words, how can I just rotate the world around the origin when I have cumulative transfromations?
Upvotes: 1
Views: 302
Reputation: 275878
To translate around a point (x,y)
, first translate by (x,y)
, then rotate, then translate by -(x,y)
.
Now, if your world has been transformed by M
(some matrix), then the origin of the world before that transformation is located at M^-1 (0,0)
.
Suppose your world transformation from the original is M
, and you want to perform some rotation R
, but that rotation should be around the original origin, but the rotation matrix R
is expressed in terms rotation around the point (0,0)
(as is the style).
Then R' = M R M^-1
will generate a new matrix R'
that consists of rotating by R
around the original (0,0)
. Then M' = R' M
is the matrix that represents starting with nothing, and then doing M
, then doing R
around the origin.
If you are doing cumulative transformations on some model, simply keep track of the product of said transformations, along side modifying the scene.
Alternatively, store the original scene, and instead of doing cumulative transformations on it, always apply M
to get the current scene.
Upvotes: 2