Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp @ 1972

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

Downgraded Bullet to latest tagged version: 2.72
That should give us more stability.

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