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.
25 mnode_t
*r_pefragtopnode
;
28 //===========================================================================
31 ===============================================================================
33 ENTITY FRAGMENT FUNCTIONS
35 ===============================================================================
40 vec3_t r_emins
, r_emaxs
;
49 Call when removing an object from the world or moving it to another position
52 void R_RemoveEfrags (entity_t
*ent
)
54 efrag_t
*ef
, *old
, *walk
, **prev
;
60 prev
= &ef
->leaf
->efrags
;
67 { // remove this fragment
72 prev
= &walk
->leafnext
;
78 // put it on the free list
79 old
->entnext
= cl
.free_efrags
;
91 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
151 R_SplitEntityOnNode (node
->children
[0]);
154 R_SplitEntityOnNode (node
->children
[1]);
163 void R_SplitEntityOnNode2 (mnode_t
*node
)
165 mplane_t
*splitplane
;
168 if (node
->visframe
!= r_visframecount
)
171 if (node
->contents
< 0)
173 if (node
->contents
!= CONTENTS_SOLID
)
174 r_pefragtopnode
= node
; // we've reached a non-solid leaf, so it's
175 // visible and not BSP clipped
179 splitplane
= node
->plane
;
180 sides
= BOX_ON_PLANE_SIDE(r_emins
, r_emaxs
, splitplane
);
184 // remember first splitter
185 r_pefragtopnode
= node
;
189 // not split yet; recurse down the contacted side
191 R_SplitEntityOnNode2 (node
->children
[0]);
193 R_SplitEntityOnNode2 (node
->children
[1]);
202 void R_AddEfrags (entity_t
*ent
)
210 if (ent
== cl_entities
)
211 return; // never add the world
215 lastlink
= &ent
->efrag
;
216 r_pefragtopnode
= NULL
;
218 entmodel
= ent
->model
;
220 for (i
=0 ; i
<3 ; i
++)
222 r_emins
[i
] = ent
->origin
[i
] + entmodel
->mins
[i
];
223 r_emaxs
[i
] = ent
->origin
[i
] + entmodel
->maxs
[i
];
226 R_SplitEntityOnNode (cl
.worldmodel
->nodes
);
228 ent
->topnode
= r_pefragtopnode
;
236 // FIXME: a lot of this goes away with edge-based
239 void R_StoreEfrags (efrag_t
**ppefrag
)
246 while ((pefrag
= *ppefrag
) != NULL
)
248 pent
= pefrag
->entity
;
249 clmodel
= pent
->model
;
251 switch (clmodel
->type
)
256 pent
= pefrag
->entity
;
258 if ((pent
->visframe
!= r_framecount
) &&
259 (cl_numvisedicts
< MAX_VISEDICTS
))
261 cl_visedicts
[cl_numvisedicts
++] = pent
;
263 // mark that we've recorded this entity for this frame
264 pent
->visframe
= r_framecount
;
267 ppefrag
= &pefrag
->leafnext
;
271 Sys_Error ("R_StoreEfrags: Bad entity type %d\n", clmodel
->type
);