Parameter Settings for Project 2
--------------------------------
This file contains various numeric parameter settings used in our
project. You are welcome to use these values in your program, but you
are encouraged to experiment with different values as well. (Remember
that, if you make use of any external resources, you must cite them in
your ReadMe file. Since this is not really external, you do not need to
cite this information.)

If any values appears to be missing, feel free to check with me.

Dave


General:
--------
Clear color: I used a glClearColor of red (1, 0, 0). I would recommend
using something different from black.

  initial window width  = 800
  initial window height = 600

World:
------
The world consists of three principal objects, a camera, a chessboard,
and a skybox. The chessboard stores the individual pieces, which (in
the current implementation) are all pawns. I assume a coordinate frame
with the x,y axes directed horizontally and the z axis pointing up.

Camera:
-------
My camera object stores a number of quantities, all related to camera,
perspective, and other information used for picking. These included the
window dimensions, the defining camera quantities (eye, at, up), the
camera's rotation, elevation, and distance from the center of the board.
It also computed and maintained the unit vectors for the view frame.
These were used for the ray-traced picking operation.

  initial camera rotation (CCW about z-axis): -40 degrees
  initial camera elevation (relative to ground): +20 degrees
  initial camera distance: 10,000 units

  y-field of view: 30 degrees
  near clipping plane: 50
  far clipping plane: 500,000

  minimum/maximum camera elevation: -85/+85 degrees
  min camera distance: 2,000
  max camera distance: 20,000

Light Source:
-------------
  Ambient light: (0.4, 0.4, 0.4)
  Light 0 position: (-5, -7, 5, 0)  (this is a light source at infinity!)
  Light 0 diffuse color: (1.25, 1.00, 0.75)

