2 Copyright (C) 1996-1997 Id Software, Inc.
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.
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.
13 See the GNU General Public License for more details.
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.
24 mnode_t *r_pefragtopnode;
27 //===========================================================================
30 ===============================================================================
32 ENTITY FRAGMENT FUNCTIONS
34 ===============================================================================
39 vec3_t r_emins, r_emaxs;
48 Call when removing an object from the world or moving it to another position
51 void R_RemoveEfrags (entity_t *ent)
53 efrag_t *ef, *old, *walk, **prev;
59 prev = &ef->leaf->efrags;
66 { // remove this fragment
71 prev = &walk->leafnext;
77 // put it on the free list
78 old->entnext = cl.free_efrags;
90 void R_SplitEntityOnNode (mnode_t *node)
98 if (node->contents == CONTENTS_SOLID)
103 // add an efrag if the node is a leaf
105 if ( node->contents < 0)
107 if (!r_pefragtopnode)
108 r_pefragtopnode = node;
110 leaf = (mleaf_t *)node;
112 // grab an efrag off the free list
116 Con_Printf ("Too many efrags!\n");
117 return; // no free fragments...
119 cl.free_efrags = cl.free_efrags->entnext;
121 ef->entity = r_addent;
123 // add the entity link
125 lastlink = &ef->entnext;
128 // set the leaf links
130 ef->leafnext = leaf->efrags;
138 splitplane = node->plane;
139 sides = BOX_ON_PLANE_SIDE(r_emins, r_emaxs, splitplane);
143 // split on this plane
144 // if this is the first splitter of this bmodel, remember it
145 if (!r_pefragtopnode)
146 r_pefragtopnode = node;
149 // recurse down the contacted sides
150 // LordHavoc: optimized recursion
151 // if (sides & 1) R_SplitEntityOnNode (node->children[0]);
152 // if (sides & 2) R_SplitEntityOnNode (node->children[1]);
157 R_SplitEntityOnNode (node->children[0]);
158 node = node->children[1];
163 node = node->children[0];
168 node = node->children[1];
179 void R_AddEfrags (entity_t *ent)
189 lastlink = &ent->efrag;
190 r_pefragtopnode = NULL;
192 entmodel = ent->model;
194 for (i=0 ; i<3 ; i++)
196 r_emins[i] = ent->origin[i] + entmodel->mins[i];
197 r_emaxs[i] = ent->origin[i] + entmodel->maxs[i];
200 R_SplitEntityOnNode (cl.worldmodel->nodes);
202 ent->topnode = r_pefragtopnode;
210 // FIXME: a lot of this goes away with edge-based
213 void R_StoreEfrags (efrag_t **ppefrag)
220 while ((pefrag = *ppefrag) != NULL)
222 pent = pefrag->entity;
223 clmodel = pent->model;
225 switch (clmodel->type)
230 pent = pefrag->entity;
232 if ((pent->visframe != r_framecount) && (cl_numvisedicts < MAX_VISEDICTS))
234 cl_visedicts[cl_numvisedicts++] = pent;
235 pent->visframe = r_framecount; // render each entity only once per frame
238 ppefrag = &pefrag->leafnext;
242 Host_Error ("R_StoreEfrags: Bad entity type %d\n", clmodel->type);