1

我在 Qt 中通过 OpenGL 使用 OpenGL QGLWidget,并且我正在尝试实现一些基本的鼠标和键盘驱动的交互。

例如,键盘方向键将用于“平移”场景,鼠标滚轮用于放大场景,鼠标用于旋转模型。

我已经想出了如何实现平移和缩放,但是在实现旋转时遇到了麻烦。

这是我到目前为止所拥有的:

void MyGLWidget::paintGL() {
    glLoadIdentity();
    gluLookAt(0+camDelta[0],0+camDelta[1],-100+camDelta[2],centerCoords[0]+lookAtDelta[0],centerCoords[1]+lookAtDelta[1],centerCoords[2]+lookAtDelta[2],0,1,0);
    // draw stuff here
}

所以基本上我设置了初始gluLookAt参数,然后我添加了两个数组float camDelta[3]float lookAtDelta[3],以跟踪相机位置的变化以及它正在寻找的位置以响应用户与场景的交互。

对于鼠标滚轮,我这样做:

void MyGLWidget::wheelEvent(QWheelEvent *event) {
    camDelta[2] += (event->delta() / 8.0 / 15.0) * WHEEL_DELTA;
    lookAtDelta[2] += (event->delta() / 8.0 / 15.0) * WHEEL_DELTA;
    updateGL();
}

同样在 中MyGLWidget::keyPressEvent,我修改了用于左右平移的 deltas 字段,以及用于上下平移的 deltas'[0]字段。[1]

所以我的问题是,我如何实现类似的东西来支持鼠标旋转?我有点困惑,因为我猜我不仅要改变相机的视线方向,还要改变向上的向量,但我对如何做到这一点并不清楚。

4

2 回答 2

3

我为这样的事情所做的就是所谓的轨道相机模型。

您可以跟踪摄像机目标位置(或观察方向)和 3 个其他参数:方位角、偏角(或倾角)和距离(或半径)。方位角是相机围绕目标水平旋转的角度(就好像目标在地面上,而您一边看着它一边绕着它走一圈)。偏角是垂直旋转。距离就是目标和相机之间的距离。

这些也称为球坐标:

http://mathworld.wolfram.com/SphericalCoordinates.html

你想要这样的方程:

x = r * sin(phi) * cos(theta)
y = r * sin(phi) * sin(theta)
z = r * cos(phi)

其中 r 是距离,theta 是方位角,phi 是偏角。这为您提供了从相机观察位置到相机位置的偏移量。

所以这就是你要做的。保留相机目标位置,但不保留相机位置。平移相机时,移动目标位置。旋转相机时,调整方位角和偏角。变焦相机时,调整距离。然后,在调用 gluLookAt 之前的每一帧,使用上述公式计算相机位置。您只需将 x、y 和 z 添加到目标位置。

于 2012-06-15T21:08:13.347 回答
0

最好的方法是使用四元数。就像复数在 2D 中旋转非常有用一样,四元数非常适合 3D 旋转。

标准的“围绕 x、y、z 轴旋转”可以工作,它的行为会很奇怪,而且不像预期的那样。

您可以在以下位置获得关于这一切的精彩教程:http://content.gpwiki.org/index.php/OpenGL:Tutorials: Using_Quaternions_to_represent_rotation

于 2012-06-15T21:29:12.227 回答