尝试围绕固定的Y轴旋转3D OpenGL / LWJGL相机

时间:2013-08-14 15:20:42

标签: java opengl 3d camera rotation

我遇到了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轴而不是旋转的轴旋转。这实现起来相当简单吗?

0 个答案:

没有答案