Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

tr_world.c File Reference

#include "tr_local.h"

Include dependency graph for tr_world.c:

Include dependency graph

Go to the source code of this file.

Functions

void R_AddBrushModelSurfaces (trRefEntity_t *ent)
void R_AddWorldSurface (msurface_t *surf, int dlightBits)
void R_AddWorldSurfaces (void)
const byteR_ClusterPVS (int cluster)
qboolean R_CullGrid (srfGridMesh_t *cv)
qboolean R_CullSurface (surfaceType_t *surface, shader_t *shader)
qboolean R_CullTriSurf (srfTriangles_t *cv)
int R_DlightFace (srfSurfaceFace_t *face, int dlightBits)
int R_DlightGrid (srfGridMesh_t *grid, int dlightBits)
int R_DlightSurface (msurface_t *surf, int dlightBits)
int R_DlightTrisurf (srfTriangles_t *surf, int dlightBits)
qboolean R_inPVS (const vec3_t p1, const vec3_t p2)
void R_MarkLeaves (void)
mnode_tR_PointInLeaf (const vec3_t p)
void R_RecursiveWorldNode (mnode_t *node, int planeBits, int dlightBits)


Function Documentation

void R_AddBrushModelSurfaces trRefEntity_t ent  ) 
 

Definition at line 319 of file tr_world.c.

References model_s::bmodel, bmodel_t::bounds, trGlobals_t::currentEntity, trRefEntity_t::e, bmodel_t::firstSurface, refEntity_t::hModel, i, model_t, trRefEntity_t::needDlights, bmodel_t::numSurfaces, R_AddWorldSurface(), R_CullLocalBox(), R_DlightBmodel(), R_GetModelByHandle(), and tr.

Referenced by R_AddEntitySurfaces().

00319                                                     {
00320     bmodel_t    *bmodel;
00321     int         clip;
00322     model_t     *pModel;
00323     int         i;
00324 
00325     pModel = R_GetModelByHandle( ent->e.hModel );
00326 
00327     bmodel = pModel->bmodel;
00328 
00329     clip = R_CullLocalBox( bmodel->bounds );
00330     if ( clip == CULL_OUT ) {
00331         return;
00332     }
00333     
00334     R_DlightBmodel( bmodel );
00335 
00336     for ( i = 0 ; i < bmodel->numSurfaces ; i++ ) {
00337         R_AddWorldSurface( bmodel->firstSurface + i, tr.currentEntity->needDlights );
00338     }
00339 }

Here is the call graph for this function:

void R_AddWorldSurface msurface_t surf,
int  dlightBits
[static]
 

Definition at line 284 of file tr_world.c.

References msurface_s::data, msurface_s::fogIndex, msurface_t, R_AddDrawSurf(), R_CullSurface(), R_DlightSurface(), msurface_s::shader, tr, trGlobals_t::viewCount, and msurface_s::viewCount.

Referenced by R_AddBrushModelSurfaces(), and R_RecursiveWorldNode().

00284                                                                   {
00285     if ( surf->viewCount == tr.viewCount ) {
00286         return;     // already in this view
00287     }
00288 
00289     surf->viewCount = tr.viewCount;
00290     // FIXME: bmodel fog?
00291 
00292     // try to cull before dlighting or adding
00293     if ( R_CullSurface( surf->data, surf->shader ) ) {
00294         return;
00295     }
00296 
00297     // check for dlighting
00298     if ( dlightBits ) {
00299         dlightBits = R_DlightSurface( surf, dlightBits );
00300         dlightBits = ( dlightBits != 0 );
00301     }
00302 
00303     R_AddDrawSurf( surf->data, surf->shader, surf->fogIndex, dlightBits );
00304 }

Here is the call graph for this function:

void R_AddWorldSurfaces void   ) 
 

Definition at line 645 of file tr_world.c.

References ClearBounds(), trGlobals_t::currentEntityNum, cvar_s::integer, world_t::nodes, trRefdef_t::num_dlights, r_drawworld, R_MarkLeaves(), R_RecursiveWorldNode(), trRefdef_t::rdflags, trGlobals_t::refdef, trGlobals_t::shiftedEntityNum, tr, trGlobals_t::viewParms, viewParms_t::visBounds, and trGlobals_t::world.

