0
votes

I am trying to rotate a first person view "camera" around it's own coordinates, instead, it is getting rotated around the origin. Here is my current code for the camera translation and rotation.

    if (Keyboard.isKeyDown(Keyboard.KEY_W)) {
        xMod -= 0.0025f * (float)delta * (float)Math.sin(Math.toRadians(camera.rotation.y));
        zMod += 0.0025f * (float)delta * (float)Math.cos(Math.toRadians(camera.rotation.y));
    }                
    if (Keyboard.isKeyDown(Keyboard.KEY_S)) {
        xMod += 0.0025f * (float)delta * (float)Math.sin(Math.toRadians(camera.rotation.y));
        zMod -= 0.0025f * (float)delta * (float)Math.cos(Math.toRadians(camera.rotation.y));
    }    
    if (Keyboard.isKeyDown(Keyboard.KEY_A)) {
        xMod -= 0.0025f * (float)delta * (float)Math.sin(Math.toRadians(camera.rotation.y-90));
        zMod += 0.0025f * (float)delta * (float)Math.cos(Math.toRadians(camera.rotation.y-90));
    }
    if (Keyboard.isKeyDown(Keyboard.KEY_D)) {
        xMod -= 0.0025f * (float)delta * (float)Math.sin(Math.toRadians(camera.rotation.y+90));
        zMod += 0.0025f * (float)delta * (float)Math.cos(Math.toRadians(camera.rotation.y+90));
    }

    if (Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) {
        Mouse.setGrabbed(false);
    }

    if (Mouse.isButtonDown(0)) {
        Mouse.setGrabbed(true);
    }

    if (Mouse.isGrabbed()) {
        camera.rotation.y += (Mouse.getDX() * 0.005f) * delta;
        camera.rotation.x += (Mouse.getDY() * -0.005f) * delta;
    }
    if (camera.rotation.x >= 90f) {
        camera.rotation.x = 90f;
    }

    else if (camera.rotation.x <= -90f) {
        camera.rotation.x = -90f;
    }

    if (Mouse.isGrabbed()) {
        camera.position.x += xMod;
        camera.position.z += zMod;
    }

    camera.reset();

    Matrix4f.translate(camera.rotation, camera.matrix(Camera.VIEWMATRIX), camera.matrix(Camera.VIEWMATRIX));
    Matrix4f.rotate(degToRad(camera.rotation.x), new Vector3f(1f,0f,0f), camera.matrix(Camera.VIEWMATRIX), camera.matrix(Camera.VIEWMATRIX));
    Matrix4f.rotate(degToRad(camera.rotation.y), new Vector3f(0f,1f,0f), camera.matrix(Camera.VIEWMATRIX), camera.matrix(Camera.VIEWMATRIX));
    Matrix4f.rotate(degToRad(camera.rotation.z), new Vector3f(0f,0f,1f), camera.matrix(Camera.VIEWMATRIX), camera.matrix(Camera.VIEWMATRIX));
    Matrix4f.scale(camera.scale, camera.matrix(Camera.VIEWMATRIX), camera.matrix(Camera.VIEWMATRIX));

camera.reset() does this...

public void reset() {
    viewMatrix = new Matrix4f();
}

essentially reseting the view matrix

also, camera.rotation is a vector3f and camera.matrix returns a matrix, either Camera.ViewMatrix or Camera.ProjectionMatrix

Thanks for your help.

1

1 Answers

0
votes

First of all

Matrix4f.translate(camera.rotation, camera.matrix(Camera.VIEWMATRIX), camera.matrix(Camera.VIEWMATRIX));

does not really make sense. I'll just assume you have camera.position here (that would be wrong, too, but I'm coming to that later.

You actually do translate the camera first, and then rotate (around the origin).

Now, you might think that it is the other way around as you might have learned that the matrix operations are applied in the reverse order - that is so, but only when you view the transformations as moving around the objects. With a classical view matrix, you place a camera in the world - which is exactly the inverse. Moving a camera in a world is exactly the same as having a fixed camera and inversely moving all objects of the world.

With marix math, (A * B) ^ -1 is the same as B^-1 * A^-1. so when you want to define the camera that way, you have to use the reverse order (of the reverse order, ending up in the order as you write things down), but with each transformation inverted. You will need the rotations with a negated angle, followed by a translation with the negated position, to make this work.