//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// // // Purpose: // // $Revision: $ // $NoKeywords: $ //=============================================================================// #ifndef ISPATIALPARTITION_H #define ISPATIALPARTITION_H #include "interface.h" //----------------------------------------------------------------------------- // forward declarations //----------------------------------------------------------------------------- class Vector; struct Ray_t; class IHandleEntity; #define INTERFACEVERSION_SPATIALPARTITION "SpatialPartition001" //----------------------------------------------------------------------------- // These are the various partition lists. Note some are server only, some // are client only //----------------------------------------------------------------------------- enum { PARTITION_ENGINE_SOLID_EDICTS = (1 << 0), // every edict_t that isn't SOLID_TRIGGER or SOLID_NOT (and static props) PARTITION_ENGINE_TRIGGER_EDICTS = (1 << 1), // every edict_t that IS SOLID_TRIGGER PARTITION_CLIENT_SOLID_EDICTS = (1 << 2), PARTITION_CLIENT_RESPONSIVE_EDICTS = (1 << 3), // these are client-side only objects that respond to being forces, etc. PARTITION_ENGINE_NON_STATIC_EDICTS = (1 << 4), // everything in solid & trigger except the static props, includes SOLID_NOTs PARTITION_CLIENT_STATIC_PROPS = (1 << 5), PARTITION_ENGINE_STATIC_PROPS = (1 << 6), PARTITION_CLIENT_NON_STATIC_EDICTS = (1 << 7), // everything except the static props PARTITION_CLIENT_TRIGGER_ENTITIES = (1 << 8), // client side prediction related triggers PARTITION_CLIENT_IK_ATTACHMENT = (1 << 9), // Can be used as an IK attachment PARTITION_ENGINE_PUSHABLE = (1 << 10), // everything with a movetype that can be pushed by MOVETYPE_PUSH ents }; // Use this to look for all client edicts. #define PARTITION_ALL_CLIENT_EDICTS ( \ PARTITION_CLIENT_NON_STATIC_EDICTS | \ PARTITION_CLIENT_STATIC_PROPS | \ PARTITION_CLIENT_RESPONSIVE_EDICTS | \ PARTITION_CLIENT_SOLID_EDICTS | \ PARTITION_CLIENT_TRIGGER_ENTITIES \ ) // These are the only handles in the spatial partition that the game is controlling (everything but static props) // These masks are used to handle updating the dirty spatial partition list in each game DLL #define PARTITION_CLIENT_GAME_EDICTS (PARTITION_ALL_CLIENT_EDICTS & ~PARTITION_CLIENT_STATIC_PROPS) #define PARTITION_SERVER_GAME_EDICTS (PARTITION_ENGINE_SOLID_EDICTS|PARTITION_ENGINE_TRIGGER_EDICTS|PARTITION_ENGINE_NON_STATIC_EDICTS) //----------------------------------------------------------------------------- // Clients that want to know about all elements within a particular // volume must inherit from this //----------------------------------------------------------------------------- enum IterationRetval_t { ITERATION_CONTINUE = 0, ITERATION_STOP, }; typedef unsigned short SpatialPartitionHandle_t; // A combination of the PARTITION_ flags above. typedef int SpatialPartitionListMask_t; typedef int SpatialTempHandle_t; //----------------------------------------------------------------------------- // Any search in the CSpatialPartition must use this to filter out entities it doesn't want. // You're forced to use listMasks because it can filter by listMasks really fast. Any other // filtering can be done by EnumElement. //----------------------------------------------------------------------------- class IPartitionEnumerator { public: virtual IterationRetval_t EnumElement( IHandleEntity *pHandleEntity ) = 0; }; //----------------------------------------------------------------------------- // Installs a callback to call right before a spatial partition query occurs //----------------------------------------------------------------------------- class IPartitionQueryCallback { public: virtual void OnPreQuery( SpatialPartitionListMask_t listMask ) = 0; virtual void OnPostQuery( SpatialPartitionListMask_t listMask ) = 0; }; //----------------------------------------------------------------------------- // This is the spatial partition manager, groups objects into buckets //----------------------------------------------------------------------------- enum { PARTITION_INVALID_HANDLE = (SpatialPartitionHandle_t)~0 }; abstract_class ISpatialPartition { public: // Create/destroy a handle for this dude in our system. Destroy // will also remove it from all lists it happens to be in virtual SpatialPartitionHandle_t CreateHandle( IHandleEntity *pHandleEntity ) = 0; // A fast method of creating a handle + inserting into the tree in the right place virtual SpatialPartitionHandle_t CreateHandle( IHandleEntity *pHandleEntity, SpatialPartitionListMask_t listMask, const Vector& mins, const Vector& maxs ) = 0; virtual void DestroyHandle( SpatialPartitionHandle_t handle ) = 0; // Adds, removes an handle from a particular spatial partition list // There can be multiple partition lists; each has a unique id virtual void Insert( SpatialPartitionListMask_t listMask, SpatialPartitionHandle_t handle ) = 0; virtual void Remove( SpatialPartitionListMask_t listMask, SpatialPartitionHandle_t handle ) = 0; // Same as calling Remove() then Insert(). For performance-sensitive areas where you want to save a call. virtual void RemoveAndInsert( SpatialPartitionListMask_t removeMask, SpatialPartitionListMask_t insertMask, SpatialPartitionHandle_t handle ) = 0; // This will remove a particular handle from all lists virtual void Remove( SpatialPartitionHandle_t handle ) = 0; // Call this when an entity moves... virtual void ElementMoved( SpatialPartitionHandle_t handle, const Vector& mins, const Vector& maxs ) = 0; // A fast method to insert + remove a handle from the tree... // This is used to suppress collision of a single model.. virtual SpatialTempHandle_t HideElement( SpatialPartitionHandle_t handle ) = 0; virtual void UnhideElement( SpatialPartitionHandle_t handle, SpatialTempHandle_t tempHandle ) = 0; // Installs callbacks to get called right before a query occurs virtual void InstallQueryCallback( IPartitionQueryCallback *pCallback ) = 0; virtual void RemoveQueryCallback( IPartitionQueryCallback *pCallback ) = 0; // Gets all entities in a particular volume... // if coarseTest == true, it'll return all elements that are in // spatial partitions that intersect the box // if coarseTest == false, it'll return only elements that truly intersect virtual void EnumerateElementsInBox( SpatialPartitionListMask_t listMask, const Vector& mins, const Vector& maxs, bool coarseTest, IPartitionEnumerator* pIterator ) = 0; virtual void EnumerateElementsInSphere( SpatialPartitionListMask_t listMask, const Vector& origin, float radius, bool coarseTest, IPartitionEnumerator* pIterator ) = 0; virtual void EnumerateElementsAlongRay( SpatialPartitionListMask_t listMask, const Ray_t& ray, bool coarseTest, IPartitionEnumerator* pIterator ) = 0; virtual void EnumerateElementsAtPoint( SpatialPartitionListMask_t listMask, const Vector& pt, bool coarseTest, IPartitionEnumerator* pIterator ) = 0; // For debugging.... suppress queries on particular lists virtual void SuppressLists( SpatialPartitionListMask_t nListMask, bool bSuppress ) = 0; virtual SpatialPartitionListMask_t GetSuppressedLists() = 0; virtual void RenderAllObjectsInTree( float flTime ) = 0; virtual void RenderObjectsInPlayerLeafs( const Vector &vecPlayerMin, const Vector &vecPlayerMax, float flTime ) = 0; virtual void RenderLeafsForRayTraceStart( float flTime ) = 0; virtual void RenderLeafsForRayTraceEnd( void ) = 0; virtual void RenderLeafsForHullTraceStart( float flTime ) = 0; virtual void RenderLeafsForHullTraceEnd( void ) = 0; virtual void RenderLeafsForBoxStart( float flTime ) = 0; virtual void RenderLeafsForBoxEnd( void ) = 0; virtual void RenderLeafsForSphereStart( float flTime ) = 0; virtual void RenderLeafsForSphereEnd( void ) = 0; virtual void RenderObjectsInBox( const Vector &vecMin, const Vector &vecMax, float flTime ) = 0; virtual void RenderObjectsInSphere( const Vector &vecCenter, float flRadius, float flTime ) = 0; virtual void RenderObjectsAlongRay( const Ray_t& ray, float flTime ) = 0; virtual void ReportStats( const char *pFileName ) = 0; }; #endif