summaryrefslogtreecommitdiff
path: root/game/shared/portal/portal_collideable_enumerator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'game/shared/portal/portal_collideable_enumerator.cpp')
-rw-r--r--game/shared/portal/portal_collideable_enumerator.cpp103
1 files changed, 103 insertions, 0 deletions
diff --git a/game/shared/portal/portal_collideable_enumerator.cpp b/game/shared/portal/portal_collideable_enumerator.cpp
new file mode 100644
index 0000000..6cd2742
--- /dev/null
+++ b/game/shared/portal/portal_collideable_enumerator.cpp
@@ -0,0 +1,103 @@
+//========= 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;
+}
+
+
+
+
+
+
+
+
+
+