Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/kicklib/src/external/bullet/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp @ 8740

Last change on this file since 8740 was 7983, checked in by rgrieder, 14 years ago

Updated Bullet Physics Engine from v2.74 to v2.77

  • Property svn:eol-style set to native
File size: 9.3 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#include "btSimpleBroadphase.h"
17#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
18#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
19
20#include "LinearMath/btVector3.h"
21#include "LinearMath/btTransform.h"
22#include "LinearMath/btMatrix3x3.h"
23#include "LinearMath/btAabbUtil2.h"
24
25#include <new>
26
27extern int gOverlappingPairs;
28
29void    btSimpleBroadphase::validate()
30{
31        for (int i=0;i<m_numHandles;i++)
32        {
33                for (int j=i+1;j<m_numHandles;j++)
34                {
35                        btAssert(&m_pHandles[i] != &m_pHandles[j]);
36                }
37        }
38       
39}
40
41btSimpleBroadphase::btSimpleBroadphase(int maxProxies, btOverlappingPairCache* overlappingPairCache)
42        :m_pairCache(overlappingPairCache),
43        m_ownsPairCache(false),
44        m_invalidPair(0)
45{
46
47        if (!overlappingPairCache)
48        {
49                void* mem = btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16);
50                m_pairCache = new (mem)btHashedOverlappingPairCache();
51                m_ownsPairCache = true;
52        }
53
54        // allocate handles buffer and put all handles on free list
55        m_pHandlesRawPtr = btAlignedAlloc(sizeof(btSimpleBroadphaseProxy)*maxProxies,16);
56        m_pHandles = new(m_pHandlesRawPtr) btSimpleBroadphaseProxy[maxProxies];
57        m_maxHandles = maxProxies;
58        m_numHandles = 0;
59        m_firstFreeHandle = 0;
60        m_LastHandleIndex = -1;
61       
62
63        {
64                for (int i = m_firstFreeHandle; i < maxProxies; i++)
65                {
66                        m_pHandles[i].SetNextFree(i + 1);
67                        m_pHandles[i].m_uniqueId = i+2;//any UID will do, we just avoid too trivial values (0,1) for debugging purposes
68                }
69                m_pHandles[maxProxies - 1].SetNextFree(0);
70       
71        }
72
73}
74
75btSimpleBroadphase::~btSimpleBroadphase()
76{
77        btAlignedFree(m_pHandlesRawPtr);
78
79        if (m_ownsPairCache)
80        {
81                m_pairCache->~btOverlappingPairCache();
82                btAlignedFree(m_pairCache);
83        }
84}
85
86
87btBroadphaseProxy*      btSimpleBroadphase::createProxy(  const btVector3& aabbMin,  const btVector3& aabbMax,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* /*dispatcher*/,void* multiSapProxy)
88{
89        if (m_numHandles >= m_maxHandles)
90        {
91                btAssert(0);
92                return 0; //should never happen, but don't let the game crash ;-)
93        }
94        btAssert(aabbMin[0]<= aabbMax[0] && aabbMin[1]<= aabbMax[1] && aabbMin[2]<= aabbMax[2]);
95
96        int newHandleIndex = allocHandle();
97        btSimpleBroadphaseProxy* proxy = new (&m_pHandles[newHandleIndex])btSimpleBroadphaseProxy(aabbMin,aabbMax,shapeType,userPtr,collisionFilterGroup,collisionFilterMask,multiSapProxy);
98
99        return proxy;
100}
101
102class   RemovingOverlapCallback : public btOverlapCallback
103{
104protected:
105        virtual bool    processOverlap(btBroadphasePair& pair)
106        {
107                (void)pair;
108                btAssert(0);
109                return false;
110        }
111};
112
113class RemovePairContainingProxy
114{
115
116        btBroadphaseProxy*      m_targetProxy;
117        public:
118        virtual ~RemovePairContainingProxy()
119        {
120        }
121protected:
122        virtual bool processOverlap(btBroadphasePair& pair)
123        {
124                btSimpleBroadphaseProxy* proxy0 = static_cast<btSimpleBroadphaseProxy*>(pair.m_pProxy0);
125                btSimpleBroadphaseProxy* proxy1 = static_cast<btSimpleBroadphaseProxy*>(pair.m_pProxy1);
126
127                return ((m_targetProxy == proxy0 || m_targetProxy == proxy1));
128        };
129};
130
131void    btSimpleBroadphase::destroyProxy(btBroadphaseProxy* proxyOrg,btDispatcher* dispatcher)
132{
133               
134                btSimpleBroadphaseProxy* proxy0 = static_cast<btSimpleBroadphaseProxy*>(proxyOrg);
135                freeHandle(proxy0);
136
137                m_pairCache->removeOverlappingPairsContainingProxy(proxyOrg,dispatcher);
138
139                //validate();
140               
141}
142
143void    btSimpleBroadphase::getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const
144{
145        const btSimpleBroadphaseProxy* sbp = getSimpleProxyFromProxy(proxy);
146        aabbMin = sbp->m_aabbMin;
147        aabbMax = sbp->m_aabbMax;
148}
149
150void    btSimpleBroadphase::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* /*dispatcher*/)
151{
152        btSimpleBroadphaseProxy* sbp = getSimpleProxyFromProxy(proxy);
153        sbp->m_aabbMin = aabbMin;
154        sbp->m_aabbMax = aabbMax;
155}
156
157void    btSimpleBroadphase::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin,const btVector3& aabbMax)
158{
159        for (int i=0; i <= m_LastHandleIndex; i++)
160        {
161                btSimpleBroadphaseProxy* proxy = &m_pHandles[i];
162                if(!proxy->m_clientObject)
163                {
164                        continue;
165                }
166                rayCallback.process(proxy);
167        }
168}
169
170
171void    btSimpleBroadphase::aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback)
172{
173        for (int i=0; i <= m_LastHandleIndex; i++)
174        {
175                btSimpleBroadphaseProxy* proxy = &m_pHandles[i];
176                if(!proxy->m_clientObject)
177                {
178                        continue;
179                }
180                if (TestAabbAgainstAabb2(aabbMin,aabbMax,proxy->m_aabbMin,proxy->m_aabbMax))
181                {
182                        callback.process(proxy);
183                }
184        }
185}
186
187
188
189       
190
191
192
193bool    btSimpleBroadphase::aabbOverlap(btSimpleBroadphaseProxy* proxy0,btSimpleBroadphaseProxy* proxy1)
194{
195        return proxy0->m_aabbMin[0] <= proxy1->m_aabbMax[0] && proxy1->m_aabbMin[0] <= proxy0->m_aabbMax[0] && 
196                   proxy0->m_aabbMin[1] <= proxy1->m_aabbMax[1] && proxy1->m_aabbMin[1] <= proxy0->m_aabbMax[1] &&
197                   proxy0->m_aabbMin[2] <= proxy1->m_aabbMax[2] && proxy1->m_aabbMin[2] <= proxy0->m_aabbMax[2];
198
199}
200
201
202
203//then remove non-overlapping ones
204class CheckOverlapCallback : public btOverlapCallback
205{
206public:
207        virtual bool processOverlap(btBroadphasePair& pair)
208        {
209                return (!btSimpleBroadphase::aabbOverlap(static_cast<btSimpleBroadphaseProxy*>(pair.m_pProxy0),static_cast<btSimpleBroadphaseProxy*>(pair.m_pProxy1)));
210        }
211};
212
213void    btSimpleBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher)
214{
215        //first check for new overlapping pairs
216        int i,j;
217        if (m_numHandles >= 0)
218        {
219                int new_largest_index = -1;
220                for (i=0; i <= m_LastHandleIndex; i++)
221                {
222                        btSimpleBroadphaseProxy* proxy0 = &m_pHandles[i];
223                        if(!proxy0->m_clientObject)
224                        {
225                                continue;
226                        }
227                        new_largest_index = i;
228                        for (j=i+1; j <= m_LastHandleIndex; j++)
229                        {
230                                btSimpleBroadphaseProxy* proxy1 = &m_pHandles[j];
231                                btAssert(proxy0 != proxy1);
232                                if(!proxy1->m_clientObject)
233                                {
234                                        continue;
235                                }
236
237                                btSimpleBroadphaseProxy* p0 = getSimpleProxyFromProxy(proxy0);
238                                btSimpleBroadphaseProxy* p1 = getSimpleProxyFromProxy(proxy1);
239
240                                if (aabbOverlap(p0,p1))
241                                {
242                                        if ( !m_pairCache->findPair(proxy0,proxy1))
243                                        {
244                                                m_pairCache->addOverlappingPair(proxy0,proxy1);
245                                        }
246                                } else
247                                {
248                                        if (!m_pairCache->hasDeferredRemoval())
249                                        {
250                                                if ( m_pairCache->findPair(proxy0,proxy1))
251                                                {
252                                                        m_pairCache->removeOverlappingPair(proxy0,proxy1,dispatcher);
253                                                }
254                                        }
255                                }
256                        }
257                }
258
259                m_LastHandleIndex = new_largest_index;
260
261                if (m_ownsPairCache && m_pairCache->hasDeferredRemoval())
262                {
263
264                        btBroadphasePairArray&  overlappingPairArray = m_pairCache->getOverlappingPairArray();
265
266                        //perform a sort, to find duplicates and to sort 'invalid' pairs to the end
267                        overlappingPairArray.quickSort(btBroadphasePairSortPredicate());
268
269                        overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair);
270                        m_invalidPair = 0;
271
272
273                        btBroadphasePair previousPair;
274                        previousPair.m_pProxy0 = 0;
275                        previousPair.m_pProxy1 = 0;
276                        previousPair.m_algorithm = 0;
277
278
279                        for (i=0;i<overlappingPairArray.size();i++)
280                        {
281
282                                btBroadphasePair& pair = overlappingPairArray[i];
283
284                                bool isDuplicate = (pair == previousPair);
285
286                                previousPair = pair;
287
288                                bool needsRemoval = false;
289
290                                if (!isDuplicate)
291                                {
292                                        bool hasOverlap = testAabbOverlap(pair.m_pProxy0,pair.m_pProxy1);
293
294                                        if (hasOverlap)
295                                        {
296                                                needsRemoval = false;//callback->processOverlap(pair);
297                                        } else
298                                        {
299                                                needsRemoval = true;
300                                        }
301                                } else
302                                {
303                                        //remove duplicate
304                                        needsRemoval = true;
305                                        //should have no algorithm
306                                        btAssert(!pair.m_algorithm);
307                                }
308
309                                if (needsRemoval)
310                                {
311                                        m_pairCache->cleanOverlappingPair(pair,dispatcher);
312
313                                        //              m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1);
314                                        //              m_overlappingPairArray.pop_back();
315                                        pair.m_pProxy0 = 0;
316                                        pair.m_pProxy1 = 0;
317                                        m_invalidPair++;
318                                        gOverlappingPairs--;
319                                } 
320
321                        }
322
323                        ///if you don't like to skip the invalid pairs in the array, execute following code:
324#define CLEAN_INVALID_PAIRS 1
325#ifdef CLEAN_INVALID_PAIRS
326
327                        //perform a sort, to sort 'invalid' pairs to the end
328                        overlappingPairArray.quickSort(btBroadphasePairSortPredicate());
329
330                        overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair);
331                        m_invalidPair = 0;
332#endif//CLEAN_INVALID_PAIRS
333
334                }
335        }
336}
337
338
339bool btSimpleBroadphase::testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
340{
341        btSimpleBroadphaseProxy* p0 = getSimpleProxyFromProxy(proxy0);
342        btSimpleBroadphaseProxy* p1 = getSimpleProxyFromProxy(proxy1);
343        return aabbOverlap(p0,p1);
344}
345
346void    btSimpleBroadphase::resetPool(btDispatcher* dispatcher)
347{
348        //not yet
349}
Note: See TracBrowser for help on using the repository browser.