Search code examples
openglgraphicscameraframe-rate

Converting from a crystal ball interface to FPS-style camera?


I currently have a crystal ball interface camera set-up where the camera is always looking at the origin and pressing left,right,up,down simply moves around the object.

I want to change this so that the camera can move around freely around the 3D environment.

I currently have two functions, LEFT and UP that have been implemented as the CB-interface I mentioned.

I want the left and right key to strafe left/right, while up/down to rise and sink the camera. How exactly would I go about changing it?

Also..what would be the proper way to move the camera forward and backward? I was thinking maybe draging the mouse could equate to moving foward/backward?

void Transform::left(float degrees, vec3& eye, vec3& up) {
eye = eye*rotate(degrees, up);
}


void Transform::up(float degrees, vec3& eye, vec3& up) {
vec3 ortho_axis = glm::cross(eye, up);
ortho_axis = glm::normalize(ortho_axis);

eye = eye*rotate(degrees, ortho_axis);
up = up*rotate(degrees, ortho_axis);
}

Solution

  • Basically throw away the entire code and start over. The camera in your scene behaves like any other object and thus has a position and orientation. (Or one transform matrix.) All you need to do is apply the opposite of the camera transformation.

    glTransformf(-camera.x, -camera.y, -camera.z);
    glRotatef(-camera.angle, camera.axis.x, camera.axis.y, camera.axis.z);
    

    You get the idea.

    What I do in my code is, since I have quaternions for rotation and converting that into a matrix or axis & angle is expensive, I compute the the forward and up vectors for the camera and feed that into gluLookAt.

    Vector3f f = transform(camera.orientation, Vector3f(1, 0, 0));
    Vector3f u = transform(camera.orientation, Vector3f(0, 0, 1));
    Vector3f p = camera.position;
    Vector3f c = p + f;
    gluLookAt(p.x, p.y, p.z, c.x, c.y, c.z, u.x, u.y. u.z);