/* * R_CullAliasModel */ qboolean R_CullAliasModel( entity_t *e ) { int i, j, clipped; qboolean frustum, query; unsigned int modhandle; model_t *mod; shader_t *shader; maliasmodel_t *aliasmodel; maliasmesh_t *mesh; mod = R_AliasModelLOD( e ); if( !( aliasmodel = ( ( maliasmodel_t * )mod->extradata ) ) || !aliasmodel->nummeshes ) return qtrue; R_AliasModelLerpBBox( e, mod ); modhandle = Mod_Handle( mod ); clipped = R_CullModel( e, alias_mins, alias_maxs, alias_radius ); frustum = clipped & 1; if( clipped & 2 ) return qtrue; query = OCCLUSION_QUERIES_ENABLED( ri ) && OCCLUSION_TEST_ENTITY( e ) ? qtrue : qfalse; if( !frustum && query ) R_IssueOcclusionQuery( R_GetOcclusionQueryNum( OQ_ENTITY, e - r_entities ), e, alias_mins, alias_maxs ); if( ( ri.refdef.rdflags & RDF_NOWORLDMODEL ) || ( r_shadows->integer != SHADOW_PLANAR && !( r_shadows->integer == SHADOW_MAPPING && ( e->flags & RF_PLANARSHADOW ) ) ) || R_CullPlanarShadow( e, alias_mins, alias_maxs, query ) ) return frustum; // entity is not in PVS or shadow is culled away by frustum culling for( i = 0, mesh = aliasmodel->meshes; i < aliasmodel->nummeshes; i++, mesh++ ) { shader = NULL; if( e->customSkin ) shader = R_FindShaderForSkinFile( e->customSkin, mesh->name ); else if( e->customShader ) shader = e->customShader; else if( mesh->numskins ) { for( j = 0; j < mesh->numskins; j++ ) { shader = mesh->skins[j].shader; if( shader && shader->sort <= SHADER_SORT_ALPHATEST ) break; shader = NULL; } } if( shader && ( shader->sort <= SHADER_SORT_ALPHATEST ) ) { R_AddModelMeshToList( modhandle, mesh->vbo, NULL, R_PlanarShadowShader(), i, 0, mesh->numverts, mesh->numtris * 3 ); } } return frustum; }
/* * R_AliasModelBBox */ float R_AliasModelBBox( const entity_t *e, vec3_t mins, vec3_t maxs ) { const model_t *mod; mod = R_AliasModelLOD( e ); if( !mod ) return 0; return R_AliasModelLerpBBox( e, mod, mins, maxs ); }
/* * R_AliasModelBBox */ float R_AliasModelBBox( entity_t *e, vec3_t mins, vec3_t maxs ) { model_t *mod; mod = R_AliasModelLOD( e ); if( !mod ) return 0; R_AliasModelLerpBBox( e, mod ); VectorCopy( alias_mins, mins ); VectorCopy( alias_maxs, maxs ); return alias_radius; }
/* * R_AddAliasModelToDrawList * * Returns true if the entity is added to draw list */ qboolean R_AddAliasModelToDrawList( const entity_t *e ) { int i, j; const model_t *mod; const maliasmodel_t *aliasmodel; const mfog_t *fog; const shader_t *shader; const maliasmesh_t *mesh; vec3_t mins, maxs; float radius; float distance; int clipped; mod = R_AliasModelLOD( e ); if( !( aliasmodel = ( ( const maliasmodel_t * )mod->extradata ) ) || !aliasmodel->nummeshes ) return qfalse; radius = R_AliasModelLerpBBox( 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.params & RP_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_AliasModelLerpBBox( e, mod ); if( R_CompletelyFogged( fog, e->origin, radius ) ) return qfalse; } #endif for( i = 0, mesh = aliasmodel->meshes; i < aliasmodel->nummeshes; i++, mesh++ ) { shader = NULL; if( e->customSkin ) { shader = R_FindShaderForSkinFile( e->customSkin, mesh->name ); } else if( e->customShader ) { shader = e->customShader; } else if( mesh->numskins ) { for( j = 0; j < mesh->numskins; j++ ) { shader = mesh->skins[j].shader; if( shader ) { R_AddDSurfToDrawList( e, fog, shader, distance, 0, NULL, aliasmodel->drawSurfs + i ); } } continue; } if( shader ) { R_AddDSurfToDrawList( e, fog, shader, distance, 0, NULL, aliasmodel->drawSurfs + i ); } } return qtrue; }
/* * R_AddAliasModelToList */ void R_AddAliasModelToList( entity_t *e ) { int i, j; unsigned int modhandle, entnum = e - r_entities; mfog_t *fog = NULL; model_t *mod; shader_t *shader; maliasmodel_t *aliasmodel; maliasmesh_t *mesh; float distance; mod = R_AliasModelLOD( e ); aliasmodel = ( maliasmodel_t * )mod->extradata; modhandle = Mod_Handle( mod ); // make sure weapon model is always closest to the viewer if( e->renderfx & RF_WEAPONMODEL ) { distance = 0; } else { distance = Distance( e->origin, ri.viewOrigin ) + 1; } if( ri.params & RP_SHADOWMAPVIEW ) { if( r_entShadowBits[entnum] & ri.shadowGroup->bit ) { if( !r_shadows_self_shadow->integer ) r_entShadowBits[entnum] &= ~ri.shadowGroup->bit; if( e->flags & RF_WEAPONMODEL ) return; } else { R_AliasModelLerpBBox( e, mod ); if( !R_CullModel( e, alias_mins, alias_maxs, alias_radius ) ) r_entShadowBits[entnum] |= ri.shadowGroup->bit; return; // mark as shadowed, proceed with caster otherwise } } else { fog = R_FogForSphere( e->origin, alias_radius ); #if 0 if( !( e->flags & RF_WEAPONMODEL ) && fog ) { R_AliasModelLerpBBox( e, mod ); if( R_CompletelyFogged( fog, e->origin, alias_radius ) ) return; } #endif } for( i = 0, mesh = aliasmodel->meshes; i < aliasmodel->nummeshes; i++, mesh++ ) { shader = NULL; if( e->customSkin ) shader = R_FindShaderForSkinFile( e->customSkin, mesh->name ); else if( e->customShader ) shader = e->customShader; else if( mesh->numskins ) { for( j = 0; j < mesh->numskins; j++ ) { shader = mesh->skins[j].shader; if( shader ) R_AddModelMeshToList( modhandle, mesh->vbo, fog, shader, i, distance, mesh->numverts, mesh->numtris * 3 ); } continue; } if( shader ) R_AddModelMeshToList( modhandle, mesh->vbo, fog, shader, i, distance, mesh->numverts, mesh->numtris * 3 ); } }