Annotation of quake1/r_efrag.c, revision 1.1.1.1

1.1       root        1: // r_efrag.c
                      2: 
                      3: #include "quakedef.h"
                      4: #include "r_local.h"
                      5: 
                      6: mnode_t        *r_pefragtopnode;
                      7: 
                      8: 
                      9: //===========================================================================
                     10: 
                     11: /*
                     12: ===============================================================================
                     13: 
                     14:                                        ENTITY FRAGMENT FUNCTIONS
                     15: 
                     16: ===============================================================================
                     17: */
                     18: 
                     19: efrag_t                **lastlink;
                     20: 
                     21: vec3_t         r_emins, r_emaxs;
                     22: 
                     23: entity_t       *r_addent;
                     24: 
                     25: 
                     26: /*
                     27: ================
                     28: R_RemoveEfrags
                     29: 
                     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:        
                     37:        ef = ent->efrag;
                     38:        
                     39:        while (ef)
                     40:        {
                     41:                prev = &ef->leaf->efrags;
                     42:                while (1)
                     43:                {
                     44:                        walk = *prev;
                     45:                        if (!walk)
                     46:                                break;
                     47:                        if (walk == ef)
                     48:                        {       // remove this fragment
                     49:                                *prev = ef->leafnext;
                     50:                                break;
                     51:                        }
                     52:                        else
                     53:                                prev = &walk->leafnext;
                     54:                }
                     55:                                
                     56:                old = ef;
                     57:                ef = ef->entnext;
                     58:                
                     59:        // put it on the free list
                     60:                old->entnext = cl.free_efrags;
                     61:                cl.free_efrags = old;
                     62:        }
                     63:        
                     64:        ent->efrag = NULL; 
                     65: }
                     66: 
                     67: /*
                     68: ===================
                     69: R_SplitEntityOnNode
                     70: ===================
                     71: */
                     72: void R_SplitEntityOnNode (mnode_t *node)
                     73: {
                     74:        efrag_t         *ef;
                     75:        mplane_t        *splitplane;
                     76:        mleaf_t         *leaf;
                     77:        int                     sides;
                     78:        
                     79:        if (node->contents == CONTENTS_SOLID)
                     80:        {
                     81:                return;
                     82:        }
                     83:        
                     84: // add an efrag if the node is a leaf
                     85: 
                     86:        if ( node->contents < 0)
                     87:        {
                     88:                if (!r_pefragtopnode)
                     89:                        r_pefragtopnode = node;
                     90: 
                     91:                leaf = (mleaf_t *)node;
                     92: 
                     93: // grab an efrag off the free list
                     94:                ef = cl.free_efrags;
                     95:                if (!ef)
                     96:                {
                     97:                        Con_Printf ("Too many efrags!\n");
                     98:                        return;         // no free fragments...
                     99:                }
                    100:                cl.free_efrags = cl.free_efrags->entnext;
                    101: 
                    102:                ef->entity = r_addent;
                    103:                
                    104: // add the entity link 
                    105:                *lastlink = ef;
                    106:                lastlink = &ef->entnext;
                    107:                ef->entnext = NULL;
                    108:                
                    109: // set the leaf links
                    110:                ef->leaf = leaf;
                    111:                ef->leafnext = leaf->efrags;
                    112:                leaf->efrags = ef;
                    113:                        
                    114:                return;
                    115:        }
                    116:        
                    117: // NODE_MIXED
                    118: 
                    119:        splitplane = node->plane;
                    120:        sides = BOX_ON_PLANE_SIDE(r_emins, r_emaxs, splitplane);
                    121:        
                    122:        if (sides == 3)
                    123:        {
                    124:        // split on this plane
                    125:        // if this is the first splitter of this bmodel, remember it
                    126:                if (!r_pefragtopnode)
                    127:                        r_pefragtopnode = node;
                    128:        }
                    129:        
                    130: // recurse down the contacted sides
                    131:        if (sides & 1)
                    132:                R_SplitEntityOnNode (node->children[0]);
                    133:                
                    134:        if (sides & 2)
                    135:                R_SplitEntityOnNode (node->children[1]);
                    136: }
                    137: 
                    138: 
                    139: /*
                    140: ===================
                    141: R_SplitEntityOnNode2
                    142: ===================
                    143: */
                    144: void R_SplitEntityOnNode2 (mnode_t *node)
                    145: {
                    146:        mplane_t        *splitplane;
                    147:        int                     sides;
                    148: 
                    149:        if (node->visframe != r_visframecount)
                    150:                return;
                    151:        
                    152:        if (node->contents < 0)
                    153:        {
                    154:                if (node->contents != CONTENTS_SOLID)
                    155:                        r_pefragtopnode = node; // we've reached a non-solid leaf, so it's
                    156:                                                                        //  visible and not BSP clipped
                    157:                return;
                    158:        }
                    159:        
                    160:        splitplane = node->plane;
                    161:        sides = BOX_ON_PLANE_SIDE(r_emins, r_emaxs, splitplane);
                    162:        
                    163:        if (sides == 3)
                    164:        {
                    165:        // remember first splitter
                    166:                r_pefragtopnode = node;
                    167:                return;
                    168:        }
                    169:        
                    170: // not split yet; recurse down the contacted side
                    171:        if (sides & 1)
                    172:                R_SplitEntityOnNode2 (node->children[0]);
                    173:        else
                    174:                R_SplitEntityOnNode2 (node->children[1]);
                    175: }
                    176: 
                    177: 
                    178: /*
                    179: ===========
                    180: R_AddEfrags
                    181: ===========
                    182: */
                    183: void R_AddEfrags (entity_t *ent)
                    184: {
                    185:        model_t         *entmodel;
                    186:        int                     i;
                    187:                
                    188:        if (!ent->model)
                    189:                return;
                    190: 
                    191:        if (ent == cl_entities)
                    192:                return;         // never add the world
                    193: 
                    194:        r_addent = ent;
                    195:                        
                    196:        lastlink = &ent->efrag;
                    197:        r_pefragtopnode = NULL;
                    198:        
                    199:        entmodel = ent->model;
                    200: 
                    201:        for (i=0 ; i<3 ; i++)
                    202:        {
                    203:                r_emins[i] = ent->origin[i] + entmodel->mins[i];
                    204:                r_emaxs[i] = ent->origin[i] + entmodel->maxs[i];
                    205:        }
                    206: 
                    207:        R_SplitEntityOnNode (cl.worldmodel->nodes);
                    208: 
                    209:        ent->topnode = r_pefragtopnode;
                    210: }
                    211: 
                    212: 
                    213: /*
                    214: ================
                    215: R_StoreEfrags
                    216: 
                    217: // FIXME: a lot of this goes away with edge-based
                    218: ================
                    219: */
                    220: void R_StoreEfrags (efrag_t **ppefrag)
                    221: {
                    222:        entity_t        *pent;
                    223:        model_t         *clmodel;
                    224:        efrag_t         *pefrag;
                    225: 
                    226: 
                    227:        while ((pefrag = *ppefrag) != NULL)
                    228:        {
                    229:                pent = pefrag->entity;
                    230:                clmodel = pent->model;
                    231: 
                    232:                switch (clmodel->type)
                    233:                {
                    234:                case mod_alias:
                    235:                case mod_brush:
                    236:                case mod_sprite:
                    237:                        pent = pefrag->entity;
                    238: 
                    239:                        if ((pent->visframe != r_framecount) &&
                    240:                                (cl_numvisedicts < MAX_VISEDICTS))
                    241:                        {
                    242:                                cl_visedicts[cl_numvisedicts++] = pent;
                    243: 
                    244:                        // mark that we've recorded this entity for this frame
                    245:                                pent->visframe = r_framecount;
                    246:                        }
                    247: 
                    248:                        ppefrag = &pefrag->leafnext;
                    249:                        break;
                    250: 
                    251:                default:        
                    252:                        Sys_Error ("R_StoreEfrags: Bad entity type %d\n", clmodel->type);
                    253:                }
                    254:        }
                    255: }
                    256: 
                    257: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.