我遇到了3D虚拟相机的问题,我正试图用Java生成OpenGL绑定LWJGL。问题是我希望相机能够遵循与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轴而不是旋转的轴旋转。这实现起来相当简单吗?