Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp @ 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: 8.1 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
17
18#include "btCollisionDispatcher.h"
19
20
21#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
22
23#include "BulletCollision/CollisionShapes/btCollisionShape.h"
24#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
25#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
26#include "LinearMath/btPoolAllocator.h"
27#include "BulletCollision/CollisionDispatch/btCollisionConfiguration.h"
28
29int gNumManifold = 0;
30
31#ifdef BT_DEBUG
32#include <stdio.h>
33#endif
34
35
36btCollisionDispatcher::btCollisionDispatcher (btCollisionConfiguration* collisionConfiguration): 
37        m_count(0),
38        m_useIslands(true),
39        m_staticWarningReported(false),
40        m_collisionConfiguration(collisionConfiguration)
41{
42        int i;
43
44        setNearCallback(defaultNearCallback);
45       
46        m_collisionAlgorithmPoolAllocator = collisionConfiguration->getCollisionAlgorithmPool();
47
48        m_persistentManifoldPoolAllocator = collisionConfiguration->getPersistentManifoldPool();
49
50        for (i=0;i<MAX_BROADPHASE_COLLISION_TYPES;i++)
51        {
52                for (int j=0;j<MAX_BROADPHASE_COLLISION_TYPES;j++)
53                {
54                        m_doubleDispatch[i][j] = m_collisionConfiguration->getCollisionAlgorithmCreateFunc(i,j);
55                        assert(m_doubleDispatch[i][j]);
56                }
57        }
58       
59       
60};
61
62
63void btCollisionDispatcher::registerCollisionCreateFunc(int proxyType0, int proxyType1, btCollisionAlgorithmCreateFunc *createFunc)
64{
65        m_doubleDispatch[proxyType0][proxyType1] = createFunc;
66}
67
68btCollisionDispatcher::~btCollisionDispatcher()
69{
70}
71
72btPersistentManifold*   btCollisionDispatcher::getNewManifold(void* b0,void* b1) 
73{ 
74        gNumManifold++;
75       
76        //btAssert(gNumManifold < 65535);
77       
78
79        btCollisionObject* body0 = (btCollisionObject*)b0;
80        btCollisionObject* body1 = (btCollisionObject*)b1;
81       
82        void* mem = 0;
83       
84        if (m_persistentManifoldPoolAllocator->getFreeCount())
85        {
86                mem = m_persistentManifoldPoolAllocator->allocate(sizeof(btPersistentManifold));
87        } else
88        {
89                mem = btAlignedAlloc(sizeof(btPersistentManifold),16);
90
91        }
92        btPersistentManifold* manifold = new(mem) btPersistentManifold (body0,body1,0);
93        manifold->m_index1a = m_manifoldsPtr.size();
94        m_manifoldsPtr.push_back(manifold);
95
96        return manifold;
97}
98
99void btCollisionDispatcher::clearManifold(btPersistentManifold* manifold)
100{
101        manifold->clearManifold();
102}
103
104       
105void btCollisionDispatcher::releaseManifold(btPersistentManifold* manifold)
106{
107       
108        gNumManifold--;
109
110        //printf("releaseManifold: gNumManifold %d\n",gNumManifold);
111        clearManifold(manifold);
112
113        int findIndex = manifold->m_index1a;
114        btAssert(findIndex < m_manifoldsPtr.size());
115        m_manifoldsPtr.swap(findIndex,m_manifoldsPtr.size()-1);
116        m_manifoldsPtr[findIndex]->m_index1a = findIndex;
117        m_manifoldsPtr.pop_back();
118
119        manifold->~btPersistentManifold();
120        if (m_persistentManifoldPoolAllocator->validPtr(manifold))
121        {
122                m_persistentManifoldPoolAllocator->freeMemory(manifold);
123        } else
124        {
125                btAlignedFree(manifold);
126        }
127       
128}
129
130       
131
132btCollisionAlgorithm* btCollisionDispatcher::findAlgorithm(btCollisionObject* body0,btCollisionObject* body1,btPersistentManifold* sharedManifold)
133{
134       
135        btCollisionAlgorithmConstructionInfo ci;
136
137        ci.m_dispatcher1 = this;
138        ci.m_manifold = sharedManifold;
139        btCollisionAlgorithm* algo = m_doubleDispatch[body0->getCollisionShape()->getShapeType()][body1->getCollisionShape()->getShapeType()]->CreateCollisionAlgorithm(ci,body0,body1);
140
141        return algo;
142}
143
144
145
146
147
148bool    btCollisionDispatcher::needsResponse(btCollisionObject* body0,btCollisionObject* body1)
149{
150        //here you can do filtering
151        bool hasResponse = 
152                (body0->hasContactResponse() && body1->hasContactResponse());
153        //no response between two static/kinematic bodies:
154        hasResponse = hasResponse &&
155                ((!body0->isStaticOrKinematicObject()) ||(! body1->isStaticOrKinematicObject()));
156        return hasResponse;
157}
158
159bool    btCollisionDispatcher::needsCollision(btCollisionObject* body0,btCollisionObject* body1)
160{
161        assert(body0);
162        assert(body1);
163
164        bool needsCollision = true;
165
166#ifdef BT_DEBUG
167        if (!m_staticWarningReported)
168        {
169                //broadphase filtering already deals with this
170                if ((body0->isStaticObject() || body0->isKinematicObject()) &&
171                        (body1->isStaticObject() || body1->isKinematicObject()))
172                {
173                        m_staticWarningReported = true;
174                        printf("warning btCollisionDispatcher::needsCollision: static-static collision!\n");
175                }
176        }
177#endif //BT_DEBUG
178
179        if ((!body0->isActive()) && (!body1->isActive()))
180                needsCollision = false;
181        else if (!body0->checkCollideWith(body1))
182                needsCollision = false;
183       
184        return needsCollision ;
185
186}
187
188
189
190///interface for iterating all overlapping collision pairs, no matter how those pairs are stored (array, set, map etc)
191///this is useful for the collision dispatcher.
192class btCollisionPairCallback : public btOverlapCallback
193{
194        const btDispatcherInfo& m_dispatchInfo;
195        btCollisionDispatcher*  m_dispatcher;
196
197public:
198
199        btCollisionPairCallback(const btDispatcherInfo& dispatchInfo,btCollisionDispatcher*     dispatcher)
200        :m_dispatchInfo(dispatchInfo),
201        m_dispatcher(dispatcher)
202        {
203        }
204
205        /*btCollisionPairCallback& operator=(btCollisionPairCallback& other)
206        {
207                m_dispatchInfo = other.m_dispatchInfo;
208                m_dispatcher = other.m_dispatcher;
209                return *this;
210        }
211        */
212
213
214        virtual ~btCollisionPairCallback() {}
215
216
217        virtual bool    processOverlap(btBroadphasePair& pair)
218        {
219                (*m_dispatcher->getNearCallback())(pair,*m_dispatcher,m_dispatchInfo);
220
221                return false;
222        }
223};
224
225
226
227void    btCollisionDispatcher::dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,const btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher) 
228{
229        //m_blockedForChanges = true;
230
231        btCollisionPairCallback collisionCallback(dispatchInfo,this);
232
233        pairCache->processAllOverlappingPairs(&collisionCallback,dispatcher);
234
235        //m_blockedForChanges = false;
236
237}
238
239
240
241
242//by default, Bullet will use this near callback
243void btCollisionDispatcher::defaultNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo)
244{
245                btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject;
246                btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject;
247
248                if (dispatcher.needsCollision(colObj0,colObj1))
249                {
250                        //dispatcher will keep algorithms persistent in the collision pair
251                        if (!collisionPair.m_algorithm)
252                        {
253                                collisionPair.m_algorithm = dispatcher.findAlgorithm(colObj0,colObj1);
254                        }
255
256                        if (collisionPair.m_algorithm)
257                        {
258                                btManifoldResult contactPointResult(colObj0,colObj1);
259                               
260                                if (dispatchInfo.m_dispatchFunc ==              btDispatcherInfo::DISPATCH_DISCRETE)
261                                {
262                                        //discrete collision detection query
263                                        collisionPair.m_algorithm->processCollision(colObj0,colObj1,dispatchInfo,&contactPointResult);
264                                } else
265                                {
266                                        //continuous collision detection query, time of impact (toi)
267                                        btScalar toi = collisionPair.m_algorithm->calculateTimeOfImpact(colObj0,colObj1,dispatchInfo,&contactPointResult);
268                                        if (dispatchInfo.m_timeOfImpact > toi)
269                                                dispatchInfo.m_timeOfImpact = toi;
270
271                                }
272                        }
273                }
274
275}
276
277
278void* btCollisionDispatcher::allocateCollisionAlgorithm(int size)
279{
280        if (m_collisionAlgorithmPoolAllocator->getFreeCount())
281        {
282                return m_collisionAlgorithmPoolAllocator->allocate(size);
283        }
284       
285        //warn user for overflow?
286        return  btAlignedAlloc(static_cast<size_t>(size), 16);
287}
288
289void btCollisionDispatcher::freeCollisionAlgorithm(void* ptr)
290{
291        if (m_collisionAlgorithmPoolAllocator->validPtr(ptr))
292        {
293                m_collisionAlgorithmPoolAllocator->freeMemory(ptr);
294        } else
295        {
296                btAlignedFree(ptr);
297        }
298}
Note: See TracBrowser for help on using the repository browser.