2 Copyright (C) 1996-1997 Id Software, Inc.
3 Copyright (C) 2007 Peter Mackay and Chris Swindle.
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 See the GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 #include "../quakedef.h"
28 mnode_t
*r_pefragtopnode
;
31 //===========================================================================
34 ===============================================================================
36 ENTITY FRAGMENT FUNCTIONS
38 ===============================================================================
43 vec3_t r_emins
, r_emaxs
;
52 Call when removing an object from the world or moving it to another position
55 void R_RemoveEfrags (entity_t
*ent
)
57 efrag_t
*ef
, *old
, *walk
, **prev
;
63 prev
= &ef
->leaf
->efrags
;
70 { // remove this fragment
75 prev
= &walk
->leafnext
;
81 // put it on the free list
82 old
->entnext
= cl
.free_efrags
;
94 void R_SplitEntityOnNode (mnode_t
*node
)
101 if (node
->contents
== CONTENTS_SOLID
)
106 // add an efrag if the node is a leaf
108 if ( node
->contents
< 0)
110 if (!r_pefragtopnode
)
111 r_pefragtopnode
= node
;
113 leaf
= (mleaf_t
*)node
;
115 // grab an efrag off the free list
119 Con_Printf ("Too many efrags!\n");
120 return; // no free fragments...
122 cl
.free_efrags
= cl
.free_efrags
->entnext
;
124 ef
->entity
= r_addent
;
126 // add the entity link
128 lastlink
= &ef
->entnext
;
131 // set the leaf links
133 ef
->leafnext
= leaf
->efrags
;
141 splitplane
= node
->plane
;
142 sides
= BOX_ON_PLANE_SIDE(r_emins
, r_emaxs
, splitplane
);
146 // split on this plane
147 // if this is the first splitter of this bmodel, remember it
148 if (!r_pefragtopnode
)
149 r_pefragtopnode
= node
;
152 // recurse down the contacted sides
154 R_SplitEntityOnNode (node
->children
[0]);
157 R_SplitEntityOnNode (node
->children
[1]);
167 void R_AddEfrags (entity_t
*ent
)
177 lastlink
= &ent
->efrag
;
178 r_pefragtopnode
= NULL
;
180 entmodel
= ent
->model
;
182 for (i
=0 ; i
<3 ; i
++)
184 r_emins
[i
] = ent
->origin
[i
] + entmodel
->mins
[i
];
185 r_emaxs
[i
] = ent
->origin
[i
] + entmodel
->maxs
[i
];
188 R_SplitEntityOnNode (cl
.worldmodel
->nodes
);
190 ent
->topnode
= r_pefragtopnode
;
198 // FIXME: a lot of this goes away with edge-based
201 void R_StoreEfrags (efrag_t
**ppefrag
)
208 while ((pefrag
= *ppefrag
) != NULL
)
210 pent
= pefrag
->entity
;
211 clmodel
= pent
->model
;
213 switch (clmodel
->type
)
218 pent
= pefrag
->entity
;
220 if ((pent
->visframe
!= r_framecount
) &&
221 (cl_numvisedicts
< MAX_VISEDICTS
))
223 cl_visedicts
[cl_numvisedicts
++] = pent
;
225 // mark that we've recorded this entity for this frame
226 pent
->visframe
= r_framecount
;
229 ppefrag
= &pefrag
->leafnext
;
233 Sys_Error ("R_StoreEfrags: Bad entity type %d\n", clmodel
->type
);