我在尝试用 Java 制作以与 OpenGL 绑定 LWJGL 一起使用的 3D 虚拟相机时遇到问题。问题是我希望相机能够跟随与 FPS 相同的运动。我的意思是围绕 Y 轴(左右)进行旋转,我希望它围绕固定轴旋转。因此,当他们围绕 X 轴向下看 45 度然后向左看时,我希望围绕固定的 (0, 1, 0) 轴而不是新转换的 Y 轴进行旋转。
目前,当前系统通过围绕任意轴创建旋转来工作,该轴作为旋转方法的参数。在 rotateY 方法中,我将向上向量替换为硬编码的固定向上指向 Y 轴 (0, 1, 0),尽管这似乎不起作用。它只是表现得好像它围绕任意 Y 轴旋转。
这是 Camera 类的源代码:
public class Camera {
public Vector4f pos, side, up, forward;
public Camera() {
pos = new Vector4f(0f, 2f, 0f);
side = new Vector4f(1.0f, 0.0f, 0.0f);
up = new Vector4f(0.0f, 1.0f, 0.0f);
forward = new Vector4f(0.0f, 0.0f, 1.0f);
}
public void rotateX(float delta) {
delta = (float) Math.toRadians(delta);
Matrix4f mat = createRotation(delta, side.x, side.y, side.z);
Vector4f n_up = Vector4f.multiply(mat, up);
Vector4f n_forward = Vector4f.cross(side, n_up);
n_up.normalise();
n_forward.normalise();
up = n_up;
forward = n_forward;
}
public void rotateY(float delta) {
delta = (float) Math.toRadians(delta);
Matrix4f mat = createRotation(delta, up.x, up.y, up.z);
Vector4f n_side = Vector4f.multiply(mat, side);
Vector4f n_forward = Vector4f.cross(n_side, up);
n_side.normalise();
n_forward.normalise();
side = n_side;
forward = n_forward;
}
public Matrix4f createRotation(float angle, float x, float y, float z) {
float cos = (float) Math.cos(angle);
float sin = (float) Math.sin(angle);
float one_c = 1.0f - cos;
float xx = x * x;
float yy = y * y;
float zz = z * z;
float xy = x * y;
float xz = x * z;
float yz = y * z;
float xs = x * sin;
float ys = y * sin;
float zs = z * sin;
float mag = (float) Math.sqrt(xx + yy + zz);
if(mag == 0.0f) {
float[] ident = new float[] {
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
};
return new Matrix4f(ident);
}
x /= mag;
y /= mag;
z /= mag;
Matrix4f m = new Matrix4f();
m.set(new float[] {
(one_c * xx) + cos,
(one_c * xy) - zs,
(one_c * xz) + ys,
0.0f,
(one_c * xy) + zs,
(one_c * yy) + cos,
(one_c * yz) - xs,
0.0f,
(one_c * xz) - ys,
(one_c * yz) + xs,
(one_c * zz) + cos,
0.0f,
0.0f, 0.0f, 0.0f, 1.0f
});
return m;
}
public void transform() {
GL11.glMultMatrix((FloatBuffer) BufferUtils.createFloatBuffer(16).put(new float[] {
side.x, up.x, forward.x, 0.0f,
side.y, up.y, forward.y, 0.0f,
side.z, up.z, forward.z, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
}).flip());
GL11.glTranslatef(-pos.x, -pos.y, -pos.z);
}
}
我尝试禁用第 15 行,这样 Y 轴就不会被转换,但这会使视图非常倾斜并且不显示任何 X 轴旋转。谁能看到我在这里出错的地方?
编辑:一直在玩它并更新了上面的代码。我找到了倾斜形状的来源。通过标准化每个新向量来解决这个问题。
我似乎无法弄清楚我如何围绕 (0, 1, 0) 旋转而不是转换后的 Y 坐标,但视图变得倾斜。我确实希望相机能够上下查看(X 轴旋转),但我也希望 Y 轴有效地保持在同一方向。在 FPS 中,所有轴都从其先前旋转的方向自由旋转,但是当它们向下看并向左转时,它们有点绕原始 Y 轴旋转,而不是旋转的 Y 轴。这实现起来相当简单吗?