コード例 #1
0
/*
=============
R_CullIQM
=============
*/
static void R_CullIQM( trRefEntity_t *ent ) {
	vec3_t     localBounds[ 2 ];
	float      scale = ent->e.skeleton.scale;
	IQModel_t *model = tr.currentModel->iqm;
	IQAnim_t  *anim = model->anims;
	float     *bounds;

	// use the bounding box by the model
	bounds = model->bounds[0];
	VectorCopy( bounds, localBounds[ 0 ] );
	VectorCopy( bounds + 3, localBounds[ 1 ] );

	if ( anim && ( bounds = anim->bounds ) ) {
		// merge bounding box provided by the animation
		BoundsAdd( localBounds[ 0 ], localBounds[ 1 ],
			   bounds, bounds + 3 );
	}

	// merge bounding box provided by skeleton
	BoundsAdd( localBounds[ 0 ], localBounds[ 1 ],
		   ent->e.skeleton.bounds[ 0 ], ent->e.skeleton.bounds[ 1 ] );

	VectorScale( localBounds[0], scale, ent->localBounds[ 0 ] );
	VectorScale( localBounds[1], scale, ent->localBounds[ 1 ] );

	
	R_SetupEntityWorldBounds(ent);

	switch ( R_CullBox( ent->worldBounds ) )
	{
	case cullResult_t::CULL_IN:
		tr.pc.c_box_cull_md5_in++;
		ent->cull = cullResult_t::CULL_IN;
		return;
	case cullResult_t::CULL_CLIP:
		tr.pc.c_box_cull_md5_clip++;
		ent->cull = cullResult_t::CULL_CLIP;
		return;
	case cullResult_t::CULL_OUT:
	default:
		tr.pc.c_box_cull_md5_out++;
		ent->cull = cullResult_t::CULL_OUT;
		return;
	}
}
コード例 #2
0
/*
==============
R_AddMD5Surfaces
==============
*/
void R_AddMD5Surfaces(trRefEntity_t * ent)
{
	md5Model_t     *model;
	md5Surface_t   *surface;
	shader_t       *shader;
	int             i;
	qboolean        personalModel;
	int				fogNum;

	model = tr.currentModel->md5;

	// don't add third_person objects if not in a portal
	personalModel = (ent->e.renderfx & RF_THIRD_PERSON) && !tr.viewParms.isPortal;

	// cull the entire model if merged bounding box of both frames
	// is outside the view frustum
	R_CullMD5(ent);
	if(ent->cull == CULL_OUT)
	{
		return;
	}

	// set up world bounds for light intersection tests
	R_SetupEntityWorldBounds(ent);

	// set up lighting now that we know we aren't culled
	if(!personalModel || r_shadows->integer > SHADOWING_BLOB)
	{
		R_SetupEntityLighting(&tr.refdef, ent, NULL);
	}

	// see if we are in a fog volume
	fogNum = R_FogWorldBox(ent->worldBounds);

	if(!r_vboModels->integer || !model->numVBOSurfaces ||
	   (!glConfig2.vboVertexSkinningAvailable && ent->e.skeleton.type == SK_ABSOLUTE))
	{
		// finally add surfaces
		for(i = 0, surface = model->surfaces; i < model->numSurfaces; i++, surface++)
		{
			if(ent->e.customShader)
			{
				shader = R_GetShaderByHandle(ent->e.customShader);
			}
			else if(ent->e.customSkin > 0 && ent->e.customSkin < tr.numSkins)
			{
				skin_t         *skin;

				skin = R_GetSkinByHandle(ent->e.customSkin);

				// match the surface name to something in the skin file
				shader = tr.defaultShader;

				// FIXME: replace MD3_MAX_SURFACES for skin_t::surfaces
				if(i >= 0 && i < skin->numSurfaces && skin->surfaces[i])
				{
					shader = skin->surfaces[i]->shader;
				}
				if(shader == tr.defaultShader)
				{
					ri.Printf(PRINT_DEVELOPER, "WARNING: no shader for surface %i in skin %s\n", i, skin->name);
				}
				else if(shader->defaultShader)
				{
					ri.Printf(PRINT_DEVELOPER, "WARNING: shader %s in skin %s not found\n", shader->name, skin->name);
				}
			}
			else
			{
				shader = R_GetShaderByHandle(surface->shaderIndex);
			}

			// we will add shadows even if the main object isn't visible in the view

			// don't add third_person objects if not viewing through a portal
			if(!personalModel)
			{
				R_AddDrawSurf((void *)surface, shader, -1, fogNum);
			}
		}
	}
	else
	{
		int             i;
		srfVBOMD5Mesh_t *vboSurface;
		shader_t       *shader;

		for(i = 0; i < model->numVBOSurfaces; i++)
		{
			vboSurface = model->vboSurfaces[i];

			if(ent->e.customShader)
			{
				shader = R_GetShaderByHandle(ent->e.customShader);
			}
			else if(ent->e.customSkin > 0 && ent->e.customSkin < tr.numSkins)
			{
				skin_t         *skin;

				skin = R_GetSkinByHandle(ent->e.customSkin);

				// match the surface name to something in the skin file
				shader = tr.defaultShader;

				// FIXME: replace MD3_MAX_SURFACES for skin_t::surfaces
				//if(i >= 0 && i < skin->numSurfaces && skin->surfaces[i])
				if(vboSurface->skinIndex >= 0 && vboSurface->skinIndex < skin->numSurfaces && skin->surfaces[vboSurface->skinIndex])
				{
					shader = skin->surfaces[vboSurface->skinIndex]->shader;
				}

				if(shader == tr.defaultShader)
				{
					ri.Printf(PRINT_DEVELOPER, "WARNING: no shader for surface %i in skin %s\n", i, skin->name);
				}
				else if(shader->defaultShader)
				{
					ri.Printf(PRINT_DEVELOPER, "WARNING: shader %s in skin %s not found\n", shader->name, skin->name);
				}
			}
			else
			{
				shader = vboSurface->shader;
			}

			// don't add third_person objects if not viewing through a portal
			if(!personalModel)
			{
				R_AddDrawSurf((void *)vboSurface, shader, -1, fogNum);
			}
		}
	}
}
コード例 #3
0
ファイル: tr_mesh.c プロジェクト: etlegacy/etlegacy
/**
 * @brief R_CullMDV
 * @param[in] model
 * @param[in,out] ent
 */
