home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / glquake_src / gl_refrag.c < prev    next >
C/C++ Source or Header  |  1999-12-28  |  4KB  |  235 lines

  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. // r_efrag.c
  21.  
  22. #include "quakedef.h"
  23.  
  24. mnode_t *r_pefragtopnode;
  25.  
  26.  
  27. //===========================================================================
  28.  
  29. /*
  30. ===============================================================================
  31.  
  32.           ENTITY FRAGMENT FUNCTIONS
  33.  
  34. ===============================================================================
  35. */
  36.  
  37. efrag_t   **lastlink;
  38.  
  39. vec3_t    r_emins, r_emaxs;
  40.  
  41. entity_t  *r_addent;
  42.  
  43.  
  44. /*
  45. ================
  46. R_RemoveEfrags
  47.  
  48. Call when removing an object from the world or moving it to another position
  49. ================
  50. */
  51. void R_RemoveEfrags (entity_t *ent)
  52. {
  53.   efrag_t   *ef, *old, *walk, **prev;
  54.   
  55.   ef = ent->efrag;
  56.   
  57.   while (ef)
  58.   {
  59.     prev = &ef->leaf->efrags;
  60.     while (1)
  61.     {
  62.       walk = *prev;
  63.       if (!walk)
  64.         break;
  65.       if (walk == ef)
  66.       { // remove this fragment
  67.         *prev = ef->leafnext;
  68.         break;
  69.       }
  70.       else
  71.         prev = &walk->leafnext;
  72.     }
  73.         
  74.     old = ef;
  75.     ef = ef->entnext;
  76.     
  77.   // put it on the free list
  78.     old->entnext = cl.free_efrags;
  79.     cl.free_efrags = old;
  80.   }
  81.   
  82.   ent->efrag = NULL; 
  83. }
  84.  
  85. /*
  86. ===================
  87. R_SplitEntityOnNode
  88. ===================
  89. */
  90. void R_SplitEntityOnNode (mnode_t *node)
  91. {
  92.   efrag_t   *ef;
  93.   mplane_t  *splitplane;
  94.   mleaf_t   *leaf;
  95.   int     sides;
  96.   
  97.   if (node->contents == CONTENTS_SOLID)
  98.   {
  99.     return;
  100.   }
  101.   
  102. // add an efrag if the node is a leaf
  103.  
  104.   if ( node->contents < 0)
  105.   {
  106.     if (!r_pefragtopnode)
  107.       r_pefragtopnode = node;
  108.  
  109.     leaf = (mleaf_t *)node;
  110.  
  111. // grab an efrag off the free list
  112.     ef = cl.free_efrags;
  113.     if (!ef)
  114.     {
  115.       Con_Printf ("Too many efrags!\n");
  116.       return;   // no free fragments...
  117.     }
  118.     cl.free_efrags = cl.free_efrags->entnext;
  119.  
  120.     ef->entity = r_addent;
  121.     
  122. // add the entity link  
  123.     *lastlink = ef;
  124.     lastlink = &ef->entnext;
  125.     ef->entnext = NULL;
  126.     
  127. // set the leaf links
  128.     ef->leaf = leaf;
  129.     ef->leafnext = leaf->efrags;
  130.     leaf->efrags = ef;
  131.       
  132.     return;
  133.   }
  134.   
  135. // NODE_MIXED
  136.  
  137.   splitplane = node->plane;
  138.   sides = BOX_ON_PLANE_SIDE(r_emins, r_emaxs, splitplane);
  139.   
  140.   if (sides == 3)
  141.   {
  142.   // split on this plane
  143.   // if this is the first splitter of this bmodel, remember it
  144.     if (!r_pefragtopnode)
  145.       r_pefragtopnode = node;
  146.   }
  147.   
  148. // recurse down the contacted sides
  149.   if (sides & 1)
  150.     R_SplitEntityOnNode (node->children[0]);
  151.     
  152.   if (sides & 2)
  153.     R_SplitEntityOnNode (node->children[1]);
  154. }
  155.  
  156.  
  157.  
  158. /*
  159. ===========
  160. R_AddEfrags
  161. ===========
  162. */
  163. void R_AddEfrags (entity_t *ent)
  164. {
  165.   model_t   *entmodel;
  166.   int     i;
  167.     
  168.   if (!ent->model)
  169.     return;
  170.  
  171.   r_addent = ent;
  172.       
  173.   lastlink = &ent->efrag;
  174.   r_pefragtopnode = NULL;
  175.   
  176.   entmodel = ent->model;
  177.  
  178.   for (i=0 ; i<3 ; i++)
  179.   {
  180.     r_emins[i] = ent->origin[i] + entmodel->mins[i];
  181.     r_emaxs[i] = ent->origin[i] + entmodel->maxs[i];
  182.   }
  183.  
  184.   R_SplitEntityOnNode (cl.worldmodel->nodes);
  185.  
  186.   ent->topnode = r_pefragtopnode;
  187. }
  188.  
  189.  
  190. /*
  191. ================
  192. R_StoreEfrags
  193.  
  194. // FIXME: a lot of this goes away with edge-based
  195. ================
  196. */
  197. void R_StoreEfrags (efrag_t **ppefrag)
  198. {
  199.   entity_t  *pent;
  200.   model_t   *clmodel;
  201.   efrag_t   *pefrag;
  202.  
  203.  
  204.   while ((pefrag = *ppefrag) != NULL)
  205.   {
  206.     pent = pefrag->entity;
  207.     clmodel = pent->model;
  208.  
  209.     switch (clmodel->type)
  210.     {
  211.     case mod_alias:
  212.     case mod_brush:
  213.     case mod_sprite:
  214.       pent = pefrag->entity;
  215.  
  216.       if ((pent->visframe != r_framecount) &&
  217.         (cl_numvisedicts < MAX_VISEDICTS))
  218.       {
  219.         cl_visedicts[cl_numvisedicts++] = pent;
  220.  
  221.       // mark that we've recorded this entity for this frame
  222.         pent->visframe = r_framecount;
  223.       }
  224.  
  225.       ppefrag = &pefrag->leafnext;
  226.       break;
  227.  
  228.     default:  
  229.       Sys_Error ("R_StoreEfrags: Bad entity type %d\n", clmodel->type);
  230.     }
  231.   }
  232. }
  233.  
  234.  
  235.