// Given a line segment from vStart to vEnd // and a list of convex polygons in pSurfInfos and nSurfInfos, // fill in the list of which polygons the segment intersects. // Returns the number of intersected surfaces. static int IntersectSegmentWithSurfInfos( const Vector &vStart, const Vector &vEnd, SurfInfo *pSurfInfos, const int nSurfInfos, SurfInfo ** pIntersections, Vector *pIntersectionPositions, int nMaxIntersections) { if(nMaxIntersections == 0) return 0; int nIntersections = 0; for(int i=0; i < nSurfInfos; i++) { SurfInfo *pSurf = &pSurfInfos[i]; // Does it intersect the plane? float dot1 = pSurf->m_Plane.DistTo(vStart); float dot2 = pSurf->m_Plane.DistTo(vEnd); if((dot1 > 0) != (dot2 > 0)) { float t = dot1 / (dot1 - dot2); Vector vIntersection = vStart + (vEnd - vStart) * t; // If the intersection is behind any edge plane, then it's not inside the polygon. unsigned long iEdge; for(iEdge=0; iEdge < pSurf->m_nVerts; iEdge++) { VPlane edgePlane; edgePlane.m_Normal = pSurf->m_Plane.m_Normal.Cross(pSurf->m_Verts[iEdge] - pSurf->m_Verts[(iEdge+1)%pSurf->m_nVerts]); VectorNormalize( edgePlane.m_Normal ); edgePlane.m_Dist = edgePlane.m_Normal.Dot(pSurf->m_Verts[iEdge]); if(edgePlane.DistTo(vIntersection) < 0.0f) break; } if(iEdge == pSurf->m_nVerts) { pIntersections[nIntersections] = pSurf; pIntersectionPositions[nIntersections] = vIntersection; ++nIntersections; if(nIntersections >= nMaxIntersections) break; } } } return nIntersections; }
VMatrix SetupMatrixReflection(const VPlane &thePlane) { VMatrix mReflect, mBack, mForward; Vector vOrigin, N; N = thePlane.m_Normal; mReflect.Init( -2.0f*N.x*N.x + 1.0f, -2.0f*N.x*N.y, -2.0f*N.x*N.z, 0.0f, -2.0f*N.y*N.x, -2.0f*N.y*N.y + 1.0f, -2.0f*N.y*N.z, 0.0f, -2.0f*N.z*N.x, -2.0f*N.z*N.y, -2.0f*N.z*N.z + 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f ); vOrigin = thePlane.GetPointOnPlane(); mBack.Identity(); mBack.SetTranslation(-vOrigin); mForward.Identity(); mForward.SetTranslation(vOrigin); // (multiplied in reverse order, so it translates to the origin point, // reflects, and translates back). return mForward * mReflect * mBack; }
bool CFuncAreaPortalBase::UpdateVisibility( const Vector &vOrigin, float fovDistanceAdjustFactor, bool &bIsOpenOnClient ) { // NOTE: We leave bIsOpenOnClient alone on purpose here. See the header for a description of why. if( m_portalNumber == -1 ) return false; // See if the viewer is on the backside. VPlane plane; if( !engine->GetAreaPortalPlane( vOrigin, m_portalNumber, &plane ) ) return true; // leave it open if there's an error here for some reason bool bOpen = false; if( plane.DistTo( vOrigin ) + VIEWER_PADDING > 0 ) bOpen = true; return bOpen; }
bool CFuncAreaPortalBase::UpdateVisibility( const CUtlVector< Vector > &vecOrigins, float fovDistanceAdjustFactor, bool &bIsOpenOnClient ) { // NOTE: We leave bIsOpenOnClient alone on purpose here. See the header for a description of why. if( m_portalNumber == -1 ) return false; // See if the viewer is on the backside. for ( int i = 0; i < vecOrigins.Count(); ++i ) { const Vector &vOrigin = vecOrigins[ i ]; VPlane plane; if( !engine->GetAreaPortalPlane( vOrigin, m_portalNumber, &plane ) ) return true; // leave it open if there's an error here for some reason // If either players' origin is on the front, the areaportal is considered opened... if( plane.DistTo( vOrigin ) + VIEWER_PADDING > 0 ) return true; } return false; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void C_FireSmoke::FindClipPlane( void ) { m_bClipTested = true; m_flClipPerc = 1.0f; trace_t tr; Vector end( 0.0f, 0.0f, SMOKE_RISE_RATE*SMOKE_LIFETIME ); UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin()+end, MASK_SOLID_BRUSHONLY, NULL, COLLISION_GROUP_NONE, &tr ); //If the ceiling is too close, reject smoke if ( tr.fraction < 0.5f ) { m_nFlags &= ~bitsFIRESMOKE_SMOKE; return; } if ( tr.fraction < 1.0f ) { m_planeClip.Init( tr.plane.normal, tr.plane.dist ); m_nFlags |= bitsFIRESMOKE_SMOKE_COLLISION; m_flClipPerc = tr.fraction * 0.5f; } }