static void R_CullMDV(mdvModel_t *model, trRefEntity_t *ent)
{
	int    i;
	// compute frame pointers
	mdvFrame_t *newFrame = model->frames + ent->e.frame;
	mdvFrame_t *oldFrame = model->frames + ent->e.oldframe;

	// calculate a bounding box in the current coordinate system
	for (i = 0; i < 3; i++)
	{
		ent->localBounds[0][i] =
		    oldFrame->bounds[0][i] < newFrame->bounds[0][i] ? oldFrame->bounds[0][i] : newFrame->bounds[0][i];
		ent->localBounds[1][i] =
		    oldFrame->bounds[1][i] > newFrame->bounds[1][i] ? oldFrame->bounds[1][i] : newFrame->bounds[1][i];
	}

	// setup world bounds for intersection tests
	R_SetupEntityWorldBounds(ent);

	// cull bounding sphere ONLY if this is not an upscaled entity
	if (!ent->e.nonNormalizedAxes)
	{
		if (ent->e.frame == ent->e.oldframe)
		{
			switch (R_CullLocalPointAndRadius(newFrame->localOrigin, newFrame->radius))
			{
			case CULL_OUT:
				tr.pc.c_sphere_cull_mdx_out++;
				ent->cull = CULL_OUT;
				return;
			case CULL_IN:
				tr.pc.c_sphere_cull_mdx_in++;
				ent->cull = CULL_IN;
				return;
			case CULL_CLIP:
				tr.pc.c_sphere_cull_mdx_clip++;
				break;
			}
		}
		else
		{
			int sphereCull, sphereCullB;

			sphereCull = R_CullLocalPointAndRadius(newFrame->localOrigin, newFrame->radius);
			if (newFrame == oldFrame)
			{
				sphereCullB = sphereCull;
			}
			else
			{
				sphereCullB = R_CullLocalPointAndRadius(oldFrame->localOrigin, oldFrame->radius);
			}

			if (sphereCull == sphereCullB)
			{
				if (sphereCull == CULL_OUT)
				{
					tr.pc.c_sphere_cull_mdx_out++;
					ent->cull = CULL_OUT;
					return;
				}
				else if (sphereCull == CULL_IN)
				{
					tr.pc.c_sphere_cull_mdx_in++;
					ent->cull = CULL_IN;
					return;
				}
				else
				{
					tr.pc.c_sphere_cull_mdx_clip++;
				}
			}
		}
	}

	switch (R_CullBox(ent->worldBounds))
	{
	case CULL_IN:
		tr.pc.c_box_cull_mdx_in++;
		ent->cull = CULL_IN;
		return;
	case CULL_CLIP:
		tr.pc.c_box_cull_mdx_clip++;
		ent->cull = CULL_CLIP;
		return;
	case CULL_OUT:
	default:
		tr.pc.c_box_cull_mdx_out++;
		ent->cull = CULL_OUT;
		return;
	}
}