我一直在寻找,但找不到这个看似简单问题的答案。我有一个3d空间,我的相机有x,y,z,偏航,俯仰和滚动变量,我希望能够将摄像机向前移动到我正在看的任何地方。大多数Camera类都有这样的东西:
//moves the camera forward relitive to its current rotation (yaw)
public void walkForward(float distance)
{
position.x -= distance * (float)Math.sin(Math.toRadians(yaw));
position.z += distance * (float)Math.cos(Math.toRadians(yaw));
}
这可以很好地根据你的偏航向前移动,但你的y位置永远不会改变。如何将其更改为相对于您的音高,以便您始终朝着相机所看到的任何方向移动?
编辑:
通过向前移动,我的意思是通过在每个轴上移动相机一定量,这个数量取决于你的偏航,俯仰和滚动,无论你面前的什么,都会变得更大。可以使用:
position.x += -Math.sin(Math.toRadians(rotation.y)) * Math.cos(Math.toRadians(rotation.x)) * distance;
position.z += Math.cos(Math.toRadians(rotation.y)) * Math.cos(Math.toRadians(rotation.x)) * distance;
position.y -= -Math.sin(Math.toRadians(rotation.x)) * distance;
注意:rotation.y = yaw,rotation.x = pitch,rotation.z将会滚动。距离只是移动多少,比方说0.1。
如果您不更改相机的滚动(在z轴上旋转),这将起作用,否则不会。这篇文章现在可能与this非常相似,但我不知道如何应用矩阵乘法,这是我的相机类的解决方案,看起来像这样
public class Camera
{
// Field Of View
private float fov;
// Aspect Ratio
private float aspect;
// Near Plane
private float zNear;
// Far Plane
private float zFar;
// Projection matrix
private Matrix4f projection;
// View matrix
private Matrix4f view;
// Camera position
private Vector3f position;
// Camera rotation
private Vector3f rotation;
// Vectors for axes
private Vector3f xAxis, yAxis, zAxis;
/**
* Creates a simple 3D Perspective Camera.
*
* @param fov The field of view in degrees.
* @param aspect The aspect ratio.
* @param zNear The near clipping plane.
* @param zFar The far clipping plane.
*/
public Camera(float fov, float aspect, float zNear, float zFar)
{
// Set the local variables
this.fov = fov;
this.aspect = aspect;
this.zNear = zNear;
this.zFar = zFar;
// Create matrices
projection = MatrixUtil.createPerspectiveProjection(fov, aspect, zNear, zFar);
view = MatrixUtil.createIdentityMatrix();
// Initialize position and rotation vectors
position = new Vector3f(0, 0, 0);
rotation = new Vector3f(0, 0, 0);
// Create normalized axis vectors
xAxis = new Vector3f(1, 0, 0);
yAxis = new Vector3f(0, 1, 0);
zAxis = new Vector3f(0, 0, 1);
// Enable depth testing
glEnable(GL_DEPTH_TEST);
}
/**
* Apply the camera's transformations.
*/
public void apply()
{
// Make the view matrix an identity.
view.setIdentity();
// Rotate the view
Matrix4f.rotate((float) Math.toRadians(rotation.x), xAxis, view, view);
Matrix4f.rotate((float) Math.toRadians(rotation.y), yAxis, view, view);
Matrix4f.rotate((float) Math.toRadians(rotation.z), zAxis, view, view);
// Move the camera
Matrix4f.translate(position, view, view);
}
//moves the camera forward relitive to its current rotation (yaw and pitch)
public void moveForward(float distance)
{
position.x += -Math.sin(Math.toRadians(rotation.y)) * Math.cos(Math.toRadians(rotation.x)) * distance;
position.z += Math.cos(Math.toRadians(rotation.y)) * Math.cos(Math.toRadians(rotation.x)) * distance;
position.y -= -Math.sin(Math.toRadians(rotation.x)) * distance;
}
(此相机类基于this教程)
那么我怎样才能让相机向前移动,具体取决于它的偏航,俯仰和滚动。
答案 0 :(得分:1)
你有3次旋转:滚动,偏航和俯仰。这些也可以想象为在3d空间中在平面上绘制的盘上的点:xy-平面(roll),xz-平面(yaw),zy-平面(pitch)。
为了帮助您想象这一点,假设您在一个立方体内。立方体有6个面,每个面都有一个圆圈。你下方和上方的2面是xz平面;在你的右边和左边是zy飞机;正面和背面是熟悉的xy飞机。
您的示例是围绕xz平面上绘制的圆心旋转。当飞机偏航时,它显然不会改变它的音高。卷(xy)看起来像:
position.x -= distance * (float)Math.cos(Math.toRadians(amount));
position.y += distance * (float)Math.sin(Math.toRadians(amount));
您可能需要更改标志,因为我不确定如何实施。
在xy平面(典型的2d视图)上,如果绘制一个半径为r的圆,则角度θ上圆上的任何点都可以由P(r * cos(theta),r * sin(theta)给出)。在3d空间中,您有3个平面,并且您必须在所有平面上应用相同的逻辑,以便在该平面上找到适当的旋转值。
但是,我不确定“向前移动相机”是什么意思。