Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h @ 1963

Last change on this file since 1963 was 1963, checked in by rgrieder, 16 years ago

Added Bullet physics engine.

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