Shadows:
--------
Shadows are drawn using the shadow painting technique discussed in
class. After projection, shadows are drawn as a transparent polygon
slightly above the ground (by 2 units):

  Shadow color (RGBA): (0.1, 0.1, 0.1, 0.3)
  Opengl Blend Function: (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

Skybox:
-------
The skybox is cube of side length 50,000 centered at the origin.

It is not shaded (lighting is disabled before drawing). Each face is
textured (using GL_REPLACE) with the files

  Resources/Skyboxes/stormydays-XX.bmp.
  
There are 6 files, where the "XX" is either ft, bk, up, dn, lf, rt (for
front, back, up, down, left, right). The naming convention is a bit
funky, and it took me a little while to fit the pieces of the puzzle
together. It may help to look at:

  http://www.mapcore.org/topic/2829-second-release-5-skies/

to see how the pieces fit together.

ChessBoard:
-----------
The board is 8x8. The total length and width are 5,000 units, and the
thickness is 50. The top of the board sits on the z=0 plane. (Thus, the
lower left corner of the top of the board is (-2,500, -2,500, 0) and the
upper right corner of the top of the board is (-2,500, -2,500, 0).

In Version-1, I drew my board using 64 calls to glutSolidCube. Since
glutSolidCube does not support texture mapping, in Version-2 I had to
write my own cub drawing function. (I needed this anyway for the
skybox.)

In Version 1, the board is colored with the following diffuse colors:

 Dark squares:
   normal: (0.3, 0.3, 0.3)
   if highlighted: (0.0, 0.0, 0.0)

 Light squares:
   normal: (0.8, 0.8, 0.8)
   if highlighted: (1.5, 1.5, 1.5)

 After a square has been selected:
   source square: (0.7, 0.0, 0.5)
   destination square: (0.0, 0.7, 0.5)

In Version-2, all the squares are colored with the diffuse color
(1.0, 1.0, 1.0), but the texture is applied on top of this.

Both versions:
  Specular color: (0.25, 0.25, 0.25)
  Shininess: 100.0

(In case you are curious, the convention in chess is that, from each
player's perspective, the lower left square should be dark.)

Internally, I represented the board as an 8 x 8 array, where each entry
stores the identity of the chess piece located at this square (or a
special value if there is no such piece).

Pawn:
-----
  Colors:
  White pawn, diffuse: (0.8, 0.8, 0.8)
  Black pawn, diffuse: (0.1, 0.1, 0.1)

  Specular color: (1.0, 1.0, 1.0)
  Specular shininess: 100

  Model:
  ------
  The model is given in the manner of the Challenge Problem on Homework
  1. See the file pawn-model.txt for the vertices. The file has 50
  lines, each of which holds an x-coordinate and a z-coordinate. (The
  first and last points have x-coordinates of 0.) This defines 49
  horizontal stacks, where each is revolved around the z-axis. In our
  program we rotated these points around the z-axis to form 32 vertical
  slices. The top and bottom slices are triangle fans, and all the
  others are quad strips.

  After constructing the vertices, we compute the surface normals. The
  top surface normal points up (0,0,1), and bottom surface normal points
  down (0,0,-1), and otherwise, the i-th surface normal is formed by
  taking a vector in the (x,z)-plane whose slope is the negative
  reciprocal of the line segment from vertex i-1 to vertex i (which we
  then normalize to unit length).

Pawn Animation:
---------------
Pawns are in one of four possible states:

  Still - just sitting on the board
  Ready - jumping up and down waiting to move
  Moving - sliding from one position to another
  Tumbling - tumbling in the air after being hit by a moving pawn

  All updates are scaled by the amount of elapsed time between updates.
  (Without this, the update times will depend on the number of frames
  per second, which is not ideal.)

  Ready:
  ------
    The pawn jumps and down. It's initial velocity is 500 units per
    second, but with each update cycle, its vertical speed decreases by
    the gravitational factor of 2000 units per second. Therefore, it
    quickly starts moving down again. When its penetrates the ground
    plane, its velocity is set back to 500 units per second.

    Only one pawn can be in this state. If the same square is selected
    twice, the pawn returns to the still state.

  Moving:
  -------
    When the second square is selected, the ready pawn starts moving at
    2000 units per second towards the center of the desired square. I
    keep track of the total distance to be travelled and the amount of
    travel performed with each update step, and when it arrives at the
    new square, it returns to the Still state.
    
    Note that the pawn may pass through many pawns on the way to its
    destination, and (demonstrating complete ignorance of the rules of
    chess) I implemented my program so it knocked out all of these
    pieces. (This is not quite accurate to the specifications, but it
    was easy to implement, and I felt it looked better than having the
    piece pass through these other pieces. You may implement this
    however you like, it is the animation that I'm most interested in
    seeing.)

  Tumbling:
  ---------
    When a still pawn is hit by a moving pawn, the still pawn is sent
    into a tumbling state. To do this, I compute the angle from which it
    was hit and generate a horizontal vector in this direction. The
    horizontal component of this vector is of length 2000 and the
    vertical component is of length 3000. This is the speed with which
    the tumbling pawn starts to move. I also generated a horizontal
    rotation axis that is perpendicular to the direction from which the
    pawn is hit. The pawn rotates at 90 degrees per second around this
    axis.

    I discovered after implementing this that when I hit a whole row of
    pawns, they all were knocked in exactly the same direction with the
    same rotation axis. To make it look a bit more random, I added a
    small random perturbation to the tumbling direction and the axis of
    rotation.

    In theory, it is possible that the tumbling pawns might hit other
    pawns, the board, or the skybox. I ignored all such collisions.

User Inputs:
-------------
  Drag mouse (left button): rotate camera
  Mouse click (right button): select square
  'up/down arrow':zoom camera in/out
  '1/2': switch to version 1 or 2
  'f': toggle full screen
  'q' or 'ESC': quit
 
Dragging the mouse with the left button depressed alters the camera
rotation (x) and camera elevation (y). Each pixel of mouse motion
corresponds 1/10 of one degree of rotation/elevation change.

(You may design your own interface, but it should involve both mouse and
keyboard input.)