Referenced by R_GenerateDrawSurfs().

00645                                {
00646     if ( !r_drawworld->integer ) {
00647         return;
00648     }
00649 
00650     if ( tr.refdef.rdflags & RDF_NOWORLDMODEL ) {
00651         return;
00652     }
00653 
00654     tr.currentEntityNum = ENTITYNUM_WORLD;
00655     tr.shiftedEntityNum = tr.currentEntityNum << QSORT_ENTITYNUM_SHIFT;
00656 
00657     // determine which leaves are in the PVS / areamask
00658     R_MarkLeaves ();
00659 
00660     // clear out the visible min/max
00661     ClearBounds( tr.viewParms.visBounds[0], tr.viewParms.visBounds[1] );
00662 
00663     // perform frustum culling and add all the potentially visible surfaces
00664     if ( tr.refdef.num_dlights > 32 ) {
00665         tr.refdef.num_dlights = 32 ;
00666     }
00667     R_RecursiveWorldNode( tr.world->nodes, 15, ( 1 << tr.refdef.num_dlights ) - 1 );
00668 }

Here is the call graph for this function:

const byte* R_ClusterPVS int  cluster  )  [static]
 

Definition at line 532 of file tr_world.c.

References byte, world_t::clusterBytes, world_t::novis, world_t::numClusters, tr, world_t::vis, and trGlobals_t::world.

Referenced by R_MarkLeaves().

00532                                               {
00533     if (!tr.world || !tr.world->vis || cluster < 0 || cluster >= tr.world->numClusters ) {
00534         return tr.world->novis;
00535     }
00536 
00537     return tr.world->vis + cluster * tr.world->clusterBytes;
00538 }

qboolean R_CullGrid srfGridMesh_t cv  )  [static]
 

Definition at line 53 of file tr_world.c.

References frontEndCounters_t::c_box_cull_patch_clip, frontEndCounters_t::c_box_cull_patch_in, frontEndCounters_t::c_box_cull_patch_out, frontEndCounters_t::c_sphere_cull_patch_clip, frontEndCounters_t::c_sphere_cull_patch_in, frontEndCounters_t::c_sphere_cull_patch_out, trGlobals_t::currentEntityNum, cvar_s::integer, srfGridMesh_s::localOrigin, srfGridMesh_s::meshBounds, srfGridMesh_s::meshRadius, trGlobals_t::pc, qboolean, R_CullLocalBox(), R_CullLocalPointAndRadius(), R_CullPointAndRadius(), r_nocurves, srfGridMesh_t, and tr.

Referenced by R_CullSurface().

00053                                                 {
00054     int     boxCull;
00055     int     sphereCull;
00056 
00057     if ( r_nocurves->integer ) {
00058         return qtrue;
00059     }
00060 
00061     if ( tr.currentEntityNum != ENTITYNUM_WORLD ) {
00062         sphereCull = R_CullLocalPointAndRadius( cv->localOrigin, cv->meshRadius );
00063     } else {
00064         sphereCull = R_CullPointAndRadius( cv->localOrigin, cv->meshRadius );
00065     }
00066     boxCull = CULL_OUT;
00067     
00068     // check for trivial reject
00069     if ( sphereCull == CULL_OUT )
00070     {
00071         tr.pc.c_sphere_cull_patch_out++;
00072         return qtrue;
00073     }
00074     // check bounding box if necessary
00075     else if ( sphereCull == CULL_CLIP )
00076     {
00077         tr.pc.c_sphere_cull_patch_clip++;
00078 
00079         boxCull = R_CullLocalBox( cv->meshBounds );
00080 
00081         if ( boxCull == CULL_OUT ) 
00082         {
00083             tr.pc.c_box_cull_patch_out++;
00084             return qtrue;
00085         }
00086         else if ( boxCull == CULL_IN )
00087         {
00088             tr.pc.c_box_cull_patch_in++;
00089         }
00090         else
00091         {
00092             tr.pc.c_box_cull_patch_clip++;
00093         }
00094     }
00095     else
00096     {
00097         tr.pc.c_sphere_cull_patch_in++;
00098     }
00099 
00100     return qfalse;
00101 }

