/* * 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_AddSkeletalModelToDrawList */ qboolean R_AddSkeletalModelToDrawList( const entity_t *e ) { int i; const mfog_t *fog; const model_t *mod; const shader_t *shader; const mskmesh_t *mesh; const mskmodel_t *skmodel; vec3_t mins, maxs; float radius; float distance; int clipped; mod = R_SkeletalModelLOD( e ); if( !( skmodel = ( ( mskmodel_t * )mod->extradata ) ) || !skmodel->nummeshes ) return qfalse; radius = R_SkeletalModelLerpBBox( e, mod, mins, maxs ); clipped = R_CullModelEntity( e, mins, maxs, radius, qtrue ); if( clipped ) return qfalse; // never render weapon models or non-occluders into shadowmaps if( rn.renderFlags & RF_SHADOWMAPVIEW ) { if( e->renderfx & RF_WEAPONMODEL ) { return qtrue; } if( rsc.entShadowGroups[R_ENT2NUM(e)] != rn.shadowGroup->id ) { return qtrue; } } // make sure weapon model is always closest to the viewer if( e->renderfx & RF_WEAPONMODEL ) { distance = 0; } else { distance = Distance( e->origin, rn.viewOrigin ) + 1; } fog = R_FogForSphere( e->origin, radius ); #if 0 if( !( e->flags & RF_WEAPONMODEL ) && fog ) { R_SkeletalModelLerpBBox( e, mod ); if( R_CompletelyFogged( fog, e->origin, skm_radius ) ) return qfalse; } #endif for( i = 0, mesh = skmodel->meshes; i < (int)skmodel->nummeshes; i++, mesh++ ) { shader = NULL; if( e->customSkin ) { shader = R_FindShaderForSkinFile( e->customSkin, mesh->name ); } else if( e->customShader ) { shader = e->customShader; } else { shader = mesh->skin.shader; } if( shader ) { R_AddDSurfToDrawList( e, fog, shader, distance, 0, NULL, skmodel->drawSurfs + i ); } } return qtrue; }