void CPortalGameMovement::TracePlayerBBox( const Vector& start, const Vector& end, unsigned int fMask, int collisionGroup, trace_t& pm ) { VPROF( "CGameMovement::TracePlayerBBox" ); CPortal_Player *pPortalPlayer = (CPortal_Player *)((CBaseEntity *)mv->m_nPlayerHandle.Get()); Ray_t ray; ray.Init( start, end, GetPlayerMins(), GetPlayerMaxs() ); #ifdef CLIENT_DLL CTraceFilterSimple traceFilter( mv->m_nPlayerHandle.Get(), collisionGroup ); #else CTraceFilterSimple baseFilter( mv->m_nPlayerHandle.Get(), collisionGroup ); CTraceFilterTranslateClones traceFilter( &baseFilter ); #endif UTIL_Portal_TraceRay_With( pPortalPlayer->m_hPortalEnvironment, ray, fMask, &traceFilter, &pm ); // If we're moving through a portal and failed to hit anything with the above ray trace // Use UTIL_Portal_TraceEntity to test this movement through a portal and override the trace with the result if ( pm.fraction == 1.0f && UTIL_DidTraceTouchPortals( ray, pm ) && sv_player_trace_through_portals.GetBool() ) { trace_t tempTrace; UTIL_Portal_TraceEntity( pPortalPlayer, start, end, fMask, &traceFilter, &tempTrace ); if ( tempTrace.DidHit() && tempTrace.fraction < pm.fraction && !tempTrace.startsolid && !tempTrace.allsolid ) { pm = tempTrace; } } }
void UTIL_TraceEntity( CBaseEntity *pEntity, const Vector &vecAbsStart, const Vector &vecAbsEnd, unsigned int mask, ITraceFilter *pFilter, trace_t *ptr ) { ICollideable *pCollision; pCollision = pEntity->GetCollideable(); // Adding this assertion here so game code catches it, but really the assertion belongs in the engine // because one day, rotated collideables will work! Assert( pCollision->GetCollisionAngles() == vec3_angle ); #ifdef PORTAL UTIL_Portal_TraceEntity( pEntity, vecAbsStart, vecAbsEnd, mask, pFilter, ptr ); #else enginetrace->SweepCollideable( pCollision, vecAbsStart, vecAbsEnd, pCollision->GetCollisionAngles(), mask, pFilter, ptr ); #endif }