You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
103 lines
2.9 KiB
103 lines
2.9 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
|
|
#include "cbase.h" |
|
#include "prop_portal_shared.h" |
|
#include "portal_collideable_enumerator.h" |
|
|
|
#define PORTAL_TELEPORTATION_PLANE_OFFSET 7.0f |
|
|
|
CPortalCollideableEnumerator::CPortalCollideableEnumerator( const CProp_Portal *pAssociatedPortal ) |
|
{ |
|
Assert( pAssociatedPortal ); |
|
m_hTestPortal = pAssociatedPortal; |
|
|
|
pAssociatedPortal->GetVectors( &m_vPlaneNormal, NULL, NULL ); |
|
|
|
m_ptForward1000 = pAssociatedPortal->GetAbsOrigin(); |
|
m_ptForward1000 += m_vPlaneNormal * PORTAL_TELEPORTATION_PLANE_OFFSET; |
|
m_fPlaneDist = m_vPlaneNormal.Dot( m_ptForward1000 ); |
|
|
|
m_ptForward1000 += m_vPlaneNormal * 1000.0f; |
|
|
|
m_iHandleCount = 0; |
|
} |
|
|
|
IterationRetval_t CPortalCollideableEnumerator::EnumElement( IHandleEntity *pHandleEntity ) |
|
{ |
|
EHANDLE hEnt = pHandleEntity->GetRefEHandle(); |
|
|
|
CBaseEntity *pEnt = hEnt.Get(); |
|
if( pEnt == NULL ) //I really never thought this would be necessary |
|
return ITERATION_CONTINUE; |
|
|
|
if( hEnt == m_hTestPortal ) |
|
return ITERATION_CONTINUE; //ignore this portal |
|
|
|
/*if( staticpropmgr->IsStaticProp( pHandleEntity ) ) |
|
{ |
|
//we're dealing with a static prop, which unfortunately doesn't have everything I want to use for checking |
|
|
|
ICollideable *pCollideable = pEnt->GetCollideable(); |
|
|
|
Vector vMins, vMaxs; |
|
pCollideable->WorldSpaceSurroundingBounds( &vMins, &vMaxs ); |
|
|
|
Vector ptTest( (m_vPlaneNormal.x > 0.0f)?(vMaxs.x):(vMins.x), |
|
(m_vPlaneNormal.y > 0.0f)?(vMaxs.y):(vMins.y), |
|
(m_vPlaneNormal.z > 0.0f)?(vMaxs.z):(vMins.z) ); |
|
|
|
float fPtPlaneDist = m_vPlaneNormal.Dot( ptTest ) - m_fPlaneDist; |
|
if( fPtPlaneDist <= 0.0f ) |
|
return ITERATION_CONTINUE; |
|
} |
|
else*/ |
|
{ |
|
//not a static prop, w00t |
|
CCollisionProperty *pEntityCollision = pEnt->CollisionProp(); |
|
|
|
if( !pEntityCollision->IsSolid() ) |
|
return ITERATION_CONTINUE; //not solid |
|
|
|
Vector ptEntCenter = pEntityCollision->WorldSpaceCenter(); |
|
|
|
float fBoundRadius = pEntityCollision->BoundingRadius(); |
|
float fPtPlaneDist = m_vPlaneNormal.Dot( ptEntCenter ) - m_fPlaneDist; |
|
|
|
if( fPtPlaneDist < -fBoundRadius ) |
|
return ITERATION_CONTINUE; //object wholly behind the portal |
|
|
|
if( !(fPtPlaneDist > fBoundRadius) && (fPtPlaneDist > -fBoundRadius) ) //object is not wholly in front of the portal, but could be partially in front, do more checks |
|
{ |
|
Vector ptNearest; |
|
pEntityCollision->CalcNearestPoint( m_ptForward1000, &ptNearest ); |
|
fPtPlaneDist = m_vPlaneNormal.Dot( ptNearest ) - m_fPlaneDist; |
|
if( fPtPlaneDist < 0.0f ) |
|
return ITERATION_CONTINUE; //closest point was behind the portal plane, we don't want it |
|
} |
|
|
|
|
|
} |
|
|
|
//if we're down here, this entity needs to be added to our enumeration |
|
Assert( m_iHandleCount < 1024 ); |
|
if( m_iHandleCount < 1024 ) |
|
m_pHandles[m_iHandleCount] = pHandleEntity; |
|
++m_iHandleCount; |
|
|
|
return ITERATION_CONTINUE; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|