Example #1
0
//-----------------------------------------------------------------------------
// Return intersection point of ray with screen in barycentric coords
//-----------------------------------------------------------------------------
bool C_VGuiScreen::IntersectWithRay( const Ray_t &ray, float *u, float *v, float *t )
{
	// Perform a raycast to see where in barycentric coordinates the ray hits
	// the viewscreen; if it doesn't hit it, you're not in the mode
	Vector origin, upt, vpt;
	ComputeEdges( &origin, &upt, &vpt );
	return ComputeIntersectionBarycentricCoordinates( ray, origin, upt, vpt, *u, *v, t );
}
bool C_Shield::TestCollision( const Ray_t& ray, unsigned int mask, trace_t& trace )
{
	// Can't block anything if we're EMPed, or we've got no power left to block
	if ( m_bIsEMPed )
		return false;
	if ( m_flPowerLevel <= 0 )
		return false;

	// Here, we're gonna test for collision.
	// If we don't stop this kind of bullet, we'll generate an effect here
	// but we won't change the trace to indicate a collision.

	// It's just polygon soup...
	int hitgroup;
	bool firstTri;
	int v1[2], v2[2], v3[2];
	float ihit, jhit;
	float mint = FLT_MAX;
	float t;

	int h = Height();
	int w = Width();

	for (int i = 0; i < h - 1; ++i)
	{
		for (int j = 0; j < w - 1; ++j)
		{
			// Don't test if this panel ain't active...
			if (!IsPanelActive( j, i ))
				continue;

			// NOTE: Structure order of points so that our barycentric
			// axes for each triangle are along the (u,v) directions of the mesh
			// The barycentric coords we'll need below 

			// Two triangles per quad...
			t = IntersectRayWithTriangle( ray,
				GetPoint( j, i + 1 ),
				GetPoint( j + 1, i + 1 ),
				GetPoint( j, i ), true );
			if ((t >= 0.0f) && (t < mint))
			{
				mint = t;
				v1[0] = j;		v1[1] = i + 1;
				v2[0] = j + 1;	v2[1] = i + 1;
				v3[0] = j;		v3[1] = i;
				ihit = i; jhit = j;
				firstTri = true;
			}
			
			t = IntersectRayWithTriangle( ray,
				GetPoint( j + 1, i ),
				GetPoint( j, i ),
				GetPoint( j + 1, i + 1 ), true );
			if ((t >= 0.0f) && (t < mint))
			{
				mint = t;
				v1[0] = j + 1;	v1[1] = i;
				v2[0] = j;		v2[1] = i;
				v3[0] = j + 1;	v3[1] = i + 1;
				ihit = i; jhit = j;
				firstTri = false;
			}
		}
	}

	if (mint == FLT_MAX)
		return false;

	// Stuff the barycentric coordinates of the triangle hit into the hit group 
	// For the first triangle, the first edge goes along u, the second edge goes
	// along -v. For the second triangle, the first edge goes along -u,
	// the second edge goes along v.
	const Vector& v1vec = GetPoint(v1[0], v1[1]);
	const Vector& v2vec = GetPoint(v2[0], v2[1]);
	const Vector& v3vec = GetPoint(v3[0], v3[1]);
	float u, v;
	bool ok = ComputeIntersectionBarycentricCoordinates( ray, 
		v1vec, v2vec, v3vec, u, v );
	Assert( ok );
	if ( !ok )
	{
		return false;
	}

	if (firstTri)
		v = 1.0 - v;
	else
		u = 1.0 - u;
	v += ihit; u += jhit;
	v /= (h - 1);
	u /= (w - 1);

	// Compress (u,v) into 1 dot 15, v in top bits
	hitgroup = (((int)(v * (1 << 15))) << 16) + (int)(u * (1 << 15));

	Vector normal;
	float intercept;
	ComputeTrianglePlane( v1vec, v2vec, v3vec, normal, intercept ); 

	UTIL_SetTrace( trace, ray, this, mint, hitgroup, CONTENTS_SOLID, normal, intercept );
	return true;
}