/* * GClip_FindBoxInRadius * Returns entities that have their boxes within a spherical area */ edict_t *GClip_FindBoxInRadius4D( edict_t *from, vec3_t org, float rad, int timeDelta ) { int i, j; c4clipedict_t *check; vec3_t mins, maxs; int fromNum; if( !from ) from = world; fromNum = ENTNUM( from ) + 1; for( i = fromNum; i < game.numentities; i++ ) { if( !game.edicts[i].r.inuse ) continue; check = GClip_GetClipEdictForDeltaTime( i, timeDelta ); if( !check->r.inuse ) continue; if( check->r.solid == SOLID_NOT ) continue; // make absolute mins and maxs for( j = 0; j < 3; j++ ) { mins[j] = check->s.origin[j] + check->r.mins[j]; maxs[j] = check->s.origin[j] + check->r.maxs[j]; } if( !BoundsAndSphereIntersect( mins, maxs, org, rad ) ) continue; return &game.edicts[i]; // return realtime entity } return NULL; }
/* * GClip_FindBoxInRadius * Returns entities that have their boxes within a spherical area */ int GClip_FindBoxInRadius4D( vec3_t org, float rad, int *list, int maxcount, int timeDelta ) { int i, num; int listnum; edict_t *check; vec3_t mins, maxs; float rad_ = rad * 1.42; int touch[MAX_EDICTS]; VectorSet( mins, org[0] - (rad_ + 1), org[1] - (rad_ + 1), org[2] - (rad_ + 1) ); VectorSet( maxs, org[0] + (rad_ + 1), org[1] + (rad_ + 1), org[2] + (rad_ + 1) ); listnum = 0; num = GClip_AreaEdicts( mins, maxs, touch, MAX_EDICTS, AREA_ALL, timeDelta ); for( i = 0; i < num; i++ ) { check = EDICT_NUM( touch[i] ); // make absolute mins and maxs if( !BoundsAndSphereIntersect( check->r.absmin, check->r.absmax, org, rad ) ) continue; if( check->s.solid == SOLID_NOT ) continue; if( listnum < maxcount ) { list[listnum] = touch[i]; } listnum++; } return listnum; }
/* * R_SurfaceDlightBits */ static unsigned int R_SurfaceDlightBits( const msurface_t *surf, unsigned int checkDlightBits ) { unsigned int i, bit; dlight_t *lt; float dist; unsigned int surfDlightBits = 0; if( !R_SurfPotentiallyLit( surf ) ) { return 0; } for( i = 0, bit = 1, lt = rsc.dlights; i < rsc.numDlights; i++, bit <<= 1, lt++ ) { if( !checkDlightBits ) { break; } if( checkDlightBits & bit ) { switch( surf->facetype ) { case FACETYPE_PLANAR: dist = PlaneDiff( lt->origin, surf->plane ); if( dist > -lt->intensity && dist < lt->intensity ) { surfDlightBits |= bit; } break; case FACETYPE_PATCH: case FACETYPE_TRISURF: case FACETYPE_FOLIAGE: if( BoundsAndSphereIntersect( surf->mins, surf->maxs, lt->origin, lt->intensity ) ) { surfDlightBits |= bit; } break; } checkDlightBits &= ~bit; } } return surfDlightBits; }
/* * R_AddBrushModelToDrawList */ qboolean R_AddBrushModelToDrawList( const entity_t *e ) { unsigned int i; vec3_t origin; vec3_t bmins, bmaxs; qboolean rotated; model_t *model = e->model; mbrushmodel_t *bmodel = ( mbrushmodel_t * )model->extradata; msurface_t *surf; mfog_t *fog; float radius, distance; unsigned int bit, fullBits; unsigned int dlightBits, shadowBits; if( bmodel->nummodelsurfaces == 0 ) { return qfalse; } radius = R_BrushModelBBox( e, bmins, bmaxs, &rotated ); if( R_CullModelEntity( e, bmins, bmaxs, radius, rotated ) ) { return qfalse; } // never render weapon models or non-occluders into shadowmaps if( rn.renderFlags & RF_SHADOWMAPVIEW ) { if( rsc.entShadowGroups[R_ENT2NUM(e)] != rn.shadowGroup->id ) { return qtrue; } } VectorAdd( e->model->mins, e->model->maxs, origin ); VectorMA( e->origin, 0.5, origin, origin ); distance = Distance( origin, rn.refdef.vieworg ); fog = R_FogForBounds( bmins, bmaxs ); R_TransformPointToModelSpace( e, rotated, rn.refdef.vieworg, modelOrg ); // check dynamic lights that matter in the instance against the model dlightBits = 0; for( i = 0, fullBits = rn.dlightBits, bit = 1; fullBits; i++, fullBits &= ~bit, bit <<= 1 ) { if( !( fullBits & bit ) ) { continue; } if( !BoundsAndSphereIntersect( bmins, bmaxs, rsc.dlights[i].origin, rsc.dlights[i].intensity ) ) { continue; } dlightBits |= bit; } // check shadowmaps that matter in the instance against the model shadowBits = 0; for( i = 0, fullBits = rn.shadowBits; fullBits; i++, fullBits &= ~bit ) { shadowGroup_t *grp = rsc.shadowGroups + i; bit = grp->bit; if( !( fullBits & bit ) ) { continue; } if( !BoundsIntersect( bmins, bmaxs, grp->visMins, grp->visMaxs ) ) { continue; } shadowBits |= bit; } for( i = 0, surf = bmodel->firstmodelsurface; i < bmodel->nummodelsurfaces; i++, surf++ ) { if( !surf->drawSurf ) { continue; } if( surf->visFrame != rf.frameCount ) { surf->visFrame = rf.frameCount; R_AddSurfaceToDrawList( e, surf, fog, 0, dlightBits, shadowBits, distance ); } } return qtrue; }
/* * R_RecursiveFragmentNode */ static void R_RecursiveFragmentNode( void ) { int stackdepth = 0; float dist; qboolean inside; mnode_t *node, *localstack[2048]; mleaf_t *leaf; msurface_t *surf, **mark; for( node = rsh.worldBrushModel->nodes, stackdepth = 0;; ) { if( node->plane == NULL ) { leaf = ( mleaf_t * )node; mark = leaf->firstFragmentSurface; if( !mark ) goto nextNodeOnStack; do { if( numFragmentVerts == maxFragmentVerts || numClippedFragments == maxClippedFragments ) return; // already reached the limit surf = *mark++; if( surf->fragmentframe == r_fragmentframecount ) continue; surf->fragmentframe = r_fragmentframecount; if( !BoundsAndSphereIntersect( surf->mins, surf->maxs, fragmentOrigin, fragmentRadius ) ) continue; if( surf->facetype == FACETYPE_PATCH ) inside = R_PatchSurfClipFragment( surf, fragmentNormal ); else inside = R_PlanarSurfClipFragment( surf, fragmentNormal ); // if there some fragments that are inside a surface, that doesn't mean that // there are no fragments that are OUTSIDE, so the check below is disabled //if( inside ) // return; (void)inside; // hush compiler warning } while( *mark ); if( numFragmentVerts == maxFragmentVerts || numClippedFragments == maxClippedFragments ) return; // already reached the limit nextNodeOnStack: if( !stackdepth ) break; node = localstack[--stackdepth]; continue; } dist = PlaneDiff( fragmentOrigin, node->plane ); if( dist > fragmentRadius ) { node = node->children[0]; continue; } if( ( dist >= -fragmentRadius ) && ( stackdepth < sizeof( localstack )/sizeof( mnode_t * ) ) ) localstack[stackdepth++] = node->children[0]; node = node->children[1]; } }
/* ================= R_RecursiveFragmentNode ================= */ static void R_RecursiveFragmentNode( void ) { int stackdepth = 0; float dist; bool inside; mnode_t *node, *localstack[2048]; mleaf_t *leaf; msurface_t *surf, **mark; for( node = r_worldbrushmodel->nodes, stackdepth = 0;; ) { if( node->plane == NULL ) { leaf = ( mleaf_t * )node; mark = leaf->firstFragmentSurface; if( !mark ) goto nextNodeOnStack; do { if( numFragmentVerts == maxFragmentVerts || numClippedFragments == maxClippedFragments ) return; // already reached the limit surf = *mark++; if( surf->fragmentframe == r_fragmentframecount ) continue; surf->fragmentframe = r_fragmentframecount; if( !BoundsAndSphereIntersect( surf->mins, surf->maxs, fragmentOrigin, fragmentRadius ) ) continue; if( surf->facetype == MST_PATCH ) inside = R_PatchSurfClipFragment( surf, fragmentNormal ); else inside = R_PlanarSurfClipFragment( surf, fragmentNormal ); if( inside ) return; } while( *mark ); if( numFragmentVerts == maxFragmentVerts || numClippedFragments == maxClippedFragments ) return; // already reached the limit nextNodeOnStack: if( !stackdepth ) break; node = localstack[--stackdepth]; continue; } dist = PlaneDiff( fragmentOrigin, node->plane ); if( dist > fragmentRadius ) { node = node->children[0]; continue; } if( ( dist >= -fragmentRadius ) && ( stackdepth < sizeof( localstack ) / sizeof( mnode_t * ))) localstack[stackdepth++] = node->children[0]; node = node->children[1]; } }