如何使用glRotatef()和glTranslatef()在3D世界中逐步移动

我有一些3D模型,我在OpenGL中在3D空间中渲染,我在移动“角色”(即相机)时遇到了一些令人头痛的问题,在这个世界里有旋转和平移。 我从一些外部事件(图像用户输入或来自GPS +指南针设备的一些数据)接收输入(即,移动/转移dregrees的坐标),并且事件的类型是旋转或平移。 我写过这个方法来管理这些事件:
- (void)moveThePlayerPositionTranslatingLat:(double)translatedLat Long:(double)translatedLong andRotating:(double)degrees{

    [super startDrawingFrame];
    if (degrees != 0)
    {
        glRotatef(degrees, 0, 0, 1);
    }

    if (translatedLat != 0)
    {
        glTranslatef(translatedLat, -translatedLong, 0);
    }

   [self redrawView];
}
然后在
redrawView
我实际绘制场景和我的模型。它是这样的:
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

NSInteger nModels = [models count];

for (NSInteger i = 0; i < nModels; i++) 
{
    MD2Object * mdobj = [models objectAtIndex:i];
    glPushMatrix();
    double * deltas = calloc(sizeof(double),2);

    deltas[0] = currentCoords[0] - mdobj.modelPosition[0];
    deltas[1] = currentCoords[1] - mdobj.modelPosition[1];

    glTranslatef(deltas[0], -deltas[1], 0);

    free(deltas);
    [mdobj setupForRenderGL];
    [mdobj renderGL];   
    [mdobj cleanupAfterRenderGL];
    glPopMatrix();

}
[super drawView];
问题在于,当平移时,一个接一个地调用旋转事件:例如,当我逐渐旋转一些迭代(仍然在原点附近)然后我翻译并最终再次旋转但看起来最后一次旋转不会发生围绕当前(翻译)的位置,但围绕旧的(旧的原点)。我很清楚,当转换的顺序颠倒时会发生这种情况,但我相信在绘制之后,世界的新中心是由翻译系统给出的。 我错过了什么?我怎样才能解决这个问题? (任何对OpenGL的引用也将受到赞赏)     
已邀请:
我建议不要在事件处理程序中进行累积转换,而是在内部存储转换的当前值,然后只转换一次,但我不知道这是否是您想要的行为。 伪代码:
someEvent(lat, long, deg)
{
  currentLat += lat;
  currentLong += long;
  currentDeg += deg;
}

redraw()
{
  glClear()
  glRotatef(currentDeg, 0, 0, 1);
  glTranslatef(currentLat, -currentLong, 0);
  ... // draw stuff
}
    
听起来你有几件事情在这里发生: 首先,您需要知道关于原点的旋转。因此,当您翻译然后旋转时,您不会围绕您认为的原点旋转,而是旋转T-10的新原点(原点由您的平移的逆转换而来)。 其次,你制造的东西比你真正需要的要难得多。你可能想要考虑的是使用gluLookAt。你基本上给它在场景中的位置和场景中的一个点来查看和一个'向上'矢量,它将正确设置场景。要正确使用它,请跟踪摄像机所在的位置,调用矢量p和矢量n(正常...表示您正在查看的方向)和u(您的向上矢量)。如果n和u是正交向量(即它们彼此正交且具有单位长度),它将使更高级的特征更容易。如果你这样做,你可以计算r = n x u,(你的'右'向量),这将是与其他两个正交的正常向量。然后你'看'p + n并提供u作为向上矢量。 理想情况下,你的n,u和r有一些规范形式,例如:
n = <0, 0, 1>
u = <0, 1, 0>
r = <1, 0, 0>
然后,您逐步累积旋转并将它们应用于oritentation向量的规范。您可以使用Euler Rotations或Quaternion Rotations来累积您的旋转(由于各种原因,我真的很欣赏四元数方法)。     

要回复问题请先登录注册