Here is the call graph for this function:

qboolean R_CullSurface surfaceType_t surface,
shader_t shader
[static]
 

Definition at line 114 of file tr_world.c.

References shader_s::cullType, d, cplane_s::dist, DotProduct, cvar_s::integer, cplane_s::normal, trGlobals_t::or, srfSurfaceFace_t::plane, qboolean, R_CullGrid(), R_CullTriSurf(), r_facePlaneCull, r_nocull, shader_t, srfGridMesh_t, tr, and orientationr_t::viewOrigin.

Referenced by R_AddWorldSurface().

00114                                                                           {
00115     srfSurfaceFace_t *sface;
00116     float           d;
00117 
00118     if ( r_nocull->integer ) {
00119         return qfalse;
00120     }
00121 
00122     if ( *surface == SF_GRID ) {
00123         return R_CullGrid( (srfGridMesh_t *)surface );
00124     }
00125 
00126     if ( *surface == SF_TRIANGLES ) {
00127         return R_CullTriSurf( (srfTriangles_t *)surface );
00128     }
00129 
00130     if ( *surface != SF_FACE ) {
00131         return qfalse;
00132     }
00133 
00134     if ( shader->cullType == CT_TWO_SIDED ) {
00135         return qfalse;
00136     }
00137 
00138     // face culling
00139     if ( !r_facePlaneCull->integer ) {
00140         return qfalse;
00141     }
00142 
00143     sface = ( srfSurfaceFace_t * ) surface;
00144     d = DotProduct (tr.or.viewOrigin, sface->plane.normal);
00145 
00146     // don't cull exactly on the plane, because there are levels of rounding
00147     // through the BSP, ICD, and hardware that may cause pixel gaps if an
00148     // epsilon isn't allowed here 
00149     if ( shader->cullType == CT_FRONT_SIDED ) {
00150         if ( d < sface->plane.dist - 8 ) {
00151             return qtrue;
00152         }
00153     } else {
00154         if ( d > sface->plane.dist + 8 ) {
00155             return qtrue;
00156         }
00157     }
00158 
00159     return qfalse;
00160 }

Here is the call graph for this function:

qboolean R_CullTriSurf srfTriangles_t cv  )  [static]
 

Definition at line 34 of file tr_world.c.

References srfTriangles_t::bounds, qboolean, and R_CullLocalBox().

Referenced by R_CullSurface().

00034                                                     {
00035     int     boxCull;
00036 
00037     boxCull = R_CullLocalBox( cv->bounds );
00038 
00039     if ( boxCull == CULL_OUT ) {
00040         return qtrue;
00041     }
00042     return qfalse;
00043 }

Here is the call graph for this function:

int R_DlightFace srfSurfaceFace_t face,
int  dlightBits
[static]
 

Definition at line 163 of file tr_world.c.

References frontEndCounters_t::c_dlightSurfacesCulled, d, cplane_s::dist, dlight_t, srfSurfaceFace_t::dlightBits, trRefdef_t::dlights, DotProduct, i, cplane_s::normal, trRefdef_t::num_dlights, dlight_s::origin, trGlobals_t::pc, srfSurfaceFace_t::plane, dlight_s::radius, trGlobals_t::refdef, trGlobals_t::smpFrame, and tr.

Referenced by R_DlightSurface().

00163                                                                   {
00164     float       d;
00165     int         i;
00166     dlight_t    *dl;
00167 
00168     for ( i = 0 ; i < tr.refdef.num_dlights ; i++ ) {
00169         if ( ! ( dlightBits & ( 1 << i ) ) ) {
00170             continue;
00171         }
00172         dl = &tr.refdef.dlights[i];
00173         d = DotProduct( dl->origin, face->plane.normal ) - face->plane.dist;
00174         if ( d < -dl->radius || d > dl->radius ) {
00175             // dlight doesn't reach the plane
00176             dlightBits &= ~( 1 << i );
00177         }
00178     }
00179 
00180     if ( !dlightBits ) {
00181         tr.pc.c_dlightSurfacesCulled++;
00182     }
00183 
00184     face->dlightBits[ tr.smpFrame ] = dlightBits;
00185     return dlightBits;
00186 }

