CMPS-4490 Game Development Lab-2

Overview:

Step 1:

This part of the lab is optional.
---------------------------------

Let's begin by working with our lab-1 program.

Log on to Odin server.
cd 4490/2

Our scene contains a box.
Stop the movement of the box.
Activate the gluPerspective call for a 3D scene.

Let's give the scene some depth, by adding more boxes.

1. Add boxes in random positions behind the current box.

2. Now let's move the camera.
Move left or right. Choose keys-presses for this.
Do not change the camera direction.

3. Now turn the camera left or right.
We will use the mouse for this.




Step 2:
Working with a 3D game framework.

We will review the program together,
then you will have a few specific tasks to complete.

You can get the files like this:

1. Log on to Odin
2. cd 4490/2
3. cp /home/fac/gordon/p/4490/code/lab2/* .

It will produce the following scene.



Your job is to give a user the ability to move the camera
in a first-person perspective. Move the camera through the tube.

Current keyboard controls:
  movement      key
  ------------  ---------
  move up       up-arrow
  move down     down-arrow
  move left     left-arrow
  move right    right-arrow
  move forward  f
  move back     b

You may change the controls and even incorporate mouse control.

Your goal is the following camera control...

  1. Look to the left or right
  2. Look up or down
  3. Move up or down
  4. Move in the direction the camera is looking (forward or back)
  5. Move left/right in relation to where the camera is looking

We will discuss this in class and do some work together on Zoom.

You can create a camera class such as

class Camera {
    Vec position;
    Vec direction;
    Camera() {
        VecMake(0, 1, 8, position);
        VecMake(0, 0, -1, direction);
    }
    void translate(float x, float y, float z) {
        position[0] += x;
        position[1] += y;
        position[2] += z;
    }
    void lookLeftRight(float angle) {
        Matrix mat;
        identity33(mat);
        Vec rot = {0.0, angle, 0.0};
        yy_transform(rot, mat);
        trans_vector(mat, direction, direction);
    }
    void lookUpDown(float angle) {
        Matrix mat;
        identity33(mat);
        Vec rot = {angle, 0.0, 0.0};
        yy_transform(rot, mat);
        trans_vector(mat, direction, direction);
    }
    void moveLeftRight(float dist) {
        //get perpendicular vector to direction/up
        Vec left;
        VecCross(direction, up, left); 
        position[0] += left[0] * dist;
        position[1] += left[1] * dist;
        position[2] += left[2] * dist;
    }
    void moveUpDown(float dist) {
        //just move straight up or down
        position[1] += dist;
    }
};

Try to get freedom of movement similar to this...





Code needed:
To accomplish the look-up and look-down (pitch) camera control, you will need
the following code segment.

The following function builds a rotation matrix, but it will rotate on any
axis given, not just x,y,z axis. Indicate an axis using a vector.

Example:
   X axis is { 1, 0, 0 }
   Y axis is { 0, 1, 0 }
   Z axis is { 0, 0, 1 }

Then use the matrix created to transform the camera direction using trans_vector.

This function was used in the animation to tilt the camera downward.

void matrixFromAxisAngle(const Vec v, Flt ang, Matrix m)
{
    // arguments
    // v   = vector indicating the axis
    // ang = amount of rotation
    // m   = matrix to be updated
    // This source was used during research...
    // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToMatrix/
    //
    struct Axisangle {
        Flt angle;
        Flt x,y,z;
    } a1;
    a1.x = v[0];
    a1.y = v[1];
    a1.z = v[2];
    a1.angle = ang;
    //
    Flt c = cos(a1.angle);
    Flt s = sin(a1.angle);
    Flt t = 1.0 - c;
    m[0][0] = c + a1.x * a1.x * t;
    m[1][1] = c + a1.y * a1.y * t;
    m[2][2] = c + a1.z * a1.z * t;
    //
    Flt tmp1 = a1.x * a1.y * t;
    Flt tmp2 = a1.z * s;
    m[1][0] = tmp1 + tmp2;
    m[0][1] = tmp1 - tmp2;
    //
    tmp1 = a1.x * a1.z * t;
    tmp2 = a1.y * s;
    m[2][0] = tmp1 - tmp2;
    m[0][2] = tmp1 + tmp2;
    tmp1 = a1.y * a1.z * t;
    tmp2 = a1.x * s;
    m[2][1] = tmp1 + tmp2;
    m[1][2] = tmp1 - tmp2;
}

void screenShot()
{
    //A capture of the OpenGL window client area.
    static int inc = 0;
    //Get pixels...
    unsigned char *data = new unsigned char [g.xres * g.yres * 3];
    glReadPixels(0, 0, g.xres, g.yres, GL_RGB, GL_UNSIGNED_BYTE, data);
    //Write a PPM file...
    char ts[256], tj[256];
    sprintf(ts, "./images/img%03i.ppm", inc);
    sprintf(tj, "./images/img%03i.jpg", inc);
    ++inc;
    FILE *fpo = fopen(ts, "w");
    fprintf(fpo, "P6\n");
    fprintf(fpo, "%i %i\n", g.xres, g.yres);
    fprintf(fpo, "255\n");
    //Image is upside-down.
    //Go backwards a row at a time...
    unsigned char *p = data;
    p = p + ((g.yres-1) * g.xres * 3);
    unsigned char *start = p;
    for (int i=0; i<g.yres; i++) {
        for (int j=0; j<g.xres*3; j++) {
            fprintf(fpo, "%c", *p);
            ++p;
        }
        start = start - (g.xres*3);
        p = start;
    }
    fclose(fpo);
    delete [] data;
    char t2[256];
    sprintf(t2, "convert %s %s", ts, tj);
    system(t2);
    unlink(ts);
}

to save a gif animation from your program...

system("convert -loop 0 -coalesce -layers OptimizeFrame -delay 20 ./images/img*.jpg abc.gif");




What to turn in...
Gordon will find your work out on Odin.