예제 #1
0
/*
* 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;
}
예제 #2
0
파일: r_skm.c 프로젝트: codetwister/qfusion
/*
* 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;
}