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

  1. // trace.c
  2.  
  3. #include "light.h"
  4.  
  5. typedef struct tnode_s
  6. {
  7.     int        type;
  8.     vec3_t    normal;
  9.     float    dist;
  10.     int        children[2];
  11.     int        pad;
  12. } tnode_t;
  13.  
  14. tnode_t        *tnodes, *tnode_p;
  15.  
  16. /*
  17. ==============
  18. MakeTnode
  19.  
  20. Converts the disk node structure into the efficient tracing structure
  21. ==============
  22. */
  23. void MakeTnode (int nodenum)
  24. {
  25.     tnode_t            *t;
  26.     dplane_t        *plane;
  27.     int                i;
  28.     dnode_t         *node;
  29.     
  30.     t = tnode_p++;
  31.  
  32.     node = dnodes + nodenum;
  33.     plane = dplanes + node->planenum;
  34.  
  35.     t->type = plane->type;
  36.     VectorCopy (plane->normal, t->normal);
  37.     t->dist = plane->dist;
  38.     
  39.     for (i=0 ; i<2 ; i++)
  40.     {
  41.         if (node->children[i] < 0)
  42.             t->children[i] = dleafs[-node->children[i] - 1].contents;
  43.         else
  44.         {
  45.             t->children[i] = tnode_p - tnodes;
  46.             MakeTnode (node->children[i]);
  47.         }
  48.     }
  49.             
  50. }
  51.  
  52.  
  53. /*
  54. =============
  55. MakeTnodes
  56.  
  57. Loads the node structure out of a .bsp file to be used for light occlusion
  58. =============
  59. */
  60. void MakeTnodes (dmodel_t *bm)
  61. {
  62.     tnode_p = tnodes = malloc(numnodes * sizeof(tnode_t));
  63.     
  64.     MakeTnode (0);
  65. }
  66.  
  67.  
  68.  
  69. /*
  70. ==============================================================================
  71.  
  72. LINE TRACING
  73.  
  74. The major lighting operation is a point to point visibility test, performed
  75. by recursive subdivision of the line by the BSP tree.
  76.  
  77. ==============================================================================
  78. */
  79.  
  80. typedef struct
  81. {
  82.     vec3_t    backpt;
  83.     int        side;
  84.     int        node;
  85. } tracestack_t;
  86.  
  87.  
  88. /*
  89. ==============
  90. TestLine
  91. ==============
  92. */
  93. qboolean TestLine (vec3_t start, vec3_t stop)
  94. {
  95.     int                node;
  96.     float            front, back;
  97.     tracestack_t    *tstack_p;
  98.     int                side;
  99.     float             frontx,fronty, frontz, backx, backy, backz;
  100.     tracestack_t    tracestack[64];
  101.     tnode_t            *tnode;
  102.     
  103.     frontx = start[0];
  104.     fronty = start[1];
  105.     frontz = start[2];
  106.     backx = stop[0];
  107.     backy = stop[1];
  108.     backz = stop[2];
  109.     
  110.     tstack_p = tracestack;
  111.     node = 0;
  112.     
  113.     while (1)
  114.     {
  115.         while (node < 0 && node != CONTENTS_SOLID)
  116.         {
  117.         // pop up the stack for a back side
  118.             tstack_p--;
  119.             if (tstack_p < tracestack)
  120.                 return true;
  121.             node = tstack_p->node;
  122.             
  123.         // set the hit point for this plane
  124.             
  125.             frontx = backx;
  126.             fronty = backy;
  127.             frontz = backz;
  128.             
  129.         // go down the back side
  130.  
  131.             backx = tstack_p->backpt[0];
  132.             backy = tstack_p->backpt[1];
  133.             backz = tstack_p->backpt[2];
  134.             
  135.             node = tnodes[tstack_p->node].children[!tstack_p->side];
  136.         }
  137.  
  138.         if (node == CONTENTS_SOLID)
  139.             return false;    // DONE!
  140.         
  141.         tnode = &tnodes[node];
  142.         
  143.         switch (tnode->type)
  144.         {
  145.         case PLANE_X:
  146.             front = frontx - tnode->dist;
  147.             back = backx - tnode->dist;
  148.             break;
  149.         case PLANE_Y:
  150.             front = fronty - tnode->dist;
  151.             back = backy - tnode->dist;
  152.             break;
  153.         case PLANE_Z:
  154.             front = frontz - tnode->dist;
  155.             back = backz - tnode->dist;
  156.             break;
  157.         default:
  158.             front = (frontx*tnode->normal[0] + fronty*tnode->normal[1] + frontz*tnode->normal[2]) - tnode->dist;
  159.             back = (backx*tnode->normal[0] + backy*tnode->normal[1] + backz*tnode->normal[2]) - tnode->dist;
  160.             break;
  161.         }
  162.  
  163.         if (front > -ON_EPSILON && back > -ON_EPSILON)
  164. //        if (front > 0 && back > 0)
  165.         {
  166.             node = tnode->children[0];
  167.             continue;
  168.         }
  169.         
  170.         if (front < ON_EPSILON && back < ON_EPSILON)
  171. //        if (front <= 0 && back <= 0)
  172.         {
  173.             node = tnode->children[1];
  174.             continue;
  175.         }
  176.  
  177.         side = front < 0;
  178.         
  179.         front = front / (front-back);
  180.     
  181.         tstack_p->node = node;
  182.         tstack_p->side = side;
  183.         tstack_p->backpt[0] = backx;
  184.         tstack_p->backpt[1] = backy;
  185.         tstack_p->backpt[2] = backz;
  186.         
  187.         tstack_p++;
  188.         
  189.         backx = frontx + front*(backx-frontx);
  190.         backy = fronty + front*(backy-fronty);
  191.         backz = frontz + front*(backz-frontz);
  192.         
  193.         node = tnode->children[side];        
  194.     }    
  195. }
  196.  
  197.  
  198.