Third Person Camera

Hello all,

At the moment I have a cube in my 3D space in which I can do pitch, yaw and roll and move in the direction the cube is facing (like a plane). My camera currently just sits in one position and follows the cube with gluLookAt. What I’m trying to achieve with the camera however is to make it always behind the cube while it moves/pitches/yaws/rolls etc. like a third person camera.

So far, I’ve attempted to turn the camera while the cube turns, but my calculations seem to be wrong since the camera doesn’t turn in sync with the cube.

My code:



// Main.cpp

float pitch = 0, roll = 0, heading = 0;
float posX = 0, posY = 0, posZ = 0;
Camera camera;

void controls(){

    float turnRate = 0.001;

    // pitch
    if(keys['w']){
        pitch += 0.01;
        if(pitch > 360){
            pitch = 0;
        }
    }

    if(keys['s']){
        pitch -= 0.01;
        if(pitch < 0){
            pitch = 360;
        }
    }

    //heading
    if(keys['a']){
        heading += 0.01;
        if(heading > 360){
            heading = 0;
        }
        float yrotrad = (heading / 180 * 3.141592);
        camera.pos.x += cos(yrotrad) * turnRate; // turn camera aswell
        camera.pos.z -= sin(yrotrad) * turnRate;
    }

    if(keys['d']){
        heading 0= 0.01;
        if(heading < 0){
            heading = 360;
        }
        float yrotrad = (heading / 180 * 3.141592);
        camera.pos.x -= cos(yrotrad) * turnRate; // turn camera aswell
        camera.pos.z += sin(yrotrad) * turnRate;
    }

    //roll

    if(keys['q']){
        roll += 0.01;
        if(roll > 360){
            roll = 0;
        }
    }

    if(keys['e']){
        roll -= 0.01;
        if(roll < 0){
            roll = 360;
        }
    }

    // move forward

   if(keys['c']){
	float yrotrad = (-heading / 180 * 3.141592);
	float xrotrad = (-pitch / 180 * 3.141592);
	posX += sin(yrotrad) * rate;
	posZ -= cos(yrotrad) * rate;
	posY -= sin(xrotrad) * rate;
	camera.pos.x += sin(yrotrad) * rate; // seems to be fine
	camera.pos.z -= cos(yrotrad) * rate;
   }

void drawCube(){

    glPushMatrix();
    glTranslatef(posX, posY, posZ);
    glRotatef(heading, 0.0, 1.0, 0.0);
    glRotatef(pitch, 1.0, 0.0, 0.0);
    glutSolidCube(1);
    glPopMatrix();

}

void display(){

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    controls();

    glLoadIdentity();
    gluLookAt(camera.getPos().x, camera.getPos().y, camera.getPos().z,
                  posX, posY, posZ,
                  camera.getUp().x, camera.getUp().y, camera.getUp().z);

    glPushMatrix();
    glTranslatef(camera.getLook().x, 0, camera.getLook().z);
    drawCube();
    glPopMatrix();

    // draw grid
    drawGrid();
    
    glutSwapBuffers();
}

void idle();
    glutPostRedisplay();
}

// keyboard/special keyboard functions

// main




//Camera.h

struct coords{
    float x, y, z;
};

class Camera{

public:
    Camera();

    void set(float posX, float posY, float posZ,
                float lookX, float lookY, float lookZ,
                float upX, float upY, float upZ);

    coords getPos();
    coords getLook();
    coords getUp();
    
private:

    coords pos;
    coords look;
    coords up;

};




// Camera.cpp

Camera::Camera(){

    set(0.0, 1.0, 5.0, 0.0, 1.0, -1.0, 0.0, 1.0, 0.0);
}

void Camera::set(float posX, float posY, float posZ,
                float lookX, float lookY, float lookZ,
                float upX, float upY, float upZ){

    pos.x = posX;
    pos.y = posY;
    pos.z = posZ;

    look.x = lookX;
    look.y = lookY;
    look.z = lookZ;

    up.x = upX;
    up.y = upY;
    up.z = upZ;
}

coords Camera::getPos(){
    return pos;
}

coords Camera::getLook(){
    return look;
}

coords Camera::getUp(){
    return up;
}


If anyone could help me implement the third person camera, it would be appreciated :slight_smile:

Thanks.

www.google.com is a good starting point…

HTH