home *** CD-ROM | disk | FTP | other *** search
/ Dream 57 / Amiga_Dream_57.iso / Amiga / Programmation / c / QuakeC / qtools0.2-src.lha / src / libqbuild / outside.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-07-15  |  5.2 KB  |  256 lines

  1. #define    LIBQBUILD_CORE
  2. #include "../include/libqbuild.h"
  3.  
  4. int outleafs = 0;                        /* 4 */
  5.  
  6. struct portal *prevleaknode;                    /* 4 */
  7. FILE *leakfile;                            /* 4 */
  8.  
  9. int hit_occupied = 0;                        /* 4 */
  10. int backdraw = 0;                        /* 4 */
  11.  
  12. /* PROGRESS-ONLY! */
  13. int outsidenum;
  14. int outsidecur;
  15.  
  16. /*
  17.  * ===========
  18.  * PointInLeaf
  19.  * ===========
  20.  */
  21. struct node *PointInLeaf(__memBase, struct node *node, vec3_t point)
  22. {
  23.   vec_t d;
  24.  
  25.   if (node->contents)
  26.     return node;
  27.  
  28. #ifdef EXHAUSIVE_CHECK
  29.   if (node->planenum >= bspMem->numbrushplanes || node->planennum < 0)
  30.     Error("looking for nonexisting plane %d\n", node->planenum);
  31. #endif
  32.   d = DotProduct(bspMem->brushplanes[node->planenum].normal, point) - bspMem->brushplanes[node->planenum].dist;
  33.  
  34.   if (d > 0)
  35.     return PointInLeaf(bspMem, node->children[0], point);
  36.  
  37.   return PointInLeaf(bspMem, node->children[1], point);
  38. }
  39.  
  40. /*
  41.  * ===========
  42.  * PlaceOccupant
  43.  * ===========
  44.  */
  45. bool PlaceOccupant(__memBase, register int num, register vec3_t point, register struct node * headnode)
  46. {
  47.   struct node *n;
  48.  
  49.   n = PointInLeaf(bspMem, headnode, point);
  50.   if (n->contents == CONTENTS_SOLID)
  51.     return FALSE;
  52.   n->occupied = num;
  53.   return TRUE;
  54. }
  55.  
  56. /*
  57.  * ==============
  58.  * MarkLeakTrail
  59.  * ==============
  60.  */
  61. void MarkLeakTrail(register struct portal *n2)
  62. {
  63.   int i;
  64.   short int j;
  65.   vec3_t p1, p2, dir;
  66.   float len;
  67.   struct portal *n1;
  68.  
  69.   if (hullnum)
  70.     return;
  71.  
  72.   n1 = prevleaknode;
  73.   prevleaknode = n2;
  74.  
  75.   if (!n1)
  76.     return;
  77.  
  78.   VectorCopy(n2->winding->points[0], p1);
  79.   for (i = 1; i < n2->winding->numpoints; i++) {
  80.     for (j = 0; j < 3; j++)
  81.       p1[j] = (p1[j] + n2->winding->points[i][j]) / 2;
  82.   }
  83.  
  84.   VectorCopy(n1->winding->points[0], p2);
  85.   for (i = 1; i < n1->winding->numpoints; i++) {
  86.     for (j = 0; j < 3; j++)
  87.       p2[j] = (p2[j] + n1->winding->points[i][j]) / 2;
  88.   }
  89.  
  90.   VectorSubtract(p2, p1, dir);
  91.   len = VectorLength(dir);
  92.   VectorNormalize(dir);
  93.  
  94.   while (len > 2) {
  95.     fprintf(leakfile, "%g %g %g\n", p1[0], p1[1], p1[2]);
  96.     for (i = 0; i < 3; i++)
  97.       p1[i] += dir[i] * 2;
  98.     len -= 2;
  99.   }
  100. }
  101.  
  102. /*
  103.  * ==================
  104.  * RecursiveFillOutside
  105.  * 
  106.  * If fill is FALSE, just check, don't fill
  107.  * Returns TRUE if an occupied leaf is reached
  108.  * ==================
  109.  */
  110. bool RecursiveFillOutside(register struct node *l, register bool fill)
  111. {
  112.   struct portal *p;
  113.   int s;
  114.  
  115.   /* PROGRESS-ONLY! */
  116.   if (!fill)
  117.     outsidenum++;
  118.   else
  119.     mprogress(outsidenum, ++outsidecur);
  120.  
  121.   if (l->contents == CONTENTS_SOLID || l->contents == CONTENTS_SKY)
  122.     return FALSE;
  123.  
  124.   if (l->valid == valid)
  125.     return FALSE;
  126.  
  127.   if (l->occupied)
  128.     return TRUE;
  129.  
  130.   l->valid = valid;
  131.  
  132.   /* fill it and it's neighbors */
  133.   if (fill)
  134.     l->contents = CONTENTS_SOLID;
  135.   outleafs++;
  136.  
  137.   for (p = l->portals; p;) {
  138.     s = (p->nodes[0] == l);
  139.  
  140.     if (RecursiveFillOutside(p->nodes[s], fill)) {        /* leaked, so stop filling */
  141.  
  142.       if (backdraw-- > 0) {
  143.     MarkLeakTrail(p);
  144.     DrawLeaf(l, 2);
  145.       }
  146.       return TRUE;
  147.     }
  148.     p = p->next[!s];
  149.   }
  150.  
  151.   return FALSE;
  152. }
  153.  
  154. /*
  155.  * ==================
  156.  * ClearOutFaces
  157.  * 
  158.  * ==================
  159.  */
  160. void ClearOutFaces(register struct node *node)
  161. {
  162.   struct visfacet **fp;
  163.  
  164.   if (node->planenum != -1) {
  165.     ClearOutFaces(node->children[0]);
  166.     ClearOutFaces(node->children[1]);
  167.     return;
  168.   }
  169.   if (node->contents != CONTENTS_SOLID)
  170.     return;
  171.  
  172.   for (fp = node->markfaces; *fp; fp++) {
  173.     /* mark all the original faces that are removed */
  174.     (*fp)->numpoints = 0;
  175.   }
  176.   node->faces = NULL;
  177. }
  178.  
  179. /*============================================================================= */
  180.  
  181. /*
  182.  * ===========
  183.  * FillOutside
  184.  * 
  185.  * ===========
  186.  */
  187. bool FillOutside(__memBase, struct node *node, char *pointfilename)
  188. {
  189.   int s;
  190.   vec_t *v;
  191.   int i;
  192.   bool inside;
  193.  
  194.   mprintf("----- FillOutside -------\n");
  195.   /* PROGRESS-ONLY! */
  196.   outsidenum = 0;
  197.   outsidecur = 0;
  198.  
  199.   if (bspMem->bspOptions & QBSP_NOFILL) {
  200.     mprintf("    - skipped\n");
  201.     return FALSE;
  202.   }
  203.  
  204.   inside = FALSE;
  205.   for (i = 1; i < bspMem->nummapentities; i++) {
  206.     if (!VectorZero(bspMem->mapentities[i].origin)) {
  207.       if (PlaceOccupant(bspMem, i, bspMem->mapentities[i].origin, node))
  208.     inside = TRUE;
  209.     }
  210.   }
  211.  
  212.   if (!inside) {
  213.     mprintf("Hullnum %i: No bspMem->mapentities in empty space -- no filling performed\n", hullnum);
  214.     return FALSE;
  215.   }
  216.  
  217.   s = !(outside_node.portals->nodes[1] == &outside_node);
  218.  
  219.   /* first check to see if an occupied leaf is hit */
  220.   outleafs = 0;
  221.   valid++;
  222.  
  223.   prevleaknode = NULL;
  224.  
  225.   if (!hullnum) {
  226.     leakfile = __fopen(pointfilename, "w");
  227.     if (!leakfile)
  228.       Error(failed_fileopen, pointfilename);
  229.   }
  230.  
  231.   if (RecursiveFillOutside(outside_node.portals->nodes[s], FALSE)) {
  232.     v = bspMem->mapentities[hit_occupied].origin;
  233.     eprintf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
  234.     eprintf("reached occupant at: ( %g %g %g )\n"
  235.         ,v[0], v[1], v[2]);
  236.     eprintf("no filling performed\n");
  237.     if (!hullnum)
  238.       __fclose(leakfile);
  239.     eprintf("leak file written to %s\n", pointfilename);
  240.     eprintf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
  241.     return FALSE;
  242.   }
  243.   if (!hullnum)
  244.     __fclose(leakfile);
  245.  
  246.   /* now go back and fill things in */
  247.   valid++;
  248.   RecursiveFillOutside(outside_node.portals->nodes[s], TRUE);
  249.  
  250.   /* remove faces from filled in leafs     */
  251.   ClearOutFaces(node);
  252.  
  253.   mprintf("%5i outleafs\n", outleafs);
  254.   return TRUE;
  255. }
  256.