//----------------------------------------------------------------------------- // 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; }