int R_DlightGrid srfGridMesh_t grid,
int  dlightBits
[static]
 

Definition at line 188 of file tr_world.c.

References frontEndCounters_t::c_dlightSurfacesCulled, dlight_t, srfGridMesh_s::dlightBits, trRefdef_t::dlights, i, srfGridMesh_s::meshBounds, trRefdef_t::num_dlights, dlight_s::origin, trGlobals_t::pc, dlight_s::radius, trGlobals_t::refdef, trGlobals_t::smpFrame, srfGridMesh_t, and tr.

Referenced by R_DlightSurface().

00188                                                                {
00189     int         i;
00190     dlight_t    *dl;
00191 
00192     for ( i = 0 ; i < tr.refdef.num_dlights ; i++ ) {
00193         if ( ! ( dlightBits & ( 1 << i ) ) ) {
00194             continue;
00195         }
00196         dl = &tr.refdef.dlights[i];
00197         if ( dl->origin[0] - dl->radius > grid->meshBounds[1][0]
00198             || dl->origin[0] + dl->radius < grid->meshBounds[0][0]
00199             || dl->origin[1] - dl->radius > grid->meshBounds[1][1]
00200             || dl->origin[1] + dl->radius < grid->meshBounds[0][1]
00201             || dl->origin[2] - dl->radius > grid->meshBounds[1][2]
00202             || dl->origin[2] + dl->radius < grid->meshBounds[0][2] ) {
00203             // dlight doesn't reach the bounds
00204             dlightBits &= ~( 1 << i );
00205         }
00206     }
00207 
00208     if ( !dlightBits ) {
00209         tr.pc.c_dlightSurfacesCulled++;
00210     }
00211 
00212     grid->dlightBits[ tr.smpFrame ] = dlightBits;
00213     return dlightBits;
00214 }

int R_DlightSurface msurface_t surf,
int  dlightBits
[static]
 

Definition at line 259 of file tr_world.c.

References frontEndCounters_t::c_dlightSurfaces, msurface_s::data, msurface_t, trGlobals_t::pc, R_DlightFace(), R_DlightGrid(), R_DlightTrisurf(), srfGridMesh_t, and tr.

Referenced by R_AddWorldSurface().

00259                                                                {
00260     if ( *surf->data == SF_FACE ) {
00261         dlightBits = R_DlightFace( (srfSurfaceFace_t *)surf->data, dlightBits );
00262     } else if ( *surf->data == SF_GRID ) {
00263         dlightBits = R_DlightGrid( (srfGridMesh_t *)surf->data, dlightBits );
00264     } else if ( *surf->data == SF_TRIANGLES ) {
00265         dlightBits = R_DlightTrisurf( (srfTriangles_t *)surf->data, dlightBits );
00266     } else {
00267         dlightBits = 0;
00268     }
00269 
00270     if ( dlightBits ) {
00271         tr.pc.c_dlightSurfaces++;
00272     }
00273 
00274     return dlightBits;
00275 }

Here is the call graph for this function:

int R_DlightTrisurf srfTriangles_t surf,
int  dlightBits
[static]
 

Definition at line 217 of file tr_world.c.

References frontEndCounters_t::c_dlightSurfacesCulled, dlight_t, srfTriangles_t::dlightBits, trRefdef_t::dlights, i, trRefdef_t::num_dlights, dlight_s::origin, trGlobals_t::pc, dlight_s::radius, trGlobals_t::refdef, trGlobals_t::smpFrame, and tr.

Referenced by R_DlightSurface().

00217                                                                    {
00218     // FIXME: more dlight culling to trisurfs...
00219     surf->dlightBits[ tr.smpFrame ] = dlightBits;
00220     return dlightBits;
00221 #if 0
00222     int         i;
00223     dlight_t    *dl;
00224 
00225     for ( i = 0 ; i < tr.refdef.num_dlights ; i++ ) {
00226         if ( ! ( dlightBits & ( 1 << i ) ) ) {
00227             continue;
00228         }
00229         dl = &tr.refdef.dlights[i];
00230         if ( dl->origin[0] - dl->radius > grid->meshBounds[1][0]
00231             || dl->origin[0] + dl->radius < grid->meshBounds[0][0]
00232             || dl->origin[1] - dl->radius > grid->meshBounds[1][1]
00233             || dl->origin[1] + dl->radius < grid->meshBounds[0][1]
00234             || dl->origin[2] - dl->radius > grid->meshBounds[1][2]
00235             || dl->origin[2] + dl->radius < grid->meshBounds[0][2] ) {
00236             // dlight doesn't reach the bounds
00237             dlightBits &= ~( 1 << i );
00238         }
00239     }
00240 
00241     if ( !dlightBits ) {
00242         tr.pc.c_dlightSurfacesCulled++;
00243     }
00244 
00245     grid->dlightBits[ tr.smpFrame ] = dlightBits;
00246     return dlightBits;
00247 #endif
00248 }

qboolean R_inPVS const vec3_t  p1,
const vec3_t  p2
 

Definition at line 545 of file tr_world.c.

References byte, mnode_s::cluster, CM_ClusterPVS(), mnode_t, p2, qboolean, and R_PointInLeaf().

00545                                                      {
00546     mnode_t *leaf;
00547     byte    *vis;
00548 
00549     leaf = R_PointInLeaf( p1 );
00550     vis = CM_ClusterPVS( leaf->cluster );
00551     leaf = R_PointInLeaf( p2 );
00552 
00553     if ( !(vis[leaf->cluster>>3] & (1<<(leaf->cluster&7))) ) {
00554         return qfalse;
00555     }
00556     return qtrue;
00557 }

Here is the call graph for this function:

void R_MarkLeaves void   )  [static]
 

Definition at line 567 of file tr_world.c.

References mnode_s::area, trRefdef_t::areamask, trRefdef_t::areamaskModified, byte, mnode_s::cluster, mnode_s::contents, i, cvar_s::integer, mnode_t, cvar_s::modified, world_t::nodes, world_t::numClusters, world_t::numnodes, mnode_s::parent, PRINT_ALL, viewParms_t::pvsOrigin, R_ClusterPVS(), r_lockpvs, r_novis, R_PointInLeaf(), r_showcluster, trGlobals_t::refdef, ri, tr, trGlobals_t::viewCluster, trGlobals_t::viewParms, trGlobals_t::visCount, mnode_s::visframe, and trGlobals_t::world.

Referenced by R_AddWorldSurfaces().

00567                                 {
00568     const byte  *vis;
00569     mnode_t *leaf, *parent;
00570     int     i;
00571     int     cluster;
00572 
00573     // lockpvs lets designers walk around to determine the
00574     // extent of the current pvs
00575     if ( r_lockpvs->integer ) {
00576         return;
00577     }
00578 
00579     // current viewcluster
00580     leaf = R_PointInLeaf( tr.viewParms.pvsOrigin );
00581     cluster = leaf->cluster;
00582 
00583     // if the cluster is the same and the area visibility matrix
00584     // hasn't changed, we don't need to mark everything again
00585 
00586     // if r_showcluster was just turned on, remark everything 
00587     if ( tr.viewCluster == cluster && !tr.refdef.areamaskModified 
00588         && !r_showcluster->modified ) {
00589         return;
00590     }
00591 
00592     if ( r_showcluster->modified || r_showcluster->integer ) {
00593         r_showcluster->modified = qfalse;
00594         if ( r_showcluster->integer ) {
00595             ri.Printf( PRINT_ALL, "cluster:%i  area:%i\n", cluster, leaf->area );
00596         }
00597     }
00598 
00599     tr.visCount++;
00600     tr.viewCluster = cluster;
00601 
00602     if ( r_novis->integer || tr.viewCluster == -1 ) {
00603         for (i=0 ; i<tr.world->numnodes ; i++) {
00604             if (tr.world->nodes[i].contents != CONTENTS_SOLID) {
00605                 tr.world->nodes[i].visframe = tr.visCount;
00606             }
00607         }
00608         return;
00609     }
00610 
00611     vis = R_ClusterPVS (tr.viewCluster);
00612     
00613     for (i=0,leaf=tr.world->nodes ; i<tr.world->numnodes ; i++, leaf++) {
00614         cluster = leaf->cluster;
00615         if ( cluster < 0 || cluster >= tr.world->numClusters ) {
00616             continue;
00617         }
00618 
00619         // check general pvs
00620         if ( !(vis[cluster>>3] & (1<<(cluster&7))) ) {
00621             continue;
00622         }
00623 
00624         // check for door connection
00625         if ( (tr.refdef.areamask[leaf->area>>3] & (1<<(leaf->area&7)) ) ) {
00626             continue;       // not visible
00627         }
00628 
00629         parent = leaf;
00630         do {
00631             if (parent->visframe == tr.visCount)
00632                 break;
00633             parent->visframe = tr.visCount;
00634             parent = parent->parent;
00635         } while (parent);
00636     }
00637 }

Here is the call graph for this function:

mnode_t* R_PointInLeaf const vec3_t  p  )  [static]
 

Definition at line 501 of file tr_world.c.

References mnode_s::children, mnode_s::contents, cplane_t, d, cplane_s::dist, DotProduct, ERR_DROP, mnode_t, world_t::nodes, cplane_s::normal, p, mnode_s::plane, ri, tr, and trGlobals_t::world.

Referenced by R_inPVS(), and R_MarkLeaves().

00501                                                 {
00502     mnode_t     *node;
00503     float       d;
00504     cplane_t    *plane;
00505     
00506     if ( !tr.world ) {
00507         ri.Error (ERR_DROP, "R_PointInLeaf: bad model");
00508     }
00509 
00510     node = tr.world->nodes;
00511     while( 1 ) {
00512         if (node->contents != -1) {
00513             break;
00514         }
00515         plane = node->plane;
00516         d = DotProduct (p,plane->normal) - plane->dist;
00517         if (d > 0) {
00518             node = node->children[0];
00519         } else {
00520             node = node->children[1];
00521         }
00522     }
00523     
00524     return node;
00525 }

void R_RecursiveWorldNode mnode_t node,
int  planeBits,
int  dlightBits
[static]
 

Definition at line 356 of file tr_world.c.

References BoxOnPlaneSide(), c, frontEndCounters_t::c_leafs, mnode_s::children, mnode_s::contents, cplane_s::dist, dlight_t, trRefdef_t::dlights, DotProduct, mnode_s::firstmarksurface, viewParms_t::frustum, i, cvar_s::integer, mnode_s::maxs, mnode_s::mins, mnode_t, msurface_t, cplane_s::normal, trRefdef_t::num_dlights, mnode_s::nummarksurfaces, dlight_s::origin, trGlobals_t::pc, mnode_s::plane, r, R_AddWorldSurface(), r_nocull, dlight_s::radius, trGlobals_t::refdef, tr, trGlobals_t::viewParms, viewParms_t::visBounds, trGlobals_t::visCount, and mnode_s::visframe.

Referenced by R_AddWorldSurfaces().

00356                                                                                  {
00357 
00358     do {
00359         int         newDlights[2];
00360 
00361         // if the node wasn't marked as potentially visible, exit
00362         if (node->visframe != tr.visCount) {
00363             return;
00364         }
00365 
00366         // if the bounding volume is outside the frustum, nothing
00367         // inside can be visible OPTIMIZE: don't do this all the way to leafs?
00368 
00369         if ( !r_nocull->integer ) {
00370             int     r;
00371 
00372             if ( planeBits & 1 ) {
00373                 r = BoxOnPlaneSide(node->mins, node->maxs, &tr.viewParms.frustum[0]);
00374                 if (r == 2) {
00375                     return;                     // culled
00376                 }
00377                 if ( r == 1 ) {
00378                     planeBits &= ~1;            // all descendants will also be in front
00379                 }
00380             }
00381 
00382             if ( planeBits & 2 ) {
00383                 r = BoxOnPlaneSide(node->mins, node->maxs, &tr.viewParms.frustum[1]);
00384                 if (r == 2) {
00385                     return;                     // culled
00386                 }
00387                 if ( r == 1 ) {
00388                     planeBits &= ~2;            // all descendants will also be in front
00389                 }
00390             }
00391 
00392             if ( planeBits & 4 ) {
00393                 r = BoxOnPlaneSide(node->mins, node->maxs, &tr.viewParms.frustum[2]);
00394                 if (r == 2) {
00395                     return;                     // culled
00396                 }
00397                 if ( r == 1 ) {
00398                     planeBits &= ~4;            // all descendants will also be in front
00399                 }
00400             }
00401 
00402             if ( planeBits & 8 ) {
00403                 r = BoxOnPlaneSide(node->mins, node->maxs, &tr.viewParms.frustum[3]);
00404                 if (r == 2) {
00405                     return;                     // culled
00406                 }
00407                 if ( r == 1 ) {
00408                     planeBits &= ~8;            // all descendants will also be in front
00409                 }
00410             }
00411 
00412         }
00413 
00414         if ( node->contents != -1 ) {
00415             break;
00416         }
00417 
00418         // node is just a decision point, so go down both sides
00419         // since we don't care about sort orders, just go positive to negative
00420 
00421         // determine which dlights are needed
00422         newDlights[0] = 0;
00423         newDlights[1] = 0;
00424         if ( dlightBits ) {
00425             int i;
00426 
00427             for ( i = 0 ; i < tr.refdef.num_dlights ; i++ ) {
00428                 dlight_t    *dl;
00429                 float       dist;
00430 
00431                 if ( dlightBits & ( 1 << i ) ) {
00432                     dl = &tr.refdef.dlights[i];
00433                     dist = DotProduct( dl->origin, node->plane->normal ) - node->plane->dist;
00434                     
00435                     if ( dist > -dl->radius ) {
00436                         newDlights[0] |= ( 1 << i );
00437                     }
00438                     if ( dist < dl->radius ) {
00439                         newDlights[1] |= ( 1 << i );
00440                     }
00441                 }
00442             }
00443         }
00444 
00445         // recurse down the children, front side first
00446         R_RecursiveWorldNode (node->children[0], planeBits, newDlights[0] );
00447 
00448         // tail recurse
00449         node = node->children[1];
00450         dlightBits = newDlights[1];
00451     } while ( 1 );
00452 
00453     {
00454         // leaf node, so add mark surfaces
00455         int         c;
00456         msurface_t  *surf, **mark;
00457 
00458         tr.pc.c_leafs++;
00459 
00460         // add to z buffer bounds
00461         if ( node->mins[0] < tr.viewParms.visBounds[0][0] ) {
00462             tr.viewParms.visBounds[0][0] = node->mins[0];
00463         }
00464         if ( node->mins[1] < tr.viewParms.visBounds[0][1] ) {
00465             tr.viewParms.visBounds[0][1] = node->mins[1];
00466         }
00467         if ( node->mins[2] < tr.viewParms.visBounds[0][2] ) {
00468             tr.viewParms.visBounds[0][2] = node->mins[2];
00469         }
00470 
00471         if ( node->maxs[0] > tr.viewParms.visBounds[1][0] ) {
00472             tr.viewParms.visBounds[1][0] = node->maxs[0];
00473         }
00474         if ( node->maxs[1] > tr.viewParms.visBounds[1][1] ) {
00475             tr.viewParms.visBounds[1][1] = node->maxs[1];
00476         }
00477         if ( node->maxs[2] > tr.viewParms.visBounds[1][2] ) {
00478             tr.viewParms.visBounds[1][2] = node->maxs[2];
00479         }
00480 
00481         // add the individual surfaces
00482         mark = node->firstmarksurface;
00483         c = node->nummarksurfaces;
00484         while (c--) {
00485             // the surface may have already been added if it
00486             // spans multiple leafs
00487             surf = *mark;
00488             R_AddWorldSurface( surf, dlightBits );
00489             mark++;
00490         }
00491     }
00492 
00493 }

Here is the call graph for this function:


Generated on Thu Aug 25 15:25:33 2005 for Quake III Arena by  doxygen 1.3.9.1