实现俯仰和偏航时相机滚动

我在一个android游戏的opengl中实现一个摄像头,并有问题得到正确的相机的俯仰/偏航/滚动。 我已经阅读了很多关于四元数的教程,并且基于这个链接实现了一个基本的相机。

一切运作良好,除了当我俯仰和偏航时,我得到不必要的滚动。 我已经阅读了一些事情,说我需要一起应用俯仰/偏航旋转来防止这种情况,还有一些事情说不跟踪角度的个别变化,但我不确定它们是什么意思,或者如何将这个实现扩展到我的。 我是新的这种types的math,所以任何帮助将不胜感激。

我的目标是拥有一个可以旋转的相机,类似于太空飞船的旋转方式 – 我希望相机能够360°旋转,颠倒 – 这也是为什么我也在旋转upVector。

有什么建议,我可以做什么不让相机在Y轴和Y轴旋转时滚动?

谢谢!

以下是将用户input转换为两个角度的代码,并旋转相机的lookVector,upVector和rightVector。 我的问题是,当我只是俯仰和偏航时,摄像机也在滚动。

// Java // Camera uses a position vector, lookAt vector, and upVector // eventually calls Matrix.setLookAtM() Camera c = mRenderer.theCamera; // PVector is a class that implements a 3 dimensional vector float thetaX = getTouchChange(...); // set by the user touching the screen float thetaY = getTouchChange(...); // set by the user touching the screen // I keep 3 vectors in the camera class, one points up, one points right, // and the 3rd is the point I am looking at /////////////////////////////////////////////// // Pitch - rotate the up and look around right /////////////////////////////////////////////// // get up and look vectors PVector lookVector = PVector.sub(c.getLookAtPoint(), c.getLocation()); PVector otherVector = c.getUpDirection(); // get axis PVector rAxis = c.getRightDirection(); rAxis.normalize(); // rotate look PVector rotated = Quaternion.rotateVector(lookVector, rAxis, thetaY); // Add back camera location to convert vector to actual look points rotated.add(mRenderer.theCamera.getLocation()); c.setLookAtPoint(rotated); // rotate up rotated = Quaternion.rotateVector(otherVector, rAxis, thetaY); rotated.normalize(); c.setUpDirection(rotated); /////////////////////////////////////////////// // Yaw - rotate the look and right around up /////////////////////////////////////////////// // get up and look vectors lookVector = PVector.sub(c.getLookAtPoint(), c.getLocation()); otherVector = c.getRightDirection(); // get axis rAxis = c.getUpDirection(); rAxis.normalize(); // rotate look rotated = Quaternion.rotateVector(lookVector, rAxis, thetaX); // Add back camera location to convert vector to actual look points rotated.add(mRenderer.theCamera.getLocation()); c.setLookAtPoint(rotated); // rotate right rotated = Quaternion.rotateVector(otherVector, rAxis, thetaX); rotated.normalize(); c.setRightDirection(rotated); 

在我的渲染代码中,我通过调用以下方法来更新相机的方向

 // called in onSurfaceChanged Matrix.frustumM(m3DProjectionMatrix, 0, -screenRatio, screenRatio, -1, 1, 1, 70); // called in onDrawFrame Matrix.setLookAtM(m3DViewMatrix, 0, theCamera.getLocation().x, theCamera.getLocation().y, theCamera.getLocation().z, theCamera.getLookAtPoint().x, theCamera.getLookAtPoint().y, theCamera.getLookAtPoint().z, theCamera.getUpDirection().x, theCamera.getUpDirection().y, theCamera.getUpDirection().z); Matrix.multiplyMM(m3DMVPMatrix, 0, m3DProjectionMatrix, 0, m3DViewMatrix, 0); // m3DMVPMatrix is eventually passed to the shader along with the shape data 

我在C#中的openGL应用程序有完全相同的问题。 我一直在阅读,有人建议这实际上是现实的。

在本地参照系中,同时更改x和y轴也会导致z旋转。 你可以用笔testing一下。 把它指向空中,夹子朝向你。 旋转它,使点面向你,剪辑指向下。 然后旋转它,使点朝右,剪辑仍然朝下。 然后旋转它,使点朝上。 该剪辑现在面向右侧,这是az旋转,即使在笔参考框架中,您只执行x和y旋转。