Exemple #1
0
void CG_DoGlass( vec3_t verts[4], vec3_t normal, vec3_t dmgPt, vec3_t dmgDir, float dmgRadius )
{
	int		i, t;
	int		mxHeight, mxWidth;
	float	height, width;
	float	stepWidth, stepHeight;
	float	timeDecay;
	float	x, z;
	float	xx, zz;
	int		time = 0;
	bool	stick = true;
	vec3_t	subVerts[4];
	vec2_t	biPoints[4];

	// To do a smarter tesselation, we should figure out the relative height and width of the brush face,
	//	then use this to pick a lod value from 1-3 in each axis.  This will give us 1-9 lod levels, which will
	//	hopefully be sufficient.
	CG_CalcHeightWidth( verts, &height, &width );

	cgi_S_StartSound( dmgPt, -1, CHAN_AUTO, cgi_S_RegisterSound("sound/effects/glassbreak1.wav"));

	// Pick "LOD" for height
	if ( height < 100 )
	{
		stepHeight = 0.2f;
		mxHeight = 5;
		timeDecay = TIME_DECAY_SLOW;
	}
/*	else if ( height > 220 ) // was originally mxHeight = 20....but removing this whole section because it causes huge number of chunks...which is bad
	{
		stepHeight = 0.075f;
		mxHeight = 15;
		timeDecay = TIME_DECAY_FAST;
	}*/
	else
	{
		stepHeight = 0.1f;
		mxHeight = 10;
		timeDecay = TIME_DECAY_MED;
	}

	// Pick "LOD" for width
	if ( width < 100 )
	{
		stepWidth = 0.2f;
		mxWidth = 5;
		timeDecay = ( timeDecay + TIME_DECAY_SLOW ) * 0.5f;
	}
/*	else if ( width > 220 ) // don't do this because it causes too much chug with large glass panes...especially when more than one pane can be broken at a time
	{
		stepWidth = 0.075f;
		mxWidth = 15;
		timeDecay = ( timeDecay + TIME_DECAY_FAST ) * 0.5f;
	}*/
	else
	{
		stepWidth = 0.1f;
		mxWidth = 10;
		timeDecay = ( timeDecay + TIME_DECAY_MED ) * 0.5f;
	}

	for ( z = 0.0f, i = 0; z < 1.0f; z += stepHeight, i++ )
	{
		for ( x = 0.0f, t = 0; x < 1.0f; x += stepWidth, t++ )
		{
			// This is nasty..we do this because we don't want to add a random offset on the edge of the glass brush
			//	...but we do in the center, otherwise the breaking scheme looks way too orderly
			if ( t > 0 && t < mxWidth )
			{
				xx = x - offX[i][t];
			}
			else
			{
				xx = x;
			}

			if ( i > 0 && i < mxHeight )
			{
				zz = z - offZ[t][i];
			}
			else
			{
				zz = z;
			}

			Vector2Set( biPoints[0], xx, zz );

			if ( t + 1 > 0 && t + 1 < mxWidth )
			{
				xx = x - offX[i][t + 1];
			}
			else
			{
				xx = x;
			}

			if ( i > 0 && i < mxHeight )
			{
				zz = z - offZ[t + 1][i];
			}
			else
			{
				zz = z;
			}

			Vector2Set( biPoints[1], xx + stepWidth, zz );

			if ( t + 1 > 0 && t + 1 < mxWidth )
			{
				xx = x - offX[i + 1][t + 1];
			}
			else
			{
				xx = x;
			}

			if ( i + 1 > 0 && i + 1 < mxHeight )
			{
				zz = z - offZ[t + 1][i + 1];
			}
			else
			{
				zz = z;
			}

			Vector2Set( biPoints[2], xx + stepWidth, zz + stepHeight);

			if ( t > 0 && t < mxWidth )
			{
				xx = x - offX[i + 1][t];
			}
			else
			{
				xx = x;
			}

			if ( i + 1 > 0 && i + 1 < mxHeight )
			{
				zz = z - offZ[t][i + 1];
			}
			else
			{
				zz = z;
			}

			Vector2Set( biPoints[3], xx, zz + stepHeight );

			CG_CalcBiLerp( verts, subVerts, biPoints );

			float dif = DistanceSquared( subVerts[0], dmgPt ) * timeDecay - Q_flrand(0.0f, 1.0f) * 32;

			// If we decrease dif, we are increasing the impact area, making it more likely to blow out large holes
			dif -= dmgRadius * dmgRadius;

			if ( dif > 1 )
			{
				stick = true;
				time = dif + Q_flrand(0.0f, 1.0f) * 200;
			}
			else
			{
				stick = false;
				time = 0;
			}

			CG_DoGlassQuad( subVerts, biPoints, stick, time, dmgDir );
		}
	}
}
void CG_DoGlass( vec3_t verts[4], vec3_t normal, vec3_t dmgPt, vec3_t dmgDir, float dmgRadius, int maxShards )
{
	int			i, t;
	int			mxHeight, mxWidth;
	float		height, width;
	float		stepWidth, stepHeight;
	float		timeDecay;
	float		x, z;
	float		xx, zz;
	float		dif;
	int			time = 0;
	int			glassShards = 0;
	qboolean	stick = qtrue;
	vec3_t		subVerts[4];
	vec2_t		biPoints[4];

	// To do a smarter tesselation, we should figure out the relative height and width of the brush face,
	//	then use this to pick a lod value from 1-3 in each axis.  This will give us 1-9 lod levels, which will
	//	hopefully be sufficient.
	CG_CalcHeightWidth( verts, &height, &width );

	trap->S_StartSound( dmgPt, -1, CHAN_AUTO, trap->S_RegisterSound("sound/effects/glassbreak1.wav"));

	// Pick "LOD" for height
	if ( height < 100 )
	{
		stepHeight = 0.2f;
		mxHeight = 5;
		timeDecay = TIME_DECAY_SLOW;
	}
	else if ( height > 220 )
	{
		stepHeight = 0.05f;
		mxHeight = 20;
		timeDecay = TIME_DECAY_FAST;
	}
	else
	{
		stepHeight = 0.1f;
		mxHeight = 10;
		timeDecay = TIME_DECAY_MED;
	}

	// Pick "LOD" for width
	/*
	if ( width < 100 )
	{
		stepWidth = 0.2f;
		mxWidth = 5;
		timeDecay = ( timeDecay + TIME_DECAY_SLOW ) * 0.5f;
	}
	else if ( width > 220 )
	{
		stepWidth = 0.05f;
		mxWidth = 20;
		timeDecay = ( timeDecay + TIME_DECAY_FAST ) * 0.5f;
	}
	else
	{
		stepWidth = 0.1f;
		mxWidth = 10;
		timeDecay = ( timeDecay + TIME_DECAY_MED ) * 0.5f;
	}
	*/

	//Attempt to scale the glass directly to the size of the window

	stepWidth = (0.25f - (width*0.0002)); //(width*0.0005));
	mxWidth = width*0.2;
	timeDecay = ( timeDecay + TIME_DECAY_FAST ) * 0.5f;

	if (stepWidth < 0.01f)
	{
		stepWidth = 0.01f;
	}
	if (mxWidth < 5)
	{
		mxWidth = 5;
	}

	for ( z = 0.0f, i = 0; z < 1.0f; z += stepHeight, i++ )
	{
		for ( x = 0.0f, t = 0; x < 1.0f; x += stepWidth, t++ )
		{
			// This is nasty..
			if ( t > 0 && t < mxWidth )
			{
				xx = x - offX[i][t];
			}
			else
			{
				xx = x;
			}

			if ( i > 0 && i < mxHeight )
			{
				zz = z - offZ[t][i];
			}
			else
			{
				zz = z;
			}

			Vector2Set( biPoints[0], xx, zz );

			if ( t + 1 > 0 && t + 1 < mxWidth )
			{
				xx = x - offX[i][t + 1];
			}
			else
			{
				xx = x;
			}

			if ( i > 0 && i < mxHeight )
			{
				zz = z - offZ[t + 1][i];
			}
			else
			{
				zz = z;
			}

			Vector2Set( biPoints[1], xx + stepWidth, zz );

			if ( t + 1 > 0 && t + 1 < mxWidth )
			{
				xx = x - offX[i + 1][t + 1];
			}
			else
			{
				xx = x;
			}

			if ( i + 1 > 0 && i + 1 < mxHeight )
			{
				zz = z - offZ[t + 1][i + 1];
			}
			else
			{
				zz = z;
			}

			Vector2Set( biPoints[2], xx + stepWidth, zz + stepHeight);

			if ( t > 0 && t < mxWidth )
			{
				xx = x - offX[i + 1][t];
			}
			else
			{
				xx = x;
			}

			if ( i + 1 > 0 && i + 1 < mxHeight )
			{
				zz = z - offZ[t][i + 1];
			}
			else
			{
				zz = z;
			}

			Vector2Set( biPoints[3], xx, zz + stepHeight );

			CG_CalcBiLerp( verts, subVerts, biPoints );
			
			dif = DistanceSquared( subVerts[0], dmgPt ) * timeDecay - random() * 32;
			
			// If we decrease dif, we are increasing the impact area, making it more likely to blow out large holes
			dif -= dmgRadius * dmgRadius;

			if ( dif > 1 )
			{
				stick = qtrue;
				time = dif + random() * 200;
			}
			else
			{
				stick = qfalse;
				time = 0;
			}

			CG_DoGlassQuad( subVerts, biPoints, stick, time, dmgDir );
			glassShards++;

			if (maxShards && glassShards >= maxShards)
			{
				return;
			}
		}
	}
}