1/*
2Bullet Continuous Collision Detection and Physics Library
3Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
4
5This software is provided 'as-is', without any express or implied warranty.
6In no event will the authors be held liable for any damages arising from the use of this software.
7Permission is granted to anyone to use this software for any purpose,
8including commercial applications, and to alter it and redistribute it freely,
9subject to the following restrictions:
10
111. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
122. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
133. This notice may not be removed or altered from any source distribution.
14*/
15
16#ifndef BT_OVERLAPPING_PAIR_CACHE_H
17#define BT_OVERLAPPING_PAIR_CACHE_H
18
19
20#include "btBroadphaseInterface.h"
21#include "btBroadphaseProxy.h"
22#include "btOverlappingPairCallback.h"
23
24#include "LinearMath/btAlignedObjectArray.h"
25class btDispatcher;
26
27typedef btAlignedObjectArray<btBroadphasePair>	btBroadphasePairArray;
28
29struct	btOverlapCallback
30{
31	virtual ~btOverlapCallback()
32	{}
33	//return true for deletion of the pair
34	virtual bool	processOverlap(btBroadphasePair& pair) = 0;
35
36};
37
38struct btOverlapFilterCallback
39{
40	virtual ~btOverlapFilterCallback()
41	{}
42	// return true when pairs need collision
43	virtual bool	needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const = 0;
44};
45
46
47
48
49
50
51
52extern int gRemovePairs;
53extern int gAddedPairs;
54extern int gFindPairs;
55
56const int BT_NULL_PAIR=0xffffffff;
57
58///The btOverlappingPairCache provides an interface for overlapping pair management (add, remove, storage), used by the btBroadphaseInterface broadphases.
59///The btHashedOverlappingPairCache and btSortedOverlappingPairCache classes are two implementations.
60class btOverlappingPairCache : public btOverlappingPairCallback
61{
62public:
63	virtual ~btOverlappingPairCache() {} // this is needed so we can get to the derived class destructor
64
65	virtual btBroadphasePair*	getOverlappingPairArrayPtr() = 0;
66
67	virtual const btBroadphasePair*	getOverlappingPairArrayPtr() const = 0;
68
69	virtual btBroadphasePairArray&	getOverlappingPairArray() = 0;
70
71	virtual	void	cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher) = 0;
72
73	virtual int getNumOverlappingPairs() const = 0;
74
75	virtual void	cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher) = 0;
76
77	virtual	void setOverlapFilterCallback(btOverlapFilterCallback* callback) = 0;
78
79	virtual void	processAllOverlappingPairs(btOverlapCallback*,btDispatcher* dispatcher) = 0;
80
81	virtual btBroadphasePair* findPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) = 0;
82
83	virtual bool	hasDeferredRemoval() = 0;
84
85	virtual	void	setInternalGhostPairCallback(btOverlappingPairCallback* ghostPairCallback)=0;
86
87	virtual void	sortOverlappingPairs(btDispatcher* dispatcher) = 0;
88
89
90};
91
92/// Hash-space based Pair Cache, thanks to Erin Catto, Box2D, http://www.box2d.org, and Pierre Terdiman, Codercorner, http://codercorner.com
93class btHashedOverlappingPairCache : public btOverlappingPairCache
94{
95	btBroadphasePairArray	m_overlappingPairArray;
96	btOverlapFilterCallback* m_overlapFilterCallback;
97	bool		m_blockedForChanges;
98
99protected:
100
101	btAlignedObjectArray<int>	m_hashTable;
102	btAlignedObjectArray<int>	m_next;
103	btOverlappingPairCallback*	m_ghostPairCallback;
104
105
106public:
107	btHashedOverlappingPairCache();
108	virtual ~btHashedOverlappingPairCache();
109
110
111	void	removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
112
113	virtual void*	removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,btDispatcher* dispatcher);
114
115	SIMD_FORCE_INLINE bool needsBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const
116	{
117		if (m_overlapFilterCallback)
118			return m_overlapFilterCallback->needBroadphaseCollision(proxy0,proxy1);
119
120		bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
121		collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
122
123		return collides;
124	}
125
126	// Add a pair and return the new pair. If the pair already exists,
127	// no new pair is created and the old one is returned.
128	virtual btBroadphasePair* 	addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
129	{
130		gAddedPairs++;
131
132		if (!needsBroadphaseCollision(proxy0,proxy1))
133			return 0;
134
135		return internalAddPair(proxy0,proxy1);
136	}
137
138
139
140	void	cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
141
142
143	virtual void	processAllOverlappingPairs(btOverlapCallback*,btDispatcher* dispatcher);
144
145	virtual btBroadphasePair*	getOverlappingPairArrayPtr()
146	{
147		return &m_overlappingPairArray[0];
148	}
149
150	const btBroadphasePair*	getOverlappingPairArrayPtr() const
151	{
152		return &m_overlappingPairArray[0];
153	}
154
155	btBroadphasePairArray&	getOverlappingPairArray()
156	{
157		return m_overlappingPairArray;
158	}
159
160	const btBroadphasePairArray&	getOverlappingPairArray() const
161	{
162		return m_overlappingPairArray;
163	}
164
165	void	cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher);
166
167
168
169	btBroadphasePair* findPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1);
170
171	int GetCount() const { return m_overlappingPairArray.size(); }
172//	btBroadphasePair* GetPairs() { return m_pairs; }
173
174	btOverlapFilterCallback* getOverlapFilterCallback()
175	{
176		return m_overlapFilterCallback;
177	}
178
179	void setOverlapFilterCallback(btOverlapFilterCallback* callback)
180	{
181		m_overlapFilterCallback = callback;
182	}
183
184	int	getNumOverlappingPairs() const
185	{
186		return m_overlappingPairArray.size();
187	}
188private:
189
190	btBroadphasePair* 	internalAddPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
191
192	void	growTables();
193
194	SIMD_FORCE_INLINE bool equalsPair(const btBroadphasePair& pair, int proxyId1, int proxyId2)
195	{
196		return pair.m_pProxy0->getUid() == proxyId1 && pair.m_pProxy1->getUid() == proxyId2;
197	}
198
199	/*
200	// Thomas Wang's hash, see: http://www.concentric.net/~Ttwang/tech/inthash.htm
201	// This assumes proxyId1 and proxyId2 are 16-bit.
202	SIMD_FORCE_INLINE int getHash(int proxyId1, int proxyId2)
203	{
204		int key = (proxyId2 << 16) | proxyId1;
205		key = ~key + (key << 15);
206		key = key ^ (key >> 12);
207		key = key + (key << 2);
208		key = key ^ (key >> 4);
209		key = key * 2057;
210		key = key ^ (key >> 16);
211		return key;
212	}
213	*/
214
215
216
217	SIMD_FORCE_INLINE	unsigned int getHash(unsigned int proxyId1, unsigned int proxyId2)
218	{
219		int key = static_cast<int>(((unsigned int)proxyId1) | (((unsigned int)proxyId2) <<16));
220		// Thomas Wang's hash
221
222		key += ~(key << 15);
223		key ^=  (key >> 10);
224		key +=  (key << 3);
225		key ^=  (key >> 6);
226		key += ~(key << 11);
227		key ^=  (key >> 16);
228		return static_cast<unsigned int>(key);
229	}
230
231
232
233
234
235	SIMD_FORCE_INLINE btBroadphasePair* internalFindPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1, int hash)
236	{
237		int proxyId1 = proxy0->getUid();
238		int proxyId2 = proxy1->getUid();
239		#if 0 // wrong, 'equalsPair' use unsorted uids, copy-past devil striked again. Nat.
240		if (proxyId1 > proxyId2)
241			btSwap(proxyId1, proxyId2);
242		#endif
243
244		int index = m_hashTable[hash];
245
246		while( index != BT_NULL_PAIR && equalsPair(m_overlappingPairArray[index], proxyId1, proxyId2) == false)
247		{
248			index = m_next[index];
249		}
250
251		if ( index == BT_NULL_PAIR )
252		{
253			return NULL;
254		}
255
256		btAssert(index < m_overlappingPairArray.size());
257
258		return &m_overlappingPairArray[index];
259	}
260
261	virtual bool	hasDeferredRemoval()
262	{
263		return false;
264	}
265
266	virtual	void	setInternalGhostPairCallback(btOverlappingPairCallback* ghostPairCallback)
267	{
268		m_ghostPairCallback = ghostPairCallback;
269	}
270
271	virtual void	sortOverlappingPairs(btDispatcher* dispatcher);
272
273
274
275};
276
277
278
279
280///btSortedOverlappingPairCache maintains the objects with overlapping AABB
281///Typically managed by the Broadphase, Axis3Sweep or btSimpleBroadphase
282class	btSortedOverlappingPairCache : public btOverlappingPairCache
283{
284	protected:
285		//avoid brute-force finding all the time
286		btBroadphasePairArray	m_overlappingPairArray;
287
288		//during the dispatch, check that user doesn't destroy/create proxy
289		bool		m_blockedForChanges;
290
291		///by default, do the removal during the pair traversal
292		bool		m_hasDeferredRemoval;
293
294		//if set, use the callback instead of the built in filter in needBroadphaseCollision
295		btOverlapFilterCallback* m_overlapFilterCallback;
296
297		btOverlappingPairCallback*	m_ghostPairCallback;
298
299	public:
300
301		btSortedOverlappingPairCache();
302		virtual ~btSortedOverlappingPairCache();
303
304		virtual void	processAllOverlappingPairs(btOverlapCallback*,btDispatcher* dispatcher);
305
306		void*	removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,btDispatcher* dispatcher);
307
308		void	cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher);
309
310		btBroadphasePair*	addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
311
312		btBroadphasePair*	findPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
313
314
315		void	cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
316
317		void	removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
318
319
320		inline bool needsBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const
321		{
322			if (m_overlapFilterCallback)
323				return m_overlapFilterCallback->needBroadphaseCollision(proxy0,proxy1);
324
325			bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
326			collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
327
328			return collides;
329		}
330
331		btBroadphasePairArray&	getOverlappingPairArray()
332		{
333			return m_overlappingPairArray;
334		}
335
336		const btBroadphasePairArray&	getOverlappingPairArray() const
337		{
338			return m_overlappingPairArray;
339		}
340
341
342
343
344		btBroadphasePair*	getOverlappingPairArrayPtr()
345		{
346			return &m_overlappingPairArray[0];
347		}
348
349		const btBroadphasePair*	getOverlappingPairArrayPtr() const
350		{
351			return &m_overlappingPairArray[0];
352		}
353
354		int	getNumOverlappingPairs() const
355		{
356			return m_overlappingPairArray.size();
357		}
358
359		btOverlapFilterCallback* getOverlapFilterCallback()
360		{
361			return m_overlapFilterCallback;
362		}
363
364		void setOverlapFilterCallback(btOverlapFilterCallback* callback)
365		{
366			m_overlapFilterCallback = callback;
367		}
368
369		virtual bool	hasDeferredRemoval()
370		{
371			return m_hasDeferredRemoval;
372		}
373
374		virtual	void	setInternalGhostPairCallback(btOverlappingPairCallback* ghostPairCallback)
375		{
376			m_ghostPairCallback = ghostPairCallback;
377		}
378
379		virtual void	sortOverlappingPairs(btDispatcher* dispatcher);
380
381
382};
383
384
385
386///btNullPairCache skips add/removal of overlapping pairs. Userful for benchmarking and unit testing.
387class btNullPairCache : public btOverlappingPairCache
388{
389
390	btBroadphasePairArray	m_overlappingPairArray;
391
392public:
393
394	virtual btBroadphasePair*	getOverlappingPairArrayPtr()
395	{
396		return &m_overlappingPairArray[0];
397	}
398	const btBroadphasePair*	getOverlappingPairArrayPtr() const
399	{
400		return &m_overlappingPairArray[0];
401	}
402	btBroadphasePairArray&	getOverlappingPairArray()
403	{
404		return m_overlappingPairArray;
405	}
406
407	virtual	void	cleanOverlappingPair(btBroadphasePair& /*pair*/,btDispatcher* /*dispatcher*/)
408	{
409
410	}
411
412	virtual int getNumOverlappingPairs() const
413	{
414		return 0;
415	}
416
417	virtual void	cleanProxyFromPairs(btBroadphaseProxy* /*proxy*/,btDispatcher* /*dispatcher*/)
418	{
419
420	}
421
422	virtual	void setOverlapFilterCallback(btOverlapFilterCallback* /*callback*/)
423	{
424	}
425
426	virtual void	processAllOverlappingPairs(btOverlapCallback*,btDispatcher* /*dispatcher*/)
427	{
428	}
429
430	virtual btBroadphasePair* findPair(btBroadphaseProxy* /*proxy0*/, btBroadphaseProxy* /*proxy1*/)
431	{
432		return 0;
433	}
434
435	virtual bool	hasDeferredRemoval()
436	{
437		return true;
438	}
439
440	virtual	void	setInternalGhostPairCallback(btOverlappingPairCallback* /* ghostPairCallback */)
441	{
442
443	}
444
445	virtual btBroadphasePair*	addOverlappingPair(btBroadphaseProxy* /*proxy0*/,btBroadphaseProxy* /*proxy1*/)
446	{
447		return 0;
448	}
449
450	virtual void*	removeOverlappingPair(btBroadphaseProxy* /*proxy0*/,btBroadphaseProxy* /*proxy1*/,btDispatcher* /*dispatcher*/)
451	{
452		return 0;
453	}
454
455	virtual void	removeOverlappingPairsContainingProxy(btBroadphaseProxy* /*proxy0*/,btDispatcher* /*dispatcher*/)
456	{
457	}
458
459	virtual void	sortOverlappingPairs(btDispatcher* dispatcher)
460	{
461        (void) dispatcher;
462	}
463
464
465};
466
467
468#endif //BT_OVERLAPPING_PAIR_CACHE_H
469
470
471