1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
|
//========= Copyright 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
};
// 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 \
)
// 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_V1() = 0;
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:
// Add a virtual destructor to silence the clang warning.
// This is harmless but not important since the only derived class
// doesn't have a destructor.
virtual ~ISpatialPartition() {}
// 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_V1( 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;
virtual void InstallQueryCallback( IPartitionQueryCallback *pCallback ) = 0;
};
#endif
|