home *** CD-ROM | disk | FTP | other *** search
/ Superpower (Alt) / SUPERPOWER.iso / q / source / mbq198 / outside.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-06-26  |  4.9 KB  |  269 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.     double    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.     int            original_contents;
  108.  
  109.     if (l->contents == CONTENTS_SOLID)
  110.         return false;
  111.         
  112.     if (l->valid == valid)
  113.         return false;
  114.     
  115.     l->valid = valid;
  116.  
  117. // Some people have been intentionaly putting lights inside sky volumes,
  118. // so I have to fail the check now that I am testing
  119.     if (l->occupied && l->contents != CONTENTS_SKY)
  120.     {
  121.         hit_occupied = l->occupied;
  122. //drawflag = true;
  123. backdraw = 4000;
  124. Draw_ClearWindow ();
  125. DrawLeaf (l, 2);
  126.         return true;
  127.     }
  128.  
  129. // fill it and it's neighbors
  130.     original_contents = l->contents;
  131.     if (fill)
  132.         l->contents = CONTENTS_SOLID;
  133.     outleafs++;
  134.  
  135.     for (p=l->portals ; p ; )
  136.     {
  137.         s = (p->nodes[0] == l);
  138.  
  139.     // flood fill into skys, but not back out
  140.         if (original_contents != CONTENTS_SKY ||
  141.         p->nodes[s]->contents == CONTENTS_SKY )
  142.         {
  143.             if (RecursiveFillOutside (p->nodes[s], fill) )
  144.             {    // leaked, so stop filling
  145.                 if (backdraw-- > 0)
  146.                 {                
  147.                     MarkLeakTrail (p);
  148.                     DrawLeaf (l, 2);
  149.                 }
  150.                 return true;
  151.             }
  152.         }
  153.         p = p->next[!s];
  154.     }
  155.     
  156.     return false;
  157. }
  158.  
  159. /*
  160. ==================
  161. ClearOutFaces
  162.  
  163. ==================
  164. */
  165. void ClearOutFaces (node_t *node)
  166. {
  167.     face_t    **fp;
  168.     
  169.     if (node->planenum != -1)
  170.     {
  171.         ClearOutFaces (node->children[0]);
  172.         ClearOutFaces (node->children[1]);
  173.         return;
  174.     }
  175.     if (node->contents != CONTENTS_SOLID)
  176.         return;
  177.  
  178.     for (fp=node->markfaces ; *fp ; fp++)
  179.     {
  180.     // mark all the original faces that are removed
  181.         (*fp)->numpoints = 0;
  182.     }
  183.     node->faces = NULL;
  184. }
  185.  
  186.  
  187. //=============================================================================
  188.  
  189. /*
  190. ===========
  191. FillOutside
  192.  
  193. ===========
  194. */
  195. qboolean FillOutside (node_t *node)
  196. {
  197.     int            s;
  198.     double        *v;
  199.     int            i;
  200.     qboolean    inside;
  201.     
  202.     qprintf ("----- FillOutside ----\n");
  203.  
  204.     if (nofill)
  205.     {
  206.         printf ("skipped\n");
  207.         return false;
  208.     }
  209.         
  210.     inside = false;
  211.     for (i=1 ; i<num_entities ; i++)
  212.     {
  213.         if (!VectorCompare(entities[i].origin, vec3_origin))
  214.         {
  215.             if (PlaceOccupant (i, entities[i].origin, node))
  216.                 inside = true;
  217.         }
  218.     }
  219.  
  220.     if (!inside)
  221.     {
  222.         printf ("Hullnum %i: No entities in empty space -- no filling performed\n", hullnum);
  223.         return false;
  224.     }
  225.  
  226.     s = !(outside_node.portals->nodes[1] == &outside_node);
  227.  
  228. // first check to see if an occupied leaf is hit
  229.     outleafs = 0;
  230.     valid++;
  231.  
  232.     prevleaknode = NULL;
  233.     
  234.     if (!hullnum)
  235.     {
  236.         leakfile = fopen (pointfilename, "w");
  237.         if (!leakfile)
  238.             Error ("Couldn't open %s\n", pointfilename);
  239.     }
  240.  
  241.     if (RecursiveFillOutside (outside_node.portals->nodes[s], false))
  242.     {
  243.         v = entities[hit_occupied].origin;
  244.         qprintf ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
  245.         qprintf ("reached occupant at: (%4.0f,%4.0f,%4.0f)\n"
  246.         , v[0], v[1], v[2]);
  247.         qprintf ("no filling performed\n");
  248.         if (!hullnum)
  249.             fclose (leakfile);
  250.         qprintf ("leak file written to %s\n", pointfilename);            
  251.         qprintf ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
  252.         return false;
  253.     }
  254.     if (!hullnum)
  255.         fclose (leakfile);
  256.  
  257. // now go back and fill things in
  258.     valid++;
  259.     RecursiveFillOutside (outside_node.portals->nodes[s], true);
  260.  
  261. // remove faces from filled in leafs    
  262.     ClearOutFaces (node);
  263.     
  264.     qprintf ("%4i outleafs\n", outleafs);
  265.     return true;
  266. }
  267.  
  268.  
  269.