Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/bullet/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp @ 2755

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

Merged presentation branch back to trunk.

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