簡體   English   中英

如何將我的相機直接旋轉到鼠標光標,並進行任何旋轉?

[英]How to move my camera straight to mouse cursor, with any rotation?

我正在使用LWJGL創建Java 3D游戲。 我是游戲的第一人稱視角,玩家可以用鼠標“轉動”相機(它實際上根據相機的旋轉移動所有其他對象)。

我正在嘗試從攝像機的俯仰,偏航和橫滾獲得3d矢量。 當我按W時,它應將相機X增加矢量X乘以速度,它也應與相機Y和Z相同。 這應該使攝像機直接移動到我的鼠標光標正在查看的位置(鼠標光標始終設置在屏幕的中間)。

目前,只要攝像機的橫搖角(Z旋轉)為0,此方法就可以正常工作。當攝像機的橫搖角不為0時,它將攝像機/播放器向錯誤的方向移動。

我想做的就是使相機朝我的光標移動,即使橫搖不等於0。

我的頂點着色器代碼如下(這似乎很相關,因為此處是計算渲染位置):

#version 400 core

in vec3 position;
in vec2 textureCoords;
in vec3 normal;

out vec2 passTextureCoords;
out vec3 surfaceNormal;
out vec3 toLightVector;

uniform mat4 projectionMatrix;
uniform mat4 transformationMatrix;
uniform mat4 viewMatrix;
uniform vec3 lightPosition;

void main(void){
    vec4 worldPosition = transformationMatrix * vec4(position,1.0);
    gl_Position = projectionMatrix * viewMatrix * worldPosition;
    passTextureCoords = textureCoords;
    surfaceNormal = (transformationMatrix * vec4(normal,0.0)).xyz;
    toLightVector = lightPosition - worldPosition.xyz;
}

位置vec3只是對象的世界位置。 下面的代碼計算了transformationMatrix和視圖矩陣:

public static final Matrix4f createTransformationMatrix(Vector3f position,     float rx, float ry, float rz, float size){
    Matrix4f matrix = new Matrix4f();
    matrix.setIdentity();
    Matrix4f.translate(position, matrix, matrix);
    Matrix4f.rotate((float) toRadians(rz), new Vector3f(0, 0, 1), matrix, matrix);
    Matrix4f.rotate((float) toRadians(ry), new Vector3f(0, 1, 0), matrix, matrix);
    Matrix4f.rotate((float) toRadians(rx), new Vector3f(1, 0, 0), matrix, matrix);
    Matrix4f.scale(new Vector3f(size, size, size), matrix, matrix);
    return matrix;
}

public static final Matrix4f createViewMatrix(Camera camera){
    Matrix4f view = new Matrix4f();
    view.setIdentity();
    Matrix4f.rotate(camera.getRadPitch(), new Vector3f(1, 0, 0), view, view);
    Matrix4f.rotate(camera.getRadYaw(), new Vector3f(0, 1, 0), view, view);
    Matrix4f.rotate(camera.getRadRoll(), new Vector3f(0, 0, 1), view, view);
    Vector3f c = camera.getPosition();
    Vector3f invert = new Vector3f(-c.x, -c.y, -c.z);
    Matrix4f.translate(invert, view, view);
    return view;
}

我很想知道為什么在代碼中不能只使用滾動旋轉,但是我對矩陣不是很了解。

我試圖獲得向量,以將照相機的運動與以下代碼相乘:

public static final Vector3f getRotationVector(float pitch, float yaw, float roll){
    Matrix4f mat = createTransformationMatrix(Game.getCamera().getPosition(), pitch, yaw, roll, 1);
    return new Vector3f(mat.m20, mat.m21, -mat.m22);
}

這是我更新旋轉和位置的相機代碼,稱為每幀:

public void update(){
    super.update();
    int midX = Display.getWidth() / 2;
    int midY = Display.getHeight() / 2;
    int mx = Mouse.getDX();
    int my = Mouse.getDY();
    if(rotationX > 360)
        rotationX -= 360;
    if(rotationX < 0)
        rotationX += 360;
    if(rotationY > 360)
        rotationY -= 360;
    if(rotationY < 0)
        rotationY += 360;
    if(rotationZ > 360)
        rotationZ -= 360;
    if(rotationZ < 0)
        rotationZ += 360;
    if(mouseMoved){
        mouseMoved = false;
        mx = 0;
        my = 0;
    }
    float speed = 0.02f;
    float rotateSpeed = 0.25f;
    if(Keyboard.isKeyDown(Keyboard.KEY_A)){
        Vector3f left = Maths.getRotationVector(-rotationX, rotationY - 90, rotationZ);
        move(left.x * speed, left.y * speed, left.z * speed);
    }
    if(Keyboard.isKeyDown(Keyboard.KEY_D)){
        Vector3f right = Maths.getRotationVector(rotationX, rotationY + 90, rotationZ);
        move(right.x * speed, right.y * speed, right.z * speed);
    }
    if(Keyboard.isKeyDown(Keyboard.KEY_W)){
        Vector3f forward = Maths.getRotationVector(rotationX, rotationY, rotationZ);
        move(forward.x * speed * 3, forward.y * speed * 3, forward.z * speed * 3);
    }
    if(Keyboard.isKeyDown(Keyboard.KEY_S)){
        Vector3f forward = Maths.getRotationVector(rotationX, rotationY, rotationZ);
        move(-forward.x * speed * 3, -forward.y * speed * 3, -forward.z * speed * 3);
    }
    if(Keyboard.isKeyDown(Keyboard.KEY_SPACE))
        position.y += speed;
    if(Keyboard.isKeyDown(Keyboard.KEY_LSHIFT))
        position.y -= speed;
    if(mx != 0 && Mouse.isInsideWindow() && wasMouse){
        rotationY += rotateSpeed * mx;
        Mouse.setCursorPosition(midX, midY);
        mouseMoved = true;
    }
    if(my != 0 && Mouse.isInsideWindow() && wasMouse){
        rotationX += rotateSpeed * -my;
        Mouse.setCursorPosition(midX, midY);
        mouseMoved = true;
    }
    if(Keyboard.isKeyDown(Keyboard.KEY_LCONTROL))
        rotationZ -= rotateSpeed;
    if(Keyboard.isKeyDown(Keyboard.KEY_RCONTROL))
        rotationZ += rotateSpeed;
    if(Keyboard.isKeyDown(Keyboard.KEY_M))
        System.out.println("rotationX = " + rotationX + " rotationY = " + rotationY + " rotationZ = " + rotationZ);
    if(Keyboard.isKeyDown(Keyboard.KEY_T))
        System.out.println(Maths.getRotationVector(getPitch(), getYaw(), getRoll()));
    if(Keyboard.isKeyDown(Keyboard.KEY_U)){
        motionX = 0;
        motionY = 0;
        motionZ = 0;
    }
    if(Keyboard.isKeyDown(Keyboard.KEY_X)){
        if(cooldown == 0){
            Vector3f forward = Maths.getRotationVector(rotationX, rotationY, rotationZ);
            world.spawnEntity(new Entity(new TexturedModel(Game.getLoader().loadModelToVAO("geometric/pyramid"), new ModelTexture(Game.getLoader().loadTexture("test 2"))), new Vector3f(position.x + forward.x * 2, position.y + forward.y * 2, position.z + forward.z * 2), rotationX, rotationY, rotationZ, 1f).addForce(rotationX, rotationY, rotationZ, 1000));
            cooldown = 120;
        }
    }
    if(!mouseMoved)
        wasMouse = Mouse.isInsideWindow();
    if(cooldown > 0)
        --cooldown;
}

有誰知道為什么我不能毫無問題地更換相機膠卷,或者如何使它工作?

在對情況進行了許多邏輯思考之后,我自己找到了一種方法。 在計算了X軸和Y軸的向量后,我對其進行了編輯,然后使用Z軸對其進行了編輯。 這可能是一種奇怪的方法,但至少可以起作用。

工作方法是這樣的:

public static final Vector3f getRotationVector(float pitch, float yaw, float roll){
    float r = (float) toRadians(roll);
    Matrix4f mat = createTransformationMatrix(new Vector3f(), pitch, yaw, 0, 1);
    Vector3f vector = new Vector3f(mat.m20, mat.m21, -mat.m22);
    return new Vector3f((float)(vector.x * cos(r) + vector.y * sin(r)), (float)(vector.y * cos(r) - vector.x * sin(r)), vector.z);
}

回答我自己的問題可能看起來有點愚蠢,但是我沒想到我在發布此文章時會設法自己解決問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM