home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1996 December / PCWKCD1296.iso / sharewar / quake106 / utils / qbsp / outside.c < prev    next >
C/C++ Source or Header  |  1996-09-12  |  4KB  |  253 lines

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