OpenGL链式翻译/轮换

时间:2015-09-23 16:45:33

标签: c++ opengl mfc rotation

我有一个通用的OpenGL 3D世界,在开始时以(0,0,0)为中心。我基于this code实施了标准轨迹球。这实现了旋转作为当前模型视图矩阵的小增量/变换,

// 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);

这部分完美无缺。但后来我想实现翻译,我也这样做也是模型视图矩阵的小增量,

glTranslatef(-dx, -dy, 0.f);

这也可以按预期工作(无论世界如何旋转,翻译都会与鼠标一起移动,即模型落后于鼠标。

当我在翻译后尝试旋转时出现问题:我希望旋转位于世界中心附近,但用户翻译后不会发生这种情况。我试图存储绝对翻译并对其进行补偿,但显然它不起作用。我做了以下的事情:

// 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);

当我应用旋转并因此围绕原点旋转场景时,如何存储绝对平移以补偿它?

或者,换句话说,当我有累积的转换法时,如何围绕原点旋转世界?

1 个答案:

答案 0 :(得分:2)

要翻译点(x,y),首先按(x,y)翻译,然后轮播,然后翻译-(x,y)

现在,如果您的世界已被M(某些矩阵)转换,则转换前的世界的起源位于M^-1 (0,0)

假设您的原始世界变换为M,并且您想要执行一些旋转R,但该旋转应该围绕原始原点,但旋转矩阵R表示为围绕点(0,0)的旋转(就像样式一样)。

然后R' = M R M^-1会生成一个新的矩阵R',其中包含围绕原始 R的{​​{1}}。然后(0,0)是表示从零开始的矩阵,然后执行M' = R' M,然后围绕原点执行M

如果您正在对某些模型进行累积变换,只需跟踪所述变换的乘积,同时修改场景。

或者,存储原始场景,而不是对其进行累积转换,始终应用R来获取当前场景。