Bullet Collision Detection & Physics Library
btCollisionDispatcher.cpp
Go to the documentation of this file.
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
4 
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose,
8 including commercial applications, and to alter it and redistribute it freely,
9 subject to the following restrictions:
10 
11 1. 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.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
14 */
15 
16 
17 
18 #include "btCollisionDispatcher.h"
19 #include "LinearMath/btQuickprof.h"
20 
22 
29 
30 #ifdef BT_DEBUG
31 #include <stdio.h>
32 #endif
33 
34 
36 m_dispatcherFlags(btCollisionDispatcher::CD_USE_RELATIVE_CONTACT_BREAKING_THRESHOLD),
37  m_collisionConfiguration(collisionConfiguration)
38 {
39  int i;
40 
42 
44 
46 
47  for (i=0;i<MAX_BROADPHASE_COLLISION_TYPES;i++)
48  {
49  for (int j=0;j<MAX_BROADPHASE_COLLISION_TYPES;j++)
50  {
54 
55  }
56  }
57 
58 
59 }
60 
61 
63 {
64  m_doubleDispatchContactPoints[proxyType0][proxyType1] = createFunc;
65 }
66 
68 {
69  m_doubleDispatchClosestPoints[proxyType0][proxyType1] = createFunc;
70 }
71 
73 {
74 }
75 
77 {
78  //btAssert(gNumManifold < 65535);
79 
80 
81 
82  //optional relative contact breaking threshold, turned on by default (use setDispatcherFlags to switch off feature for improved performance)
83 
87 
88  btScalar contactProcessingThreshold = btMin(body0->getContactProcessingThreshold(),body1->getContactProcessingThreshold());
89 
91  if (NULL == mem)
92  {
93  //we got a pool memory overflow, by default we fallback to dynamically allocate memory. If we require a contiguous contact pool then assert.
95  {
96  mem = btAlignedAlloc(sizeof(btPersistentManifold),16);
97  } else
98  {
99  btAssert(0);
100  //make sure to increase the m_defaultMaxPersistentManifoldPoolSize in the btDefaultCollisionConstructionInfo/btDefaultCollisionConfiguration
101  return 0;
102  }
103  }
104  btPersistentManifold* manifold = new(mem) btPersistentManifold (body0,body1,0,contactBreakingThreshold,contactProcessingThreshold);
105  manifold->m_index1a = m_manifoldsPtr.size();
106  m_manifoldsPtr.push_back(manifold);
107 
108  return manifold;
109 }
110 
112 {
113  manifold->clearManifold();
114 }
115 
116 
118 {
119 
120 
121  //printf("releaseManifold: gNumManifold %d\n",gNumManifold);
122  clearManifold(manifold);
123 
124  int findIndex = manifold->m_index1a;
125  btAssert(findIndex < m_manifoldsPtr.size());
126  m_manifoldsPtr.swap(findIndex,m_manifoldsPtr.size()-1);
127  m_manifoldsPtr[findIndex]->m_index1a = findIndex;
129 
130  manifold->~btPersistentManifold();
132  {
134  } else
135  {
136  btAlignedFree(manifold);
137  }
138 
139 }
140 
141 
142 
143 
145 {
146 
148 
149  ci.m_dispatcher1 = this;
150  ci.m_manifold = sharedManifold;
151  btCollisionAlgorithm* algo = 0;
152  if (algoType == BT_CONTACT_POINT_ALGORITHMS)
153  {
154  algo = m_doubleDispatchContactPoints[body0Wrap->getCollisionShape()->getShapeType()][body1Wrap->getCollisionShape()->getShapeType()]->CreateCollisionAlgorithm(ci, body0Wrap, body1Wrap);
155  }
156  else
157  {
158  algo = m_doubleDispatchClosestPoints[body0Wrap->getCollisionShape()->getShapeType()][body1Wrap->getCollisionShape()->getShapeType()]->CreateCollisionAlgorithm(ci, body0Wrap, body1Wrap);
159  }
160 
161  return algo;
162 }
163 
164 
165 
166 
168 {
169  //here you can do filtering
170  bool hasResponse =
171  (body0->hasContactResponse() && body1->hasContactResponse());
172  //no response between two static/kinematic bodies:
173  hasResponse = hasResponse &&
174  ((!body0->isStaticOrKinematicObject()) ||(! body1->isStaticOrKinematicObject()));
175  return hasResponse;
176 }
177 
179 {
180  btAssert(body0);
181  btAssert(body1);
182 
183  bool needsCollision = true;
184 
185 #ifdef BT_DEBUG
187  {
188  //broadphase filtering already deals with this
189  if (body0->isStaticOrKinematicObject() && body1->isStaticOrKinematicObject())
190  {
192  printf("warning btCollisionDispatcher::needsCollision: static-static collision!\n");
193  }
194  }
195 #endif //BT_DEBUG
196 
197  if ((!body0->isActive()) && (!body1->isActive()))
198  needsCollision = false;
199  else if ((!body0->checkCollideWith(body1)) || (!body1->checkCollideWith(body0)))
200  needsCollision = false;
201 
202  return needsCollision ;
203 
204 }
205 
206 
207 
211 {
214 
215 public:
216 
218  :m_dispatchInfo(dispatchInfo),
219  m_dispatcher(dispatcher)
220  {
221  }
222 
223  /*btCollisionPairCallback& operator=(btCollisionPairCallback& other)
224  {
225  m_dispatchInfo = other.m_dispatchInfo;
226  m_dispatcher = other.m_dispatcher;
227  return *this;
228  }
229  */
230 
231 
233 
234 
235  virtual bool processOverlap(btBroadphasePair& pair)
236  {
237  (*m_dispatcher->getNearCallback())(pair,*m_dispatcher,m_dispatchInfo);
238  return false;
239  }
240 };
241 
242 
243 
244 
246 {
247  //m_blockedForChanges = true;
248 
249  btCollisionPairCallback collisionCallback(dispatchInfo,this);
250 
251  {
252  BT_PROFILE("processAllOverlappingPairs");
253  pairCache->processAllOverlappingPairs(&collisionCallback,dispatcher, dispatchInfo);
254  }
255 
256  //m_blockedForChanges = false;
257 
258 }
259 
260 
261 
262 //by default, Bullet will use this near callback
264 {
265  btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject;
266  btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject;
267 
268  if (dispatcher.needsCollision(colObj0,colObj1))
269  {
270  btCollisionObjectWrapper obj0Wrap(0,colObj0->getCollisionShape(),colObj0,colObj0->getWorldTransform(),-1,-1);
271  btCollisionObjectWrapper obj1Wrap(0,colObj1->getCollisionShape(),colObj1,colObj1->getWorldTransform(),-1,-1);
272 
273 
274  //dispatcher will keep algorithms persistent in the collision pair
275  if (!collisionPair.m_algorithm)
276  {
277  collisionPair.m_algorithm = dispatcher.findAlgorithm(&obj0Wrap,&obj1Wrap,0, BT_CONTACT_POINT_ALGORITHMS);
278  }
279 
280  if (collisionPair.m_algorithm)
281  {
282  btManifoldResult contactPointResult(&obj0Wrap,&obj1Wrap);
283 
285  {
286  //discrete collision detection query
287 
288  collisionPair.m_algorithm->processCollision(&obj0Wrap,&obj1Wrap,dispatchInfo,&contactPointResult);
289  } else
290  {
291  //continuous collision detection query, time of impact (toi)
292  btScalar toi = collisionPair.m_algorithm->calculateTimeOfImpact(colObj0,colObj1,dispatchInfo,&contactPointResult);
293  if (dispatchInfo.m_timeOfImpact > toi)
294  dispatchInfo.m_timeOfImpact = toi;
295 
296  }
297  }
298  }
299 
300 }
301 
302 
304 {
305  void* mem = m_collisionAlgorithmPoolAllocator->allocate( size );
306  if (NULL == mem)
307  {
308  //warn user for overflow?
309  return btAlignedAlloc(static_cast<size_t>(size), 16);
310  }
311  return mem;
312 }
313 
315 {
317  {
319  } else
320  {
321  btAlignedFree(ptr);
322  }
323 }
virtual btScalar calculateTimeOfImpact(btCollisionObject *body0, btCollisionObject *body1, const btDispatcherInfo &dispatchInfo, btManifoldResult *resultOut)=0
btCollisionConfiguration * m_collisionConfiguration
virtual btPoolAllocator * getCollisionAlgorithmPool()=0
btPersistentManifold is a contact point cache, it stays persistent as long as objects are overlapping...
void push_back(const T &_Val)
int getShapeType() const
void registerCollisionCreateFunc(int proxyType0, int proxyType1, btCollisionAlgorithmCreateFunc *createFunc)
registerCollisionCreateFunc allows registration of custom/alternative collision create functions ...
btCollisionPairCallback(const btDispatcherInfo &dispatchInfo, btCollisionDispatcher *dispatcher)
virtual void processCollision(const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap, const btDispatcherInfo &dispatchInfo, btManifoldResult *resultOut)=0
virtual btCollisionAlgorithm * CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo &, const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
const btDispatcherInfo & m_dispatchInfo
#define btAssert(x)
Definition: btScalar.h:131
btCollisionConfiguration allows to configure Bullet collision detection stack allocator size...
btCollisionDispatcher supports algorithms that handle ConvexConvex and ConvexConcave collision pairs...
btCollisionAlgorithmCreateFunc * m_doubleDispatchClosestPoints[MAX_BROADPHASE_COLLISION_TYPES][MAX_BROADPHASE_COLLISION_TYPES]
btScalar getContactProcessingThreshold() const
virtual void freeCollisionAlgorithm(void *ptr)
btManifoldResult is a helper class to manage contact results.
bool validPtr(void *ptr)
void setNearCallback(btNearCallback nearCallback)
void swap(int index0, int index1)
bool hasContactResponse() const
virtual void releaseManifold(btPersistentManifold *manifold)
The btOverlappingPairCache provides an interface for overlapping pair management (add, remove, storage), used by the btBroadphaseInterface broadphases.
virtual bool needsCollision(const btCollisionObject *body0, const btCollisionObject *body1)
interface for iterating all overlapping collision pairs, no matter how those pairs are stored (array...
virtual btCollisionAlgorithmCreateFunc * getCollisionAlgorithmCreateFunc(int proxyType0, int proxyType1)=0
btTransform & getWorldTransform()
static void defaultNearCallback(btBroadphasePair &collisionPair, btCollisionDispatcher &dispatcher, const btDispatcherInfo &dispatchInfo)
int size() const
return the number of elements in the array
btScalar m_timeOfImpact
Definition: btDispatcher.h:57
virtual bool processOverlap(btBroadphasePair &pair)
btAlignedObjectArray< btPersistentManifold * > m_manifoldsPtr
virtual btScalar getContactBreakingThreshold(btScalar defaultContactThresholdFactor) const
Used by the btCollisionDispatcher to register and create instances for btCollisionAlgorithm.
bool isStaticOrKinematicObject() const
bool checkCollideWith(const btCollisionObject *co) const
#define btAlignedFree(ptr)
btCollisionObject can be used to manage collision detection objects.
virtual void clearManifold(btPersistentManifold *manifold)
virtual btPersistentManifold * getNewManifold(const btCollisionObject *b0, const btCollisionObject *b1)
btBroadphaseProxy * m_pProxy1
btCollisionAlgorithm * m_algorithm
const btCollisionShape * getCollisionShape() const
btBroadphaseProxy * m_pProxy0
#define BT_PROFILE(name)
Definition: btQuickprof.h:216
btCollisionDispatcher(btCollisionConfiguration *collisionConfiguration)
btCollisionDispatcher * m_dispatcher
virtual btPoolAllocator * getPersistentManifoldPool()=0
memory pools
void * allocate(int size)
btCollisionAlgorithmCreateFunc * m_doubleDispatchContactPoints[MAX_BROADPHASE_COLLISION_TYPES][MAX_BROADPHASE_COLLISION_TYPES]
virtual void dispatchAllCollisionPairs(btOverlappingPairCache *pairCache, const btDispatcherInfo &dispatchInfo, btDispatcher *dispatcher)
btPoolAllocator * m_collisionAlgorithmPoolAllocator
virtual bool needsResponse(const btCollisionObject *body0, const btCollisionObject *body1)
#define btAlignedAlloc(size, alignment)
virtual void * allocateCollisionAlgorithm(int size)
virtual btCollisionAlgorithmCreateFunc * getClosestPointsAlgorithmCreateFunc(int proxyType0, int proxyType1)=0
void freeMemory(void *ptr)
btNearCallback getNearCallback() const
The btDispatcher interface class can be used in combination with broadphase to dispatch calculations ...
Definition: btDispatcher.h:77
const T & btMin(const T &a, const T &b)
Definition: btMinMax.h:23
btCollisionAlgorithm is an collision interface that is compatible with the Broadphase and btDispatche...
const btCollisionShape * getCollisionShape() const
btPoolAllocator * m_persistentManifoldPoolAllocator
virtual void processAllOverlappingPairs(btOverlapCallback *, btDispatcher *dispatcher)=0
btScalar gContactBreakingThreshold
btCollisionAlgorithm * findAlgorithm(const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap, btPersistentManifold *sharedManifold, ebtDispatcherQueryType queryType)
ebtDispatcherQueryType
Definition: btDispatcher.h:69
void registerClosestPointsCreateFunc(int proxyType0, int proxyType1, btCollisionAlgorithmCreateFunc *createFunc)
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:292
bool isActive() const
The btBroadphasePair class contains a pair of aabb-overlapping objects.