home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / i / iritsm3s.zip / poly3d-r / prepdata.c < prev    next >
C/C++ Source or Header  |  1991-09-11  |  6KB  |  180 lines

  1. /*****************************************************************************
  2. *   Routines to    prepare objects for the scan conversion:             *
  3. * At this stage, it is assumed all vertices normals has been evaluated, if   *
  4. * is is required to interpolate them (i.e. Gouraud shading.)             *
  5. * This module sort the polygons into hash table of GlblShadeInfo.ScrnYSize size,         *
  6. * according to their lowest vertex, and update a pointer to it.             *
  7. *                                         *
  8. * Written by:  Gershon Elber                Ver 2.0, Mar. 1990   *
  9. *****************************************************************************/
  10.  
  11. #ifdef __MSDOS__
  12. #include <stdlib.h>
  13. #endif /* __MSDOS__ */
  14.  
  15. #include <math.h>
  16. #include <stdio.h>
  17. #include <time.h>
  18. #include "program.h"
  19. #include "genmat.h"
  20. #include "iritprsr.h"
  21.  
  22. static void PrepareAllObjects(IPObjectStruct *PObjects);
  23. static void PrepareOneObject(IPObjectStruct *PObject);
  24. static void PrepareOnePolygon(IPPolygonStruct *PPolygon);
  25. static int UpdateBBoxPolygon(IPPolygonStruct *PPolygon);
  26. static void UpdateScanConvertData(int MinVertex, IPPolygonStruct *PPolygon);
  27.  
  28. /*****************************************************************************
  29. * Routine to prepare NumOfObjects given in Objects from FileDescription FD   *
  30. * according to view matrix Mat. If NumOfObjects == 0 then all the objects    *
  31. * defined by the data sturcture are handled, and NumOfObjects is set to real *
  32. * number of objects exists.                             *
  33. *****************************************************************************/
  34. void PrepareViewData(IPObjectStruct *PObjects)
  35. {
  36.     long
  37.     SaveTime = time(NULL);
  38.  
  39.     fprintf(stderr, "\nPass 2, Polys        =      ");
  40.  
  41.     PrepareAllObjects(PObjects);
  42.  
  43.     fprintf(stderr, ",  %ld seconds.", time(NULL) - SaveTime);
  44. }
  45.  
  46. /*****************************************************************************
  47. * Scan all objects.                                 *
  48. *****************************************************************************/
  49. static void PrepareAllObjects(IPObjectStruct *PObjects)
  50. {
  51.     while (PObjects) {
  52.     PrepareOneObject(PObjects);
  53.     PObjects = PObjects -> Pnext;
  54.     }
  55. }
  56.  
  57. /*****************************************************************************
  58. * Routine to prepare one object PObject.                     *
  59. *****************************************************************************/
  60. static void PrepareOneObject(IPObjectStruct *PObject)
  61. {
  62.     struct IPPolygonStruct *PList = PObject -> U.PPolygon;
  63.  
  64.     while (PList) {
  65.     PrepareOnePolygon(PList);
  66.     PList =    PList -> Pnext;
  67.     }
  68. }
  69.  
  70. /*****************************************************************************
  71. * Routine to prepare one polygon PPolygon.                     *
  72. *****************************************************************************/
  73. static void PrepareOnePolygon(IPPolygonStruct *PPolygon)
  74. {
  75.     static int
  76.     PolyCount = 0;
  77.     int    i;
  78.     RealType CpCoord[3];
  79.     IPVertexStruct
  80.     *VList = PPolygon -> PVertex;
  81.  
  82.     fprintf(stderr, "\b\b\b\b\b%5d", ++PolyCount);
  83.     GlblNumOfPolys++;
  84.  
  85.     for (; VList != NULL; VList = VList -> Pnext) {
  86.     /* Convert the coordinate to screen space (pres.). */
  87.     MultVecby4by4(CpCoord, VList -> Coord, GlblViewMat);
  88.     for (i = 0; i < 3; i++) VList -> Coord[i] = CpCoord[i];
  89.     }
  90.  
  91.     if (PPolygon -> Type != IP_POLYGON) return;
  92.  
  93.     /* Find X, Y extremum in screen space, and use the lowest vertex in Y to */
  94.     /* initialize the scan conversion structure of the polygon:             */
  95.     i = UpdateBBoxPolygon(PPolygon);
  96.     UpdateScanConvertData(i, PPolygon);
  97.  
  98.     /* Transform the polygon plane equation as well, and normalize it: */
  99.     UpdateEqnPolygon(PPolygon, FALSE);
  100. }
  101.  
  102. /*****************************************************************************
  103. * Routine to update polygon boundary box in screen space:             *
  104. * Note this routine is called after the    polygons was checked for validity -  *
  105. * all the list of objects was found to be vertices only.             *
  106. *****************************************************************************/
  107. static int UpdateBBoxPolygon(IPPolygonStruct *PPolygon)
  108. {
  109.     int i,
  110.     MinV = 0;
  111.     RealType *Coord, Xmin, Xmax, Ymin, Ymax;
  112.     struct IPVertexStruct
  113.     *VList = PPolygon -> PVertex;
  114.  
  115.     Xmin = Xmax = VList -> Coord[0];
  116.     Ymin = Ymax = VList -> Coord[1];
  117.     for (VList = VList -> Pnext, i = 1;
  118.      VList != NULL;
  119.      VList = VList -> Pnext, i++) {
  120.     Coord = VList -> Coord;
  121.     if (Coord[0] > Xmax) Xmax = Coord[0];
  122.     if (Coord[0] < Xmin) Xmin = Coord[0];
  123.     if (Coord[1] > Ymax) Ymax = Coord[1];
  124.     if (Coord[1] < Ymin) {
  125.         Ymin = Coord[1];
  126.         MinV = i;
  127.     }
  128.     }
  129.  
  130.     PPolygon -> Xmin = (int) Xmin;
  131.     PPolygon -> Xmax = (int) Xmax;
  132.     PPolygon -> Ymin = (int) Ymin;
  133.     PPolygon -> Ymax = (int) Ymax;
  134.  
  135.     return MinV;
  136. }
  137.  
  138. /*****************************************************************************
  139. * Routine to update polygon scan conversion information:             *
  140. * Each polygon (Remember they must be convex), has two boundaries we cross   *
  141. * by the scan lines if it is active. These are LeftBndry and RightBndry we   *
  142. * update here.                                     *
  143. *****************************************************************************/
  144. static void UpdateScanConvertData(int MinVertex, IPPolygonStruct *PPolygon)
  145. {
  146.     int i;
  147.     struct IPVertexStruct *VMinY, *VBefore, *VAfter,
  148.     *VList = PPolygon -> PVertex;
  149.     struct PolygonScanConvertStruct *PScan;
  150.  
  151.     /* Find the minimum location again: */
  152.     if (MinVertex == 0) {
  153.     /* Its the first vertex that has minimum Y value: */
  154.     VMinY = VList;
  155.     for (VBefore = VList;
  156.          VBefore -> Pnext != NULL;
  157.          VBefore = VBefore -> Pnext);
  158.     VAfter = VList -> Pnext;
  159.     }
  160.  
  161.     else {
  162.     for (i = 1, VBefore = VList;
  163.          i < MinVertex;
  164.          i++, VBefore = VBefore -> Pnext);
  165.     VMinY = VBefore -> Pnext;
  166.     VAfter = VMinY -> Pnext ? VMinY -> Pnext : VList;
  167.     }
  168.  
  169.     PPolygon -> PAux = MyMalloc(sizeof(struct PolygonScanConvertStruct));
  170.     PScan = (PolygonScanConvertStruct *) PPolygon -> PAux;
  171.  
  172.     PScan -> Bndry1.VMinY = VMinY;
  173.     PScan -> Bndry1.VMaxY = VBefore;
  174.     PScan -> Bndry1.MaxEdgeY = (int) VBefore -> Coord[1];
  175.  
  176.     PScan -> Bndry2.VMinY = VMinY;
  177.     PScan -> Bndry2.VMaxY = VAfter;
  178.     PScan -> Bndry2.MaxEdgeY = (int) VAfter -> Coord[1];
  179. }
  180.