CS-460/560, Week 12-A
    Spring, 1998
    R. Eckert
    
    3-D MODELING WITH POLYGONS
    
    Two types of polygon models:
    
    1. Wireframe--Store the polygon edges (list of edge endpoints).
    
    2. Polygon Mesh--Store the polygon faces (array of vertex lists, one list
    for each polygon)).
    
    If the image is to be shaded, a wireframe model will not be useful.
    
    In either case we need to store the 3-D world coordinates of each vertex
    in the polygons approximating the object(s) being modeled.
    
    Use an array of 3-D points:
    
      struct point3d {float x; floaty; float z}    // a single 3-D point
      struct point3d w_pts[];                // w_pts is the 3-D points array
    
    For a wireframe model, the polygon edges could be stored as an array in
    which each element is represented as a pair of indices into the 3-D points
    array:
    
      int edges[][2];  // each second-index value gives the position of
                       // a vertex in the 3-D points array
    
    For a polygon mesh model, an object can be represented as an array of
    polygons, in which each element consists of:
    
      (a) the number of vertices in the polygon
      (b) a list of indices into the 3-D points array
          (Each index gives the position of a vertex in the 3-D points array)
    
      struct polygon {int n; int *inds};  // n is the number of vertices
                                          // inds is a list of indices into
                                          // the points array to specify which
                                          // vertices form the polygon
    
      struct polygon object[];            // the object being modeled--
                                          // an array of polygons
    
    
    EXAMPLE--A PYRAMID
    
    As an example, we will write code necessary to generate the data
    structures for both a wireframe model and a polygon mesh model of the
    following pyramid:
    
    
    
    This pyramid has 5 vertices, 8 edges and 5 polygon faces. The world
    coordinates of each vertex are:
    
    vertex    xw   yw   zw
    ----------------------
      0       0    0    0
      1       150  0    0
      2       150  150  150
      3       0    150  0
      4       75   75   150
    
    So the points array would be set up as follows:
    
      struct point3d w_pts[5];    /* 5 pyramid vertices in world coords */
    
      int b=150, h=75 ;                    // dimensions of pyramid
      w_pts[0].x=w_pts[0].y=w_pts[0].z=0;  // set up world coord. points array
      w_pts[1].x=b; w_pts[1].y=w_pts[1].z=0;
      w_pts[2].x=w_pts[2].y=b; w_pts[2].z=0;
      w_pts[3].x=w_pts[3].z=0; w_pts[3].y=b;
      w_pts[4].x=w_pts[4].y=b/2; w_pts[4].z=h;
    
    The pyramid has the following edges:
    
    edge    edge endpoints (indices into the points array)
    ------------------------------------------------------
     0         0, 1
     1         1, 2
     2         2, 3
     3         3, 0
     4         0, 4
     5         1, 4
     6         2, 4
     7         3, 4
    
    So the edge list needed for a wireframe model could be generated by the
    following code:
    
      int edges[8][2] = {{0,1},{1,2},{2,3},{3,0},{0,4},{1,4},{2,4},{3,4}};
    
    
    The pyramid has the following polygon faces:
    
    polygon   number of vertices   vertices (indices into the points array)
    -----------------------------------------------------------------------
      0               3             0, 1, 4
      1               3             1, 2, 4
      2               3             2, 3, 4
      3               3             0, 4, 3
      4               4             0, 3, 2, 1
    
    The polygon list needed for a polygon mesh model could be generated by the
    following code:
    
      for (i=0;i<=3;i++)                     // set up polygons array
      {
         object[i].n=3;
         object[i].inds = (int *) calloc(3,sizeof(int));
      }
      object[4].n=4;
      object[4].inds = (int *) calloc(4,sizeof(int));
    
      // define the side triangles
      object[0].inds[0]=0; object[0].inds[1]=1; object[0].inds[2]=4; // left back
      object[1].inds[0]=1; object[1].inds[1]=2; object[1].inds[2]=4; // left front
      object[2].inds[0]=2; object[2].inds[1]=3; object[2].inds[2]=4; // right front
      object[3].inds[0]=0; object[3].inds[1]=4; object[3].inds[2]=3; // right back
    
      // define the square base
      object[4].inds[0]=0; object[4].inds[1]=3;
      object[4].inds[2]=2;object[4].inds[3]=1;
    
    
    For more complex objects, the points, edges, and/or polygons arrays can,
    in many cases, be generated procedurally.