0
votes

I have been wondering how I can get my FPS camera to basically move forward and backward depending on the camera's direction, but I've been failing miserably, I would like to know the way to do this optimally, as right now my code is switch directions behind my triangle (w becomes s and s becomes w) and generally not work (move diagonally instead of forward, sometimes), rotation works perfectly, but translation screws up my matrix...

void glfwCursorCallback(GLFWwindow* window, double x, double y) {
    camera.rx += (x - camera.lcx) * 0.01f;
    camera.ry += (y - camera.lcy) * 0.01f;
    kmMat4RotationYawPitchRoll(&camera.mat, camera.ry , camera.rx, 0.0f);
    camera.lcx = x;
    camera.lcy = y;
}
...
kmMat4PerspectiveProjection(&projection, 90.0f, aspect, 0.1f, 1000.f);
float x = 0.0f, y = 0.0f, z = -1.0f;
while(!glfwWindowShouldClose(window)) {
    if(glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) {
        /* pitch - ry */
        x += 0.1*sin(camera.ry)*cos(camera.rx);
        y += 0.1*sin(camera.ry)*sin(camera.rx);
        z += 0.1*cos(camera.ry);
    }
    if(glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) {
        x -= 0.1*sin(camera.ry)*cos(camera.rx);
        y -= 0.1*sin(camera.ry)*sin(camera.rx);
        z -= 0.1*cos(camera.ry);
    }

    glClear(GL_COLOR_BUFFER_BIT);
    kmMat4Translation(&transform, x, y, z);
    kmMat4Multiply(&object, &camera.mat, &transform);
    kmMat4Multiply(&final, &projection, &object);
    glUniformMatrix4fv(shader.mpm, 1, GL_FALSE, final.mat);
    ...

I have no idea how to do it since I never did it before, so I would love some pointers from the more experienced folk around here!

Edit: The purpose is to have the camera move forward according to orientation. Also, It works perfectly if i omit x, y and just set z to +- 0.1... so it's not an issue of matrix multiplications

1

1 Answers

0
votes

While in the world the X-axis is pointing to the right, the Y-axis to the front, and the Z-axis to the top,on the viewport the X-axis points to the left, the Y-axis up and the Z-axis out of the view (Note in a right hand system the Z-Axis is the cross product of the X-Axis and the Y-Axis).

world to view

Each point and each vector from the reference system of the scene must therefore be converted first into viewport coordinates. This can be easily processed by the following table:

 x  y  z
--------
 1  0  0  | x' =  x
 0  0  1  | y' =  z
 0 -1  0  | z' = -y


Further you have to incrementally change the camera matrix and not to sum up the movements and rotations. This means you have to calculate the current movement and current rotation matrix. Apply the movement and rotation to the camera and keep the camera for the next cycle of the loop. At the next cycle of the loop you have to use the manipulated camera from the previous cycle and you have to apply the new movement and rotation. This causes that the camera incremental changes, always based on its current position and orientation.

movement and rotation


Your code should look somehow like this:

double currenYaw    = 0.0;
double currentPitch = 0.0;
double currentX     = 0.0;
double currentY     = 0.0;

void glfwCursorCallback( GLFWwindow* window, double x, double y )
{
    currenYaw    += (x - currentX) * 0.01;
    currentPitch += (currentY - y) * 0.01;
    currentX      = x;
    currentY      = y;
}

glfwGetCursorPos( _wnd, &currentX, &currentY );
while(!glfwWindowShouldClose(window)) {

    float x = 0.0f, y = 0.0f, z = 0.0f;
    if ( glfwGetKey(_wnd, GLFW_KEY_W) == GLFW_PRESS )
        y = 0.1f;
    if ( glfwGetKey(_wnd, GLFW_KEY_S) == GLFW_PRESS ) {
        y = -0.1f;
    if ( glfwGetKey(_wnd, GLFW_KEY_D) == GLFW_PRESS )
        x = 0.1f;
    if ( glfwGetKey(_wnd, GLFW_KEY_A) == GLFW_PRESS ) {
        x = -0.1f;
    if ( glfwGetKey(_wnd, GLFW_KEY_Q) == GLFW_PRESS )
        z = -0.1f;
    if ( glfwGetKey(_wnd, GLFW_KEY_E) == GLFW_PRESS ) {
        z = 0.1f;

    // movment
    kmMat4 yaw_matrix; 
    kmMat4Translation( &transform, x, z, -y );

    // yaw
    kmMat4 yaw_matrix;
    kmMat4RotationY( &yaw_matrix, currenYaw );
    currenYaw = 0.0;

    // pitch
    kmMat4 pitch_matrix;
    kmMat4RotationX( &pitch_matrix, currentPitch );
    currentPitch = 0.0;

    // roatation = pitch_matrix * yaw_matrix
    kmMat4 roatation;
    kmMat4Multiply( &roatation, &yaw_matrix, &yaw_matrix );

    // change the camera matrix incrementally
    kmMat4Multiply( &camera.mat, &transform, &camera.mat );
    kmMat4Multiply( &camera.mat, &roatation, &camera.mat );

    ....
}


Seet further: