home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / IRIT / POLY3DRS.ZIP / PREPDATA.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-05-05  |  7.9 KB  |  226 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 ScreenYSize 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 "parser.h"
  21.  
  22. static int PrepareAllObjects(FileDescription **FD);
  23. static int VisitObjectTree(BinTree *PBinTree);
  24. static void PrepareOneObject(ObjectStruct *PObject);
  25. static void PrepareOnePolygon(PolygonStruct *PPolygon);
  26. static VertexStruct *UpdateBBoxPolygon(PolygonStruct *PPolygon);
  27. static void UpdateScanConvertData(VertexStruct *PMinY, PolygonStruct *PPolygon);
  28.  
  29. /*****************************************************************************
  30. * Routine to prepare NumOfObjects given in Objects from FileDescription FD   *
  31. * according to view matrix Mat. If NumOfObjects == 0 then all the objects    *
  32. * defined by the data sturcture are handled, and NumOfObjects is set to real *
  33. * number of objects exists.                             *
  34. *****************************************************************************/
  35. void PrepareViewData(FileDescription **FD, int *NumOfObjects, char **Objects)
  36. {
  37.     int    i;
  38.     long SaveTime = time(NULL);
  39.     struct ObjectStruct    *PObject;
  40.  
  41.     fprintf(stderr, "\nPass 2, Polys [%4d] =      ", NumOfPolygons);
  42.  
  43.     if (*NumOfObjects > 0)       /* There was something on command line... */
  44.     for (i=0; i<*NumOfObjects; i++) {
  45.         if ((PObject = SearchObject(FD, *Objects)) == NULL)
  46.         fprintf(stderr,
  47.             "\n\nGiven Object %s not found in data files\n", *Objects);
  48.         else PrepareOneObject(PObject);
  49.         Objects++;
  50.     }
  51.     else {            /* Prepare all objects by scanning object trees. */
  52.     *NumOfObjects = PrepareAllObjects(FD);
  53.     }
  54.  
  55.     fprintf(stderr, ",  %ld seconds.", time(NULL) - SaveTime);
  56. }
  57.  
  58. /*****************************************************************************
  59. * Routine to search for    an object in the File descriptions FD. Note that if  *
  60. * an object exists more    than once only the first will be returned. If none   *
  61. * is found then    NULL is    returned, else a pointer to that object    struct.         *
  62. *****************************************************************************/
  63. ObjectStruct *SearchObject(FileDescription **FD, char *Object)
  64. {
  65.     struct BinTree *PBinTree;
  66.  
  67.     while (*FD) {
  68.     if ((PBinTree = GetBinTree(Object, (*FD++) -> ObjectPointer)) !=
  69.                             (BinTree *) NULL)
  70.         return PBinTree -> Data.PObject;
  71.     }
  72.     return (ObjectStruct *) NULL;
  73. }
  74.  
  75. /*****************************************************************************
  76. * Scan all objects.                                 *
  77. *****************************************************************************/
  78. static int PrepareAllObjects(FileDescription **FD)
  79. {
  80.     int Num = 0;
  81.  
  82.     while (*FD)    Num += VisitObjectTree((*FD++) -> ObjectPointer);
  83.  
  84.     return Num;
  85. }
  86.  
  87. /*****************************************************************************
  88. * Scanning all the object in tree PBinTree and prepare them.             *
  89. *****************************************************************************/
  90. static int VisitObjectTree(BinTree *PBinTree)
  91. {
  92.     int Num;
  93.  
  94.     if (PBinTree == (BinTree *)    NULL) return 0;
  95.  
  96.     Num = VisitObjectTree(PBinTree -> right);
  97.  
  98.     PrepareOneObject(PBinTree -> Data.PObject);
  99.  
  100.     Num += VisitObjectTree(PBinTree -> left);
  101.  
  102.     return Num + 1;
  103. }
  104.  
  105. /*****************************************************************************
  106. * Routine to prepare one object PObject.                     *
  107. *****************************************************************************/
  108. static void PrepareOneObject(ObjectStruct *PObject)
  109. {
  110.     struct PolygonStruct *Ptemp, *PList = PObject -> PPolygon;
  111.  
  112.     while (PList) {
  113.     Ptemp = PList -> Pnext;
  114.  
  115.     PrepareOnePolygon(PList);
  116.  
  117.     PList =    Ptemp;
  118.     }
  119. }
  120.  
  121. /*****************************************************************************
  122. * Routine to prepare one polygon PPolygon.                     *
  123. *****************************************************************************/
  124. static void PrepareOnePolygon(PolygonStruct *PPolygon)
  125. {
  126.     static PolyCount = 0;
  127.     int    i;
  128.     double CpCoord[3];
  129.     struct VertexStruct *PList = PPolygon -> PVertex;
  130.  
  131.     fprintf(stderr, "\b\b\b\b\b%5d", ++PolyCount);
  132.  
  133.     while (PList) {
  134.     /* Use the transform flag to specify number of references   */
  135.     /* and if one allready trasnform it, dont do that again.    */
  136.     if (++PList -> Transform > 1) break;
  137.  
  138.     /* Convert the coordinate to screen space (in double pres.). */
  139.     MultVecby4by4(CpCoord, PList -> Coord, GlblViewMat);
  140.     for (i=0; i<3; i++) PList -> Coord[i] = CpCoord[i];
  141.     PList =    PList -> Pnext;
  142.     }
  143.  
  144.     if (PPolygon -> Polyline) return;
  145.  
  146.     /* Find X, Y extremum in screen space, and use the lowest vertex in Y to */
  147.     /* initialize the scan conversion structure of the polygon:             */
  148.     PList = UpdateBBoxPolygon(PPolygon);
  149.     UpdateScanConvertData(PList, PPolygon);
  150.  
  151.     /* Transform the polygon plane equation as well, and normalize it: */
  152.     UpdateEqnPolygon(PPolygon, FALSE);
  153. }
  154.  
  155. /*****************************************************************************
  156. * Routine to update polygon boundary box in screen space:             *
  157. * Note this routine is called after the    polygons was checked for validity -  *
  158. * all the list of objects was found to be vertices only.             *
  159. *****************************************************************************/
  160. static VertexStruct *UpdateBBoxPolygon(PolygonStruct *PPolygon)
  161. {
  162.     float *Coord, Xmin, Xmax, Ymin, Ymax;
  163.     struct VertexStruct *PList = PPolygon -> PVertex, *PMinY;
  164.  
  165.     PMinY = PList;
  166.     Xmin = Xmax = PList -> Coord[0];
  167.     Ymin = Ymax = PList -> Coord[1];
  168.     PList = PList -> Pnext;
  169.     while (PList) {
  170.     Coord = PList -> Coord;
  171.     if (Coord[0] > Xmax) Xmax = Coord[0];
  172.     if (Coord[0] < Xmin) Xmin = Coord[0];
  173.     if (Coord[1] > Ymax) Ymax = Coord[1];
  174.     if (Coord[1] < Ymin) {
  175.         Ymin = Coord[1];
  176.         PMinY = PList;
  177.     }
  178.     PList =    PList -> Pnext;
  179.     }
  180.  
  181.     PPolygon -> Xmin = (int) Xmin;
  182.     PPolygon -> Xmax = (int) Xmax;
  183.     PPolygon -> Ymin = (int) Ymin;
  184.     PPolygon -> Ymax = (int) Ymax;
  185.  
  186.     return PMinY;
  187. }
  188.  
  189. /*****************************************************************************
  190. * Routine to update polygon scan conversion information:             *
  191. * Each polygon (Remember they must be convex), has two boundaries we cross   *
  192. * by the scan lines if it is active. These are LeftBndry and RightBndry we   *
  193. * update here.                                     *
  194. *****************************************************************************/
  195. static void UpdateScanConvertData(VertexStruct *PMinY, PolygonStruct *PPolygon)
  196. {
  197.     struct VertexStruct *PList = PPolygon -> PVertex,
  198.     *VMinY, *VBefore, *VAfter;
  199.  
  200.     /* Find the minimum location again: */
  201.     while (PList != PMinY && PList -> Pnext != PMinY)
  202.     PList = PList -> Pnext;
  203.     if (PList == PMinY) {
  204.     /* Its the first vertex that has minimum Y value: */
  205.     VMinY = PList;
  206.     VAfter = PList -> Pnext;
  207.     while (PList -> Pnext != NULL) PList = PList -> Pnext;
  208.     VBefore = PList;
  209.     }
  210.     else {
  211.     VMinY = PList -> Pnext;
  212.     VBefore = PList;
  213.     if (PList -> Pnext -> Pnext != NULL)
  214.          VAfter = PList -> Pnext -> Pnext;
  215.     else VAfter = PPolygon -> PVertex;
  216.     }
  217.  
  218.     PPolygon -> Bndry1.VMinY = VMinY;
  219.     PPolygon -> Bndry1.VMaxY = VBefore;
  220.     PPolygon -> Bndry1.MaxEdgeY = (int) VBefore -> Coord[1];
  221.  
  222.     PPolygon -> Bndry2.VMinY = VMinY;
  223.     PPolygon -> Bndry2.VMaxY = VAfter;
  224.     PPolygon -> Bndry2.MaxEdgeY = (int) VAfter -> Coord[1];
  225. }
  226.