Added NPC PVS checking for point_cameras

This commit is contained in:
Blixibon 2022-11-21 00:51:54 -06:00
parent a2e91759e0
commit b2110d0354
3 changed files with 64 additions and 0 deletions

View File

@ -98,6 +98,7 @@
#ifdef MAPBASE
#include "mapbase/matchers.h"
#include "items.h"
#include "point_camera.h"
#endif
#ifdef MAPBASE_VSCRIPT
@ -4301,6 +4302,12 @@ bool CAI_BaseNPC::CheckPVSCondition()
{
bool bInPVS = ( UTIL_FindClientInPVS( edict() ) != NULL ) || (UTIL_ClientPVSIsExpanded() && UTIL_FindClientInVisibilityPVS( edict() ));
#ifdef MAPBASE
// We can be in a player's PVS if there is an active point_camera nearby (fixes issues with choreo)
if (!bInPVS && UTIL_FindRTCameraInEntityPVS( edict() ))
bInPVS = true;
#endif
if ( bInPVS )
SetCondition( COND_IN_PVS );
else

View File

@ -28,6 +28,58 @@ CPointCamera* GetPointCameraList()
return g_PointCameraList.m_pClassList;
}
#ifdef MAPBASE
//-----------------------------------------------------------------------------
// Purpose: Returns true if a camera is in the PVS of the specified entity
//-----------------------------------------------------------------------------
edict_t *UTIL_FindRTCameraInEntityPVS( edict_t *pEdict )
{
CBaseEntity *pe = GetContainingEntity( pEdict );
if ( !pe )
return NULL;
bool bGotPVS = false;
Vector org;
static byte pvs[ MAX_MAP_CLUSTERS/8 ];
static int pvssize = sizeof( pvs );
for ( CPointCamera *pCameraEnt = GetPointCameraList(); pCameraEnt != NULL; pCameraEnt = pCameraEnt->m_pNext )
{
if (!pCameraEnt->IsActive())
continue;
if (!bGotPVS)
{
// Getting the PVS during the loop like this makes sure we only get the PVS if there's actually an active camera in the level
org = pe->EyePosition();
int clusterIndex = engine->GetClusterForOrigin( org );
Assert( clusterIndex >= 0 );
engine->GetPVSForCluster( clusterIndex, pvssize, pvs );
bGotPVS = true;
}
Vector vecCameraEye = pCameraEnt->EyePosition();
Vector vecCameraDirection;
pCameraEnt->GetVectors( &vecCameraDirection, NULL, NULL );
Vector los = (org - vecCameraEye);
float flDot = DotProduct( los, vecCameraDirection );
// Make sure we're in the camera's FOV before checking PVS
if ( flDot <= cos( DEG2RAD( pCameraEnt->GetFOV() / 2 ) ) )
continue;
if ( engine->CheckOriginInPVS( vecCameraEye, pvs, pvssize ) )
{
return pCameraEnt->edict();
}
}
return NULL;
}
#endif
// These are already built into CBaseEntity
// DEFINE_KEYFIELD( m_iName, FIELD_STRING, "targetname" ),
// DEFINE_KEYFIELD( m_iParent, FIELD_STRING, "parentname" ),

View File

@ -42,6 +42,7 @@ public:
void InputSetRenderTarget( inputdata_t &inputdata ) { m_iszRenderTarget = inputdata.value.StringID(); }
float GetFOV() const { return m_FOV; }
bool IsActive() const { return m_bIsOn; }
#endif
private:
@ -117,4 +118,8 @@ private:
#endif
CPointCamera *GetPointCameraList();
#ifdef MAPBASE
edict_t *UTIL_FindRTCameraInEntityPVS( edict_t *pEdict );
#endif
#endif // CAMERA_H