我通过QGLWidget
在Qt中使用OpenGL,我正在尝试实现一些基本的鼠标和键盘驱动的交互。
例如,键盘箭头键将用于“平移”场景,鼠标滚轮用于放大场景,鼠标应用于旋转模型。
我已经想出了如何实现平移和缩放,但是我在实现旋转方面遇到了麻烦。
这是我到目前为止所做的:
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
中,我会修改增量“[0]
字段以向左和向右平移,以及增量”[1]
用于向上和向下平移。
所以我的问题是,如何使用鼠标实现类似的支持旋转?我有点困惑,因为我猜我不仅要以某种方式改变相机的外观以及向上的向量,但我并不清楚如何做到这一点。
答案 0 :(得分: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是距离,θ是方位角,phi是赤纬。 这为您提供了从相机外观位置到相机位置的偏移。
所以这就是你做的。保持相机目标位置,但不保持相机位置。平移相机时,移动目标位置。旋转相机时,调整方位角和偏角。缩放相机时,请调整距离。然后,在调用gluLookAt之前的每一帧,使用上面的公式计算相机位置。您只需将x,y和z添加到目标位置。
答案 1 :(得分:0)
最好的办法是使用四元数。就像复数对于在2D中旋转非常有用一样,四元数非常适合3D旋转。
标准'围绕x,y,z轴旋转'可以工作,它会表现得很奇怪而且不像预期的那样。
您可以在http://content.gpwiki.org/index.php/OpenGL:Tutorials:Using_Quaternions_to_represent_rotation
获得有关所有这些内容的精彩教程