在OpenGL中,我正在尝试创建一个免费的飞行摄像头。我的问题是Y轴上的旋转。摄像机应始终在Y世界轴上旋转,而不是在本地方向上旋转。我尝试了几次矩阵乘法,但都没有结果。与
camMatrix = camMatrix * yrotMatrix
沿着本地轴旋转相机。
camMatrix = yrotMatrix * camMatrix
沿着世界轴旋转相机,但始终围绕原点旋转。但是,旋转中心应该是相机。有人有点想法吗?
答案 0 :(得分:4)
3D编程的一个比较棘手的方面就是正确地进行复杂的转换。
在OpenGL中,每个点都用模型/视图矩阵转换,然后用投影矩阵转换。
模型视图矩阵获取每个点并将其从相机的视角转换到应该的位置。投影矩阵转换点的坐标,以便X和Y坐标可以轻松地映射到窗口。
要使模式/视图矩阵正确,您必须从单位矩阵(不改变顶点的矩阵)开始,然后对相机的位置和方向应用变换,然后为对象的位置和方向应用< em>按相反顺序。
您需要记住的另一件事是,旋转总是关于以原点(0,0,0)为中心的轴。因此,当你为相机应用旋转变换时,无论你是转动它(就像你转过头)或绕着原点绕轨道运行它绕地球轨道运行Sun)取决于您之前是否已应用翻译转换。
因此,如果你想旋转和环绕相机,你需要:
如果您想要将相机指向不是(0,0,0)的点并且还以该设定距离绕该点运行,那么事情会变得更加复杂,同时还能够俯仰或偏航相机。有关WebGL中的示例,请参阅here。寻找GLViewerBase.prototype.display
。
Red Book covers transforms in much more detail。
另请注意gluLookAt,您可以使用它来将相机指向,而无需使用旋转。
答案 1 :(得分:3)
您可能会发现创建一个存储位置和正交n
,u
和v
轴的相机类,并适当地旋转它们,而不是使用矩阵执行此操作。例如见:
https://github.com/sgolodetz/hesperus2/blob/master/Shipwreck/MapEditor/GUI/Camera.java
和
https://github.com/sgolodetz/hesperus2/blob/master/Shipwreck/MapEditor/Math/MathUtil.java
然后你写下这样的话:
if(m_keysDown[TURN_LEFT])
{
m_camera.rotate(new Vector3d(0,0,1), deltaAngle);
}
在设置相机视图时,您可以:
gl.glLoadIdentity();
glu.gluLookAt(m_position.x, m_position.y, m_position.z,
m_position.x + m_nVector.x, m_position.y + m_nVector.y, m_position.z + m_nVector.z,
m_vVector.x, m_vVector.y, m_vVector.z);
如果您想知道如何围绕像(0,0,1)
这样的任意轴进行旋转,请参阅上面代码中的MathUtil.rotate_about_axis
。
答案 2 :(得分:1)
如果您不想基于前一帧中的相机进行变换,我的建议可能就是抛弃矩阵复合并在每帧重新计算它。我不认为有一种方法可以用单个矩阵做你想要的,因为它存储了平移和旋转。
我想如果你只想要一个俯仰/偏航相机,只需将这些值存储为两个浮点数,然后根据它重建矩阵。也许像伪代码那样:
onFrameUpdate() {
newPos = camMatrix * (0,0,speed) //move forward along the camera axis
pitch += mouse_move_x;
yaw += mouse_move_y;
camMatrix = identity.translate(newPos)
camMatrix = rotate(camMatrix, (0,1,0), yaw)
camMatrix = rotate(camMatrix, (1,0,0), pitch)
}
答案 3 :(得分:0)
沿着世界轴旋转相机,但始终围绕原点旋转。但是,旋转中心应该是相机。有人有点想法吗?
我假设矩阵以这种方式存储在内存中(如果矩阵是线性1d数组,则数字表示元素索引):
0 1 2 3 //row 0
4 5 6 7 //row 1
8 9 10 11 //row 2
12 13 14 15 //row 3
<强>解决方案强>:
camMatrix = yrotMatrix * camMatrix