Bullet Collision Detection & Physics Library
btCompoundCompoundCollisionAlgorithm.cpp
Go to the documentation of this file.
1/*
2Bullet Continuous Collision Detection and Physics Library
3Copyright (c) 2003-2013 Erwin Coumans http://bulletphysics.org
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
26
27//USE_LOCAL_STACK will avoid most (often all) dynamic memory allocations due to resizing in processCollision and MycollideTT
28#define USE_LOCAL_STACK 1
29
31
33 : btCompoundCollisionAlgorithm(ci, body0Wrap, body1Wrap, isSwapped)
34{
35 void* ptr = btAlignedAlloc(sizeof(btHashedSimplePairCache), 16);
37
38 const btCollisionObjectWrapper* col0ObjWrap = body0Wrap;
39 btAssert(col0ObjWrap->getCollisionShape()->isCompound());
40
41 const btCollisionObjectWrapper* col1ObjWrap = body1Wrap;
42 btAssert(col1ObjWrap->getCollisionShape()->isCompound());
43
44 const btCompoundShape* compoundShape0 = static_cast<const btCompoundShape*>(col0ObjWrap->getCollisionShape());
46
47 const btCompoundShape* compoundShape1 = static_cast<const btCompoundShape*>(col1ObjWrap->getCollisionShape());
49}
50
52{
56}
57
59{
60 int i;
62 for (i = 0; i < pairs.size(); i++)
63 {
64 if (pairs[i].m_userPointer)
65 {
66 ((btCollisionAlgorithm*)pairs[i].m_userPointer)->getAllContactManifolds(manifoldArray);
67 }
68 }
69}
70
72{
74
75 int numChildren = pairs.size();
76 int i;
77 for (i = 0; i < numChildren; i++)
78 {
79 if (pairs[i].m_userPointer)
80 {
84 }
85 }
87}
88
90{
92
98
100
102
111 {
112 }
113
115 {
116 BT_PROFILE("btCompoundCompoundLeafCallback::Process");
118
119 int childIndex0 = leaf0->dataAsInt;
120 int childIndex1 = leaf1->dataAsInt;
121
122 btAssert(childIndex0 >= 0);
123 btAssert(childIndex1 >= 0);
124
126 btAssert(childIndex0 < compoundShape0->getNumChildShapes());
127
129 btAssert(childIndex1 < compoundShape1->getNumChildShapes());
130
133
134 //backup
136 const btTransform& childTrans0 = compoundShape0->getChildTransform(childIndex0);
138
140 const btTransform& childTrans1 = compoundShape1->getChildTransform(childIndex1);
142
143 //perform an AABB check first
147
149
152
154 {
156 return;
157 }
158
160 {
163
165 bool removePair = false;
168 {
170 removePair = true;
171 }
172 else
173 {
174 if (pair)
175 {
176 colAlgo = (btCollisionAlgorithm*)pair->m_userPointer;
177 }
178 else
179 {
182 btAssert(pair);
183 pair->m_userPointer = colAlgo;
184 }
185 }
186
188
191
194
197
200
202
205
206 if (removePair)
207 {
208 colAlgo->~btCollisionAlgorithm();
210 }
211 }
212 }
213};
214
216 const btDbvtAabbMm& b, const btTransform& xform, btScalar distanceThreshold)
217{
219 btTransformAabb(b.Mins(), b.Maxs(), 0.f, xform, newmin, newmax);
223 return Intersect(a, newb);
224}
225
226static inline void MycollideTT(const btDbvtNode* root0,
227 const btDbvtNode* root1,
228 const btTransform& xform,
230{
231 if (root0 && root1)
232 {
233 int depth = 1;
236#ifdef USE_LOCAL_STACK
239#else
241#endif
243 do
244 {
246 if (MyIntersect(p.a->volume, p.b->volume, xform, distanceThreshold))
247 {
248 if (depth > treshold)
249 {
250 stkStack.resize(stkStack.size() * 2);
251 treshold = stkStack.size() - 4;
252 }
253 if (p.a->isinternal())
254 {
255 if (p.b->isinternal())
256 {
257 stkStack[depth++] = btDbvt::sStkNN(p.a->childs[0], p.b->childs[0]);
258 stkStack[depth++] = btDbvt::sStkNN(p.a->childs[1], p.b->childs[0]);
259 stkStack[depth++] = btDbvt::sStkNN(p.a->childs[0], p.b->childs[1]);
260 stkStack[depth++] = btDbvt::sStkNN(p.a->childs[1], p.b->childs[1]);
261 }
262 else
263 {
264 stkStack[depth++] = btDbvt::sStkNN(p.a->childs[0], p.b);
265 stkStack[depth++] = btDbvt::sStkNN(p.a->childs[1], p.b);
266 }
267 }
268 else
269 {
270 if (p.b->isinternal())
271 {
272 stkStack[depth++] = btDbvt::sStkNN(p.a, p.b->childs[0]);
273 stkStack[depth++] = btDbvt::sStkNN(p.a, p.b->childs[1]);
274 }
275 else
276 {
277 callback->Process(p.a, p.b);
278 }
279 }
280 }
281 } while (depth);
282 }
283}
284
286{
287 const btCollisionObjectWrapper* col0ObjWrap = body0Wrap;
288 const btCollisionObjectWrapper* col1ObjWrap = body1Wrap;
289
290 btAssert(col0ObjWrap->getCollisionShape()->isCompound());
291 btAssert(col1ObjWrap->getCollisionShape()->isCompound());
292 const btCompoundShape* compoundShape0 = static_cast<const btCompoundShape*>(col0ObjWrap->getCollisionShape());
293 const btCompoundShape* compoundShape1 = static_cast<const btCompoundShape*>(col1ObjWrap->getCollisionShape());
294
295 const btDbvt* tree0 = compoundShape0->getDynamicAabbTree();
296 const btDbvt* tree1 = compoundShape1->getDynamicAabbTree();
297 if (!tree0 || !tree1)
298 {
300 }
303 if ((compoundShape0->getUpdateRevision() != m_compoundShapeRevision0) || (compoundShape1->getUpdateRevision() != m_compoundShapeRevision1))
304 {
307 m_compoundShapeRevision0 = compoundShape0->getUpdateRevision();
308 m_compoundShapeRevision1 = compoundShape1->getUpdateRevision();
309 }
310
314 {
315 int i;
317#ifdef USE_LOCAL_STACK
320#endif
322 for (i = 0; i < pairs.size(); i++)
323 {
324 if (pairs[i].m_userPointer)
325 {
328 for (int m = 0; m < manifoldArray.size(); m++)
329 {
330 if (manifoldArray[m]->getNumContacts())
331 {
332 resultOut->setPersistentManifold(manifoldArray[m]);
333 resultOut->refreshContactPoints();
334 resultOut->setPersistentManifold(0);
335 }
336 }
338 }
339 }
340 }
341
343
344 const btTransform xform = col0ObjWrap->getWorldTransform().inverse() * col1ObjWrap->getWorldTransform();
345 MycollideTT(tree0->m_root, tree1->m_root, xform, &callback, resultOut->m_closestPointDistanceThreshold);
346
347 //printf("#compound-compound child/leaf overlap =%d \r",callback.m_numOverlapPairs);
348
349 //remove non-overlapping child pairs
350
351 {
353
354 //iterate over all children, perform an AABB check inside ProcessChildShape
356
357 int i;
359
361
362 for (i = 0; i < pairs.size(); i++)
363 {
364 if (pairs[i].m_userPointer)
365 {
367
368 {
369 const btCollisionShape* childShape0 = 0;
370
372 childShape0 = compoundShape0->getChildShape(pairs[i].m_indexA);
373 const btTransform& childTrans0 = compoundShape0->getChildTransform(pairs[i].m_indexA);
374 newChildWorldTrans0 = col0ObjWrap->getWorldTransform() * childTrans0;
376 }
377 btVector3 thresholdVec(resultOut->m_closestPointDistanceThreshold, resultOut->m_closestPointDistanceThreshold, resultOut->m_closestPointDistanceThreshold);
380 {
381 const btCollisionShape* childShape1 = 0;
383
384 childShape1 = compoundShape1->getChildShape(pairs[i].m_indexB);
385 const btTransform& childTrans1 = compoundShape1->getChildTransform(pairs[i].m_indexB);
386 newChildWorldTrans1 = col1ObjWrap->getWorldTransform() * childTrans1;
388 }
389
392
394 {
395 algo->~btCollisionAlgorithm();
397 m_removePairs.push_back(btSimplePair(pairs[i].m_indexA, pairs[i].m_indexB));
398 }
399 }
400 }
401 for (int i = 0; i < m_removePairs.size(); i++)
402 {
404 }
406 }
407}
408
410{
411 btAssert(0);
412 return 0.f;
413}
bool TestAabbAgainstAabb2(const btVector3 &aabbMin1, const btVector3 &aabbMax1, const btVector3 &aabbMin2, const btVector3 &aabbMax2)
conservative test for overlap between two aabbs
Definition btAabbUtil2.h:43
void btTransformAabb(const btVector3 &halfExtents, btScalar margin, const btTransform &t, btVector3 &aabbMinOut, btVector3 &aabbMaxOut)
#define btAlignedFree(ptr)
#define btAlignedAlloc(size, alignment)
bool(* btShapePairCallback)(const btCollisionShape *pShape0, const btCollisionShape *pShape1)
btShapePairCallback gCompoundCompoundChildShapePairCallback
static DBVT_INLINE bool MyIntersect(const btDbvtAabbMm &a, const btDbvtAabbMm &b, const btTransform &xform, btScalar distanceThreshold)
static void MycollideTT(const btDbvtNode *root0, const btDbvtNode *root1, const btTransform &xform, btCompoundCompoundLeafCallback *callback, btScalar distanceThreshold)
DBVT_INLINE bool Intersect(const btDbvtAabbMm &a, const btDbvtAabbMm &b)
Definition btDbvt.h:621
#define DBVT_INLINE
Definition btDbvt.h:53
@ BT_CLOSEST_POINT_ALGORITHMS
@ BT_CONTACT_POINT_ALGORITHMS
const T & btMax(const T &a, const T &b)
Definition btMinMax.h:27
#define BT_PROFILE(name)
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition btScalar.h:314
#define ATTRIBUTE_ALIGNED16(a)
Definition btScalar.h:99
#define btAssert(x)
Definition btScalar.h:153
int size() const
return the number of elements in the array
void resize(int newsize, const T &fillData=T())
void clear()
clear the array, deallocated memory. Generally it is better to use array.resize(0),...
void push_back(const T &_Val)
void initializeFromBuffer(void *buffer, int size, int capacity)
btCollisionAlgorithm is an collision interface that is compatible with the Broadphase and btDispatche...
virtual void getAllContactManifolds(btManifoldArray &manifoldArray)=0
btCollisionObject can be used to manage collision detection objects.
The btCollisionShape class provides an interface for collision shapes that can be shared among btColl...
btCompoundCollisionAlgorithm supports collision between CompoundCollisionShapes and other collision s...
virtual void processCollision(const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap, const btDispatcherInfo &dispatchInfo, btManifoldResult *resultOut)
class btPersistentManifold * m_sharedManifold
class btHashedSimplePairCache * m_childCollisionAlgorithmCache
virtual void processCollision(const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap, const btDispatcherInfo &dispatchInfo, btManifoldResult *resultOut)
btScalar calculateTimeOfImpact(btCollisionObject *body0, btCollisionObject *body1, const btDispatcherInfo &dispatchInfo, btManifoldResult *resultOut)
btCompoundCompoundCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo &ci, const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap, bool isSwapped)
virtual void getAllContactManifolds(btManifoldArray &manifoldArray)
The btCompoundShape allows to store multiple other btCollisionShapes This allows for moving concave c...
int getUpdateRevision() const
The btDispatcher interface class can be used in combination with broadphase to dispatch calculations ...
virtual void freeCollisionAlgorithm(void *ptr)=0
virtual btCollisionAlgorithm * findAlgorithm(const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap, btPersistentManifold *sharedManifold, ebtDispatcherQueryType queryType)=0
btSimplePairArray & getOverlappingPairArray()
btSimplePair * findPair(int indexA, int indexB)
virtual btSimplePair * addOverlappingPair(int indexA, int indexB)
virtual void * removeOverlappingPair(int indexA, int indexB)
btManifoldResult is a helper class to manage contact results.
virtual void setShapeIdentifiersA(int partId0, int index0)
setShapeIdentifiersA/B provides experimental support for per-triangle material / custom material comb...
void setBody0Wrap(const btCollisionObjectWrapper *obj0Wrap)
const btCollisionObjectWrapper * getBody1Wrap() const
void setBody1Wrap(const btCollisionObjectWrapper *obj1Wrap)
virtual void setShapeIdentifiersB(int partId1, int index1)
btScalar m_closestPointDistanceThreshold
const btCollisionObjectWrapper * getBody0Wrap() const
btPersistentManifold is a contact point cache, it stays persistent as long as objects are overlapping...
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition btTransform.h:30
btTransform inverse() const
Return the inverse of this transform.
btVector3 can be used to represent 3D points and vectors.
Definition btVector3.h:82
const btCollisionShape * getCollisionShape() const
const btCollisionObject * getCollisionObject() const
const btTransform & getWorldTransform() const
void Process(const btDbvtNode *leaf0, const btDbvtNode *leaf1)
const btCollisionObjectWrapper * m_compound0ColObjWrap
btCompoundCompoundLeafCallback(const btCollisionObjectWrapper *compound1ObjWrap, const btCollisionObjectWrapper *compound0ObjWrap, btDispatcher *dispatcher, const btDispatcherInfo &dispatchInfo, btManifoldResult *resultOut, btHashedSimplePairCache *childAlgorithmsCache, btPersistentManifold *sharedManifold)
const btCollisionObjectWrapper * m_compound1ColObjWrap
class btHashedSimplePairCache * m_childCollisionAlgorithmCache
static btDbvtAabbMm FromMM(const btVector3 &mi, const btVector3 &mx)
Definition btDbvt.h:479
DBVT_INLINE const btVector3 & Mins() const
Definition btDbvt.h:137
DBVT_INLINE const btVector3 & Maxs() const
Definition btDbvt.h:138
DBVT_INLINE bool isinternal() const
Definition btDbvt.h:185
btDbvtNode * childs[2]
Definition btDbvt.h:187
btDbvtVolume volume
Definition btDbvt.h:182
const btDbvtNode * b
Definition btDbvt.h:234
const btDbvtNode * a
Definition btDbvt.h:233
The btDbvt class implements a fast dynamic bounding volume tree based on axis aligned bounding boxes ...
Definition btDbvt.h:229
@ DOUBLE_STACKSIZE
Definition btDbvt.h:298