Android:GLES 20 的相机旋转问题
Android: Camera rotation issues with GLES 20
我已经在 3D Space 中移动了我的相机 (mViewMatrix),每个角度 x、y、z 移动了 15°(所有角度都是 0°,我对相机旋转没有任何问题!)
3D Space 中的所有对象都很好(显示在屏幕右下角)。
好的,现在我想围绕X轴旋转Camera。右下角的对象应该在右侧从下向上移动。
但是...由于更改了 15° 的摄像机角度...对象不仅在右侧从下向上移动...它们还从右向左移动了一点点。
我想我必须更改矢量:
Matrix.setRotateM(mViewMatrix, 0, 15, 0, 1, 0);
至:
Matrix.setRotateM(mViewMatrix, 0, 15, cameraVector.x, cameraVector.y, cameraVector.z);
...或者什么的。
这就是我所做的(我知道我必须使用旋转矩阵,但这里我 post 编辑了简单的代码,只是为了便于阅读的原因):
Matrix.setIdentityM(mViewMatrix, 0);
Matrix.translateM(mViewMatrix, 0, 0, 0, -8);
Matrix.setRotateM(mViewMatrix, 0, 15 + angle, 1, 0, 0);
Matrix.setRotateM(mViewMatrix, 0, 15, 0, 1, 0);
Matrix.setRotateM(mViewMatrix, 0, 15, 0, 0, 1);
如果有人能 post 一个简单的工作演示代码就好了,因为我已经试了 5 天了,但我不知道如何修复它(我测试了很多)。
实际上您不能在 OpenGL 中旋转相机。相反,你应该 move/rotate 周围的物体。您需要将 model/view/projection 矩阵应用于每个正在渲染的对象。
你不必自己计算它们,你可以使用 android.graphics.matrix。您在代码中使用了它,但使用了错误的方法。要旋转你的相机,你应该使用方法。
Matrix.setLookAtM(float rm[], int rmOffset, float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ)
但是,您需要提供相机居中点的坐标。
幸运的是,找到这样一个点的坐标很容易,你只需要一点三角学知识和 3 行代码:
centerX = eyeX + ( float ) Math.cos( Math.toRadians( pitch ) ) * ( float ) Math.cos( Math.toRadians( yaw ) );
centerY = eyeY - ( float ) Math.sin( Math.toRadians( pitch ) );
centerZ =eyeZ + ( float ) Math.cos( Math.toRadians( pitch ) ) * ( float ) Math.sin( Math.toRadians( yaw ) );
Math.cos(双角)和 Math.sin(双角)接受 弧度 的角度,因此您应该使用 [=25] 将它们转换为弧度=](双角)。这些函数 return 类型为双精度值,因此您需要将它们转换为浮点数,因为 Matrix class 函数接受浮点数作为坐标。
这是完整的工作代码:
float pitch = 0;
float yaw = 90;
float roll = -90;
lookX = eyeX + ( float ) Math.cos( Math.toRadians( pitch ) ) * ( float ) Math.cos( Math.toRadians( yaw ) );
lookY = eyeY - ( float ) Math.sin( Math.toRadians( pitch ) );
lookZ = eyeZ + ( float ) Math.cos( Math.toRadians( pitch ) ) * ( float ) Math.sin( Math.toRadians( yaw ) );
upX = (float) Math.cos(Math.toRadians( roll ));
upY = (float) -Math.sin(Math.toRadians( roll ));
Matrix.setIdentityM(mViewMatrix, 0);
Matrix.setLookAtM(mViewMatrix, 0, eyeX, eyeY, eyeZ, lookX, lookY, lookZ, upX, upY, upZ);
我已经在 3D Space 中移动了我的相机 (mViewMatrix),每个角度 x、y、z 移动了 15°(所有角度都是 0°,我对相机旋转没有任何问题!)
3D Space 中的所有对象都很好(显示在屏幕右下角)。
好的,现在我想围绕X轴旋转Camera。右下角的对象应该在右侧从下向上移动。
但是...由于更改了 15° 的摄像机角度...对象不仅在右侧从下向上移动...它们还从右向左移动了一点点。
我想我必须更改矢量:
Matrix.setRotateM(mViewMatrix, 0, 15, 0, 1, 0);
至:
Matrix.setRotateM(mViewMatrix, 0, 15, cameraVector.x, cameraVector.y, cameraVector.z);
...或者什么的。
这就是我所做的(我知道我必须使用旋转矩阵,但这里我 post 编辑了简单的代码,只是为了便于阅读的原因):
Matrix.setIdentityM(mViewMatrix, 0);
Matrix.translateM(mViewMatrix, 0, 0, 0, -8);
Matrix.setRotateM(mViewMatrix, 0, 15 + angle, 1, 0, 0);
Matrix.setRotateM(mViewMatrix, 0, 15, 0, 1, 0);
Matrix.setRotateM(mViewMatrix, 0, 15, 0, 0, 1);
如果有人能 post 一个简单的工作演示代码就好了,因为我已经试了 5 天了,但我不知道如何修复它(我测试了很多)。
实际上您不能在 OpenGL 中旋转相机。相反,你应该 move/rotate 周围的物体。您需要将 model/view/projection 矩阵应用于每个正在渲染的对象。 你不必自己计算它们,你可以使用 android.graphics.matrix。您在代码中使用了它,但使用了错误的方法。要旋转你的相机,你应该使用方法。
Matrix.setLookAtM(float rm[], int rmOffset, float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ)
但是,您需要提供相机居中点的坐标。 幸运的是,找到这样一个点的坐标很容易,你只需要一点三角学知识和 3 行代码:
centerX = eyeX + ( float ) Math.cos( Math.toRadians( pitch ) ) * ( float ) Math.cos( Math.toRadians( yaw ) );
centerY = eyeY - ( float ) Math.sin( Math.toRadians( pitch ) );
centerZ =eyeZ + ( float ) Math.cos( Math.toRadians( pitch ) ) * ( float ) Math.sin( Math.toRadians( yaw ) );
Math.cos(双角)和 Math.sin(双角)接受 弧度 的角度,因此您应该使用 [=25] 将它们转换为弧度=](双角)。这些函数 return 类型为双精度值,因此您需要将它们转换为浮点数,因为 Matrix class 函数接受浮点数作为坐标。
这是完整的工作代码:
float pitch = 0;
float yaw = 90;
float roll = -90;
lookX = eyeX + ( float ) Math.cos( Math.toRadians( pitch ) ) * ( float ) Math.cos( Math.toRadians( yaw ) );
lookY = eyeY - ( float ) Math.sin( Math.toRadians( pitch ) );
lookZ = eyeZ + ( float ) Math.cos( Math.toRadians( pitch ) ) * ( float ) Math.sin( Math.toRadians( yaw ) );
upX = (float) Math.cos(Math.toRadians( roll ));
upY = (float) -Math.sin(Math.toRadians( roll ));
Matrix.setIdentityM(mViewMatrix, 0);
Matrix.setLookAtM(mViewMatrix, 0, eyeX, eyeY, eyeZ, lookX, lookY, lookZ, upX, upY, upZ);