PVS

A Potentially Visible Set (or Potential Visibility Set) is a collection of visleaves which might be visible from a given location. It is not a precise measure of visibility, but thanks to being pre-compiled into a map, it is a very fast one. It forms the basis for many run-time tests, including networking filtering and rendering control.
== Console Commands ==
== Programming ==
=== Clusters ===
; int engine->GetClusterForOrigin( Vector origin )
: Gets the cluster for the given origin.
; 
: The number of clusters in the map. 
; 
: Gets a list of all clusters' bounds. Returns total number of clusters. bbox_t is a struct containing a min and max .
=== PVS ===
A PVS is stored in a byte buffer in which each bit represents the visibility of a cluster.
; int engine->GetPVSForCluster( int cluster, int outputpvslength, byte* outputpvs )
: Places the PVS for the given cluster in outputpvs. The return value is the number of bytes that were written; values in the rest of the buffer are undefined.
; bool engine->CheckOriginInPVS( Vector origin, byte *checkpvs, int checkpvssize )
: Determines whether the given location is within the given PVS.
; bool engine->CheckBoxInPVS( Vector mins, Vector maxs, byte *checkpvs, int checkpvssize )
: Determines whether the given box is within the given PVS at any point.
; void engine->ResetPVS( byte *pvs, int pvssize )
: Resets pvssize bytes to 0, starting at pvs.
; void engine->AddOriginToPVS( Vector origin )
: Deprecated? Adds the PVS of the given origin to the "current accumulated pvs" with an "8 unit fudge factor".
==== Example ====
This function bypasses the problem of a dynamic light entity being processed needlessly when its bounding box pokes through a wall. The code is quite expensive, but not as expensive as a dynamic light!
int CMyEnt::ShouldTransmit(const CCheckTransmitInfo *pInfo)
{
	Vector vecSurroundMins, vecSurroundMaxs;
	CollisionProp()->WorldSpaceSurroundingBounds( &vecSurroundMins, &vecSurroundMaxs );
	
	// Are our surrounding bounds in PVS?
	if ( !engine->CheckBoxInPVS(vecSurroundMins, vecSurroundMaxs, pInfo->m_PVS, pInfo->m_nPVSSize) )
		return FL_EDICT_DONTSEND;
	// Get our own PVS (cache the buffer if you use this code)
	int pvsSize = ceil(engine->GetClusterCount() / 8.0f); // bits to bytes
	byte* pvs = new byte[pvsSize];
	int cluster = engine->GetClusterForOrigin(GetAbsOrigin());
	engine->GetPVSForCluster(cluster, pvsSize, pvs);
	// Find the intersection of our PVS and the player's
	byte* pvs_shared = new byte[pvsSize];
	bool found_overlap = false;
	for (int i=0; i < pvsSize; i++)
	{
		pvs_shared[i] = pvs[i] & pInfo->PVS[i]; // bitwise AND
		
		if (!found_overlap && pvs_shared[i] != 0)
			found_overlap = true;
	}
	bool in_pvs = false;
	if (found_overlap)
		in_pvs = engine->CheckBoxInPVS( vecSurroundMins, vecSurroundMaxs, pvs_shared, pvsSize );
	// Free the memory we just allocated
	delete[] pvs;
	delete[] pvs_shared;
	// transmit if we are in the shared PVS
	return in_pvs ? FL_EDICT_ALWAYS : FL_EDICT_DONTSEND;
}
=== Areas ===
Areas are completely separate collections of leaves, either set in stone by brushwork or created dynamically by closed areaportals (the latter of which PVS alone cannot account for).
; int engine->GetArea( Vector origin )
: Determine which area the origin is within.
; void engine->GetAreaBits( int area, byte *bits, int buflen )
: Get a bit buffer of which areas the given area can flow into.
; int engine->CheckAreasConnected( int area1, int area2 )
: Check whether area1 flows into area2 and vice versa. Result depends on areaportal state. 
; bool engine->GetAreaPortalPlane( Vector vViewOrigin, int portalKey, VPlane *pPlane )
: Given a view origin (which tells us the area to start looking in) and a portal key, fill in the plane that leads out of this area (it points into whatever area it leads to).
; void engine->SetAreaPortalState( int portalNumber, int isOpen )
; void engine->SetAreaPortalStates( int *portalNumbers, int *isOpen, int nPortals )
: Open or close one or many areaportals.
== See also ==
* Visibility optimization for in-depth discussion of how leaves and the PVS work.
* Half-Life 2 Map Editing Optimization Guide: Visleafs 
* VBSP, which generates leaves
* VVIS, which determines visibility between leaves
* PAS, the Potentially Audible Set
* Wikipedia:Potentially visible set
Category:Glossary
Category:Programming