gl_refrag.c 4.1 KB

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