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 int gNumManifold = 0;
31 
32 #ifdef BT_DEBUG
33 #include <stdio.h>
34 #endif
35 
36 
38 m_dispatcherFlags(btCollisionDispatcher::CD_USE_RELATIVE_CONTACT_BREAKING_THRESHOLD),
39  m_collisionConfiguration(collisionConfiguration)
40 {
41  int i;
42 
44 
46 
48 
49  for (i=0;i<MAX_BROADPHASE_COLLISION_TYPES;i++)
50  {
51  for (int j=0;j<MAX_BROADPHASE_COLLISION_TYPES;j++)
52  {
56 
57  }
58  }
59 
60 
61 }
62 
63 
65 {
66  m_doubleDispatchContactPoints[proxyType0][proxyType1] = createFunc;
67 }
68 
70 {
71  m_doubleDispatchClosestPoints[proxyType0][proxyType1] = createFunc;
72 }
73 
75 {
76 }
77 
79 {
80  gNumManifold++;
81 
82  //btAssert(gNumManifold < 65535);
83 
84 
85 
86  //optional relative contact breaking threshold, turned on by default (use setDispatcherFlags to switch off feature for improved performance)
87 
91 
92  btScalar contactProcessingThreshold = btMin(body0->getContactProcessingThreshold(),body1->getContactProcessingThreshold());
93 
95  if (NULL == mem)
96  {
97  //we got a pool memory overflow, by default we fallback to dynamically allocate memory. If we require a contiguous contact pool then assert.
99  {
100  mem = btAlignedAlloc(sizeof(btPersistentManifold),16);
101  } else
102  {
103  btAssert(0);
104  //make sure to increase the m_defaultMaxPersistentManifoldPoolSize in the btDefaultCollisionConstructionInfo/btDefaultCollisionConfiguration
105  return 0;
106  }
107  }
108  btPersistentManifold* manifold = new(mem) btPersistentManifold (body0,body1,0,contactBreakingThreshold,contactProcessingThreshold);
109  manifold->m_index1a = m_manifoldsPtr.size();
110  m_manifoldsPtr.push_back(manifold);
111 
112  return manifold;
113 }
114 
116 {
117  manifold->clearManifold();
118 }
119 
120 
122 {
123 
124  gNumManifold--;
125 
126  //printf("releaseManifold: gNumManifold %d\n",gNumManifold);
127  clearManifold(manifold);
128 
129  int findIndex = manifold->m_index1a;
130  btAssert(findIndex < m_manifoldsPtr.size());
131  m_manifoldsPtr.swap(findIndex,m_manifoldsPtr.size()-1);
132  m_manifoldsPtr[findIndex]->m_index1a = findIndex;
134 
135  manifold->~btPersistentManifold();
137  {
139  } else
140  {
141  btAlignedFree(manifold);
142  }
143 
144 }
145 
146 
147 
148 
150 {
151 
153 
154  ci.m_dispatcher1 = this;
155  ci.m_manifold = sharedManifold;
156  btCollisionAlgorithm* algo = 0;
157  if (algoType == BT_CONTACT_POINT_ALGORITHMS)
158  {
159  algo = m_doubleDispatchContactPoints[body0Wrap->getCollisionShape()->getShapeType()][body1Wrap->getCollisionShape()->getShapeType()]->CreateCollisionAlgorithm(ci, body0Wrap, body1Wrap);
160  }
161  else
162  {
163  algo = m_doubleDispatchClosestPoints[body0Wrap->getCollisionShape()->getShapeType()][body1Wrap->getCollisionShape()->getShapeType()]->CreateCollisionAlgorithm(ci, body0Wrap, body1Wrap);
164  }
165 
166  return algo;
167 }
168 
169 
170 
171 
173 {
174  //here you can do filtering
175  bool hasResponse =
176  (body0->hasContactResponse() && body1->hasContactResponse());
177  //no response between two static/kinematic bodies:
178  hasResponse = hasResponse &&
179  ((!body0->isStaticOrKinematicObject()) ||(! body1->isStaticOrKinematicObject()));
180  return hasResponse;
181 }
182 
184 {
185  btAssert(body0);
186  btAssert(body1);
187 
188  bool needsCollision = true;
189 
190 #ifdef BT_DEBUG
192  {
193  //broadphase filtering already deals with this
194  if (body0->isStaticOrKinematicObject() && body1->isStaticOrKinematicObject())
195  {
197  printf("warning btCollisionDispatcher::needsCollision: static-static collision!\n");
198  }
199  }
200 #endif //BT_DEBUG
201 
202  if ((!body0->isActive()) && (!body1->isActive()))
203  needsCollision = false;
204  else if ((!body0->checkCollideWith(body1)) || (!body1->checkCollideWith(body0)))
205  needsCollision = false;
206 
207  return needsCollision ;
208 
209 }
210 
211 
212 
216 {
219 
220 public:
221 
223  :m_dispatchInfo(dispatchInfo),
224  m_dispatcher(dispatcher)
225  {
226  }
227 
228  /*btCollisionPairCallback& operator=(btCollisionPairCallback& other)
229  {
230  m_dispatchInfo = other.m_dispatchInfo;
231  m_dispatcher = other.m_dispatcher;
232  return *this;
233  }
234  */
235 
236 
238 
239 
240  virtual bool processOverlap(btBroadphasePair& pair)
241  {
243  return false;
244  }
245 };
246 
247 
248 
250 {
251  //m_blockedForChanges = true;
252 
253  btCollisionPairCallback collisionCallback(dispatchInfo,this);
254 
255  pairCache->processAllOverlappingPairs(&collisionCallback,dispatcher);
256 
257  //m_blockedForChanges = false;
258 
259 }
260 
261 
262 
263 //by default, Bullet will use this near callback
265 {
266  btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject;
267  btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject;
268 
269  if (dispatcher.needsCollision(colObj0,colObj1))
270  {
271  btCollisionObjectWrapper obj0Wrap(0,colObj0->getCollisionShape(),colObj0,colObj0->getWorldTransform(),-1,-1);
272  btCollisionObjectWrapper obj1Wrap(0,colObj1->getCollisionShape(),colObj1,colObj1->getWorldTransform(),-1,-1);
273 
274 
275  //dispatcher will keep algorithms persistent in the collision pair
276  if (!collisionPair.m_algorithm)
277  {
278  collisionPair.m_algorithm = dispatcher.findAlgorithm(&obj0Wrap,&obj1Wrap,0, BT_CONTACT_POINT_ALGORITHMS);
279  }
280 
281  if (collisionPair.m_algorithm)
282  {
283  btManifoldResult contactPointResult(&obj0Wrap,&obj1Wrap);
284 
286  {
287  //discrete collision detection query
288 
289  collisionPair.m_algorithm->processCollision(&obj0Wrap,&obj1Wrap,dispatchInfo,&contactPointResult);
290  } else
291  {
292  //continuous collision detection query, time of impact (toi)
293  btScalar toi = collisionPair.m_algorithm->calculateTimeOfImpact(colObj0,colObj1,dispatchInfo,&contactPointResult);
294  if (dispatchInfo.m_timeOfImpact > toi)
295  dispatchInfo.m_timeOfImpact = toi;
296 
297  }
298  }
299  }
300 
301 }
302 
303 
305 {
307  if (NULL == mem)
308  {
309  //warn user for overflow?
310  return btAlignedAlloc(static_cast<size_t>(size), 16);
311  }
312  return mem;
313 }
314 
316 {
318  {
320  } else
321  {
322  btAlignedFree(ptr);
323  }
324 }
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)
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]
virtual void freeCollisionAlgorithm(void *ptr)
btManifoldResult is a helper class to manage contact results.
bool validPtr(void *ptr)
void setNearCallback(btNearCallback nearCallback)
btNearCallback getNearCallback() const
const btCollisionShape * getCollisionShape() const
bool isStaticOrKinematicObject() const
void swap(int index0, int index1)
bool checkCollideWith(const btCollisionObject *co) const
virtual void releaseManifold(btPersistentManifold *manifold)
The btOverlappingPairCache provides an interface for overlapping pair management (add,...
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)
btScalar m_timeOfImpact
Definition: btDispatcher.h:56
virtual bool processOverlap(btBroadphasePair &pair)
btAlignedObjectArray< btPersistentManifold * > m_manifoldsPtr
Used by the btCollisionDispatcher to register and create instances for btCollisionAlgorithm.
#define btAlignedFree(ptr)
btCollisionObject can be used to manage collision detection objects.
virtual void clearManifold(btPersistentManifold *manifold)
bool hasContactResponse() const
virtual btPersistentManifold * getNewManifold(const btCollisionObject *b0, const btCollisionObject *b1)
virtual btScalar getContactBreakingThreshold(btScalar defaultContactThresholdFactor) const
btBroadphaseProxy * m_pProxy1
btCollisionAlgorithm * m_algorithm
btScalar getContactProcessingThreshold() const
int size() const
return the number of elements in the array
btBroadphaseProxy * m_pProxy0
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)
int getShapeType() const
virtual void * allocateCollisionAlgorithm(int size)
virtual btCollisionAlgorithmCreateFunc * getClosestPointsAlgorithmCreateFunc(int proxyType0, int proxyType1)=0
void freeMemory(void *ptr)
The btDispatcher interface class can be used in combination with broadphase to dispatch calculations ...
Definition: btDispatcher.h:75
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...
btPoolAllocator * m_persistentManifoldPoolAllocator
virtual void processAllOverlappingPairs(btOverlapCallback *, btDispatcher *dispatcher)=0
btScalar gContactBreakingThreshold
btCollisionAlgorithm * findAlgorithm(const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap, btPersistentManifold *sharedManifold, ebtDispatcherQueryType queryType)
int gNumManifold
ebtDispatcherQueryType
Definition: btDispatcher.h:67
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
const btCollisionShape * getCollisionShape() const
The btBroadphasePair class contains a pair of aabb-overlapping objects.