Bullet Collision Detection & Physics Library
btCollisionWorld.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 #include "btCollisionWorld.h"
17 #include "btCollisionDispatcher.h"
22 #include "BulletCollision/CollisionShapes/btSphereShape.h" //for raycasting
32 #include "LinearMath/btAabbUtil2.h"
33 #include "LinearMath/btQuickprof.h"
37 
38 //#define DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION
39 
40 
41 //#define USE_BRUTEFORCE_RAYBROADPHASE 1
42 //RECALCULATE_AABB is slower, but benefit is that you don't need to call 'stepSimulation' or 'updateAabbs' before using a rayTest
43 //#define RECALCULATE_AABB_RAYCAST 1
44 
45 //When the user doesn't provide dispatcher or broadphase, create basic versions (and delete them in destructor)
49 
50 
52 
53 //for debug rendering
66 
67 
68 
70 :m_dispatcher1(dispatcher),
71 m_broadphasePairCache(pairCache),
72 m_debugDrawer(0),
73 m_forceUpdateAllAabbs(true)
74 {
75 }
76 
77 
79 {
80 
81  //clean up remaining objects
82  int i;
83  for (i=0;i<m_collisionObjects.size();i++)
84  {
85  btCollisionObject* collisionObject= m_collisionObjects[i];
86 
87  btBroadphaseProxy* bp = collisionObject->getBroadphaseHandle();
88  if (bp)
89  {
90  //
91  // only clear the cached algorithms
92  //
95  collisionObject->setBroadphaseHandle(0);
96  }
97  }
98 
99 
100 }
101 
102 
103 
104 
105 
106 
107 
108 
109 
110 
111 void btCollisionWorld::addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup,short int collisionFilterMask)
112 {
113 
114  btAssert(collisionObject);
115 
116  //check that the object isn't already added
118 
119  m_collisionObjects.push_back(collisionObject);
120 
121  //calculate new AABB
122  btTransform trans = collisionObject->getWorldTransform();
123 
124  btVector3 minAabb;
125  btVector3 maxAabb;
126  collisionObject->getCollisionShape()->getAabb(trans,minAabb,maxAabb);
127 
128  int type = collisionObject->getCollisionShape()->getShapeType();
129  collisionObject->setBroadphaseHandle( getBroadphase()->createProxy(
130  minAabb,
131  maxAabb,
132  type,
133  collisionObject,
134  collisionFilterGroup,
135  collisionFilterMask,
136  m_dispatcher1,0
137  )) ;
138 
139 
140 
141 
142 
143 }
144 
145 
146 
148 {
149  btVector3 minAabb,maxAabb;
150  colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);
151  //need to increase the aabb for contact thresholds
153  minAabb -= contactThreshold;
154  maxAabb += contactThreshold;
155 
156  if(getDispatchInfo().m_useContinuous && colObj->getInternalType()==btCollisionObject::CO_RIGID_BODY && !colObj->isStaticOrKinematicObject())
157  {
158  btVector3 minAabb2,maxAabb2;
159  colObj->getCollisionShape()->getAabb(colObj->getInterpolationWorldTransform(),minAabb2,maxAabb2);
160  minAabb2 -= contactThreshold;
161  maxAabb2 += contactThreshold;
162  minAabb.setMin(minAabb2);
163  maxAabb.setMax(maxAabb2);
164  }
165 
167 
168  //moving objects should be moderately sized, probably something wrong if not
169  if ( colObj->isStaticObject() || ((maxAabb-minAabb).length2() < btScalar(1e12)))
170  {
171  bp->setAabb(colObj->getBroadphaseHandle(),minAabb,maxAabb, m_dispatcher1);
172  } else
173  {
174  //something went wrong, investigate
175  //this assert is unwanted in 3D modelers (danger of loosing work)
177 
178  static bool reportMe = true;
179  if (reportMe && m_debugDrawer)
180  {
181  reportMe = false;
182  m_debugDrawer->reportErrorWarning("Overflow in AABB, object removed from simulation");
183  m_debugDrawer->reportErrorWarning("If you can reproduce this, please email bugs@continuousphysics.com\n");
184  m_debugDrawer->reportErrorWarning("Please include above information, your Platform, version of OS.\n");
185  m_debugDrawer->reportErrorWarning("Thanks.\n");
186  }
187  }
188 }
189 
191 {
192  BT_PROFILE("updateAabbs");
193 
194  btTransform predictedTrans;
195  for ( int i=0;i<m_collisionObjects.size();i++)
196  {
198 
199  //only update aabb of active objects
200  if (m_forceUpdateAllAabbs || colObj->isActive())
201  {
202  updateSingleAabb(colObj);
203  }
204  }
205 }
206 
207 
209 {
210  BT_PROFILE("calculateOverlappingPairs");
212 }
213 
215 {
216  BT_PROFILE("performDiscreteCollisionDetection");
217 
218  btDispatcherInfo& dispatchInfo = getDispatchInfo();
219 
220  updateAabbs();
221 
223 
224  btDispatcher* dispatcher = getDispatcher();
225  {
226  BT_PROFILE("dispatchAllCollisionPairs");
227  if (dispatcher)
229  }
230 
231 }
232 
233 
234 
236 {
237 
238 
239  //bool removeFromBroadphase = false;
240 
241  {
242 
243  btBroadphaseProxy* bp = collisionObject->getBroadphaseHandle();
244  if (bp)
245  {
246  //
247  // only clear the cached algorithms
248  //
251  collisionObject->setBroadphaseHandle(0);
252  }
253  }
254 
255 
256  //swapremove
257  m_collisionObjects.remove(collisionObject);
258 
259 }
260 
261 
262 void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans,
263  btCollisionObject* collisionObject,
264  const btCollisionShape* collisionShape,
265  const btTransform& colObjWorldTransform,
266  RayResultCallback& resultCallback)
267 {
268  btCollisionObjectWrapper colObWrap(0,collisionShape,collisionObject,colObjWorldTransform,-1,-1);
269  btCollisionWorld::rayTestSingleInternal(rayFromTrans,rayToTrans,&colObWrap,resultCallback);
270 }
271 
272 void btCollisionWorld::rayTestSingleInternal(const btTransform& rayFromTrans,const btTransform& rayToTrans,
273  const btCollisionObjectWrapper* collisionObjectWrap,
274  RayResultCallback& resultCallback)
275 {
276  btSphereShape pointShape(btScalar(0.0));
277  pointShape.setMargin(0.f);
278  const btConvexShape* castShape = &pointShape;
279  const btCollisionShape* collisionShape = collisionObjectWrap->getCollisionShape();
280  const btTransform& colObjWorldTransform = collisionObjectWrap->getWorldTransform();
281 
282  if (collisionShape->isConvex())
283  {
284  // BT_PROFILE("rayTestConvex");
285  btConvexCast::CastResult castResult;
286  castResult.m_fraction = resultCallback.m_closestHitFraction;
287 
288  btConvexShape* convexShape = (btConvexShape*) collisionShape;
289  btVoronoiSimplexSolver simplexSolver;
290  btSubsimplexConvexCast subSimplexConvexCaster(castShape,convexShape,&simplexSolver);
291 
292  btGjkConvexCast gjkConvexCaster(castShape,convexShape,&simplexSolver);
293 
294  //btContinuousConvexCollision convexCaster(castShape,convexShape,&simplexSolver,0);
295 
296  btConvexCast* convexCasterPtr = 0;
297  //use kF_UseSubSimplexConvexCastRaytest by default
299  convexCasterPtr = &gjkConvexCaster;
300  else
301  convexCasterPtr = &subSimplexConvexCaster;
302 
303  btConvexCast& convexCaster = *convexCasterPtr;
304 
305  if (convexCaster.calcTimeOfImpact(rayFromTrans,rayToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
306  {
307  //add hit
308  if (castResult.m_normal.length2() > btScalar(0.0001))
309  {
310  if (castResult.m_fraction < resultCallback.m_closestHitFraction)
311  {
312  //todo: figure out what this is about. When is rayFromTest.getBasis() not identity?
313 #ifdef USE_SUBSIMPLEX_CONVEX_CAST
314  //rotate normal into worldspace
315  castResult.m_normal = rayFromTrans.getBasis() * castResult.m_normal;
316 #endif //USE_SUBSIMPLEX_CONVEX_CAST
317 
318  castResult.m_normal.normalize();
319  btCollisionWorld::LocalRayResult localRayResult
320  (
321  collisionObjectWrap->getCollisionObject(),
322  0,
323  castResult.m_normal,
324  castResult.m_fraction
325  );
326 
327  bool normalInWorldSpace = true;
328  resultCallback.addSingleResult(localRayResult, normalInWorldSpace);
329 
330  }
331  }
332  }
333  } else {
334  if (collisionShape->isConcave())
335  {
336 
337  //ConvexCast::CastResult
338  struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback
339  {
340  btCollisionWorld::RayResultCallback* m_resultCallback;
341  const btCollisionObject* m_collisionObject;
342  const btConcaveShape* m_triangleMesh;
343 
344  btTransform m_colObjWorldTransform;
345 
346  BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,
347  btCollisionWorld::RayResultCallback* resultCallback, const btCollisionObject* collisionObject,const btConcaveShape* triangleMesh,const btTransform& colObjWorldTransform):
348  //@BP Mod
349  btTriangleRaycastCallback(from,to, resultCallback->m_flags),
350  m_resultCallback(resultCallback),
351  m_collisionObject(collisionObject),
352  m_triangleMesh(triangleMesh),
353  m_colObjWorldTransform(colObjWorldTransform)
354  {
355  }
356 
357 
358  virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex )
359  {
361  shapeInfo.m_shapePart = partId;
362  shapeInfo.m_triangleIndex = triangleIndex;
363 
364  btVector3 hitNormalWorld = m_colObjWorldTransform.getBasis() * hitNormalLocal;
365 
367  (m_collisionObject,
368  &shapeInfo,
369  hitNormalWorld,
370  hitFraction);
371 
372  bool normalInWorldSpace = true;
373  return m_resultCallback->addSingleResult(rayResult,normalInWorldSpace);
374  }
375 
376  };
377 
378  btTransform worldTocollisionObject = colObjWorldTransform.inverse();
379  btVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin();
380  btVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin();
381 
382  // BT_PROFILE("rayTestConcave");
383  if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE)
384  {
386  btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape;
387 
388  BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObjectWrap->getCollisionObject(),triangleMesh,colObjWorldTransform);
389  rcb.m_hitFraction = resultCallback.m_closestHitFraction;
390  triangleMesh->performRaycast(&rcb,rayFromLocal,rayToLocal);
391  }
392  else
393  {
394  //generic (slower) case
395  btConcaveShape* concaveShape = (btConcaveShape*)collisionShape;
396 
397  btTransform worldTocollisionObject = colObjWorldTransform.inverse();
398 
399  btVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin();
400  btVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin();
401 
402  //ConvexCast::CastResult
403 
404  struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback
405  {
406  btCollisionWorld::RayResultCallback* m_resultCallback;
407  const btCollisionObject* m_collisionObject;
408  btConcaveShape* m_triangleMesh;
409 
410  btTransform m_colObjWorldTransform;
411 
412  BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,
413  btCollisionWorld::RayResultCallback* resultCallback, const btCollisionObject* collisionObject,btConcaveShape* triangleMesh, const btTransform& colObjWorldTransform):
414  //@BP Mod
415  btTriangleRaycastCallback(from,to, resultCallback->m_flags),
416  m_resultCallback(resultCallback),
417  m_collisionObject(collisionObject),
418  m_triangleMesh(triangleMesh),
419  m_colObjWorldTransform(colObjWorldTransform)
420  {
421  }
422 
423 
424  virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex )
425  {
427  shapeInfo.m_shapePart = partId;
428  shapeInfo.m_triangleIndex = triangleIndex;
429 
430  btVector3 hitNormalWorld = m_colObjWorldTransform.getBasis() * hitNormalLocal;
431 
433  (m_collisionObject,
434  &shapeInfo,
435  hitNormalWorld,
436  hitFraction);
437 
438  bool normalInWorldSpace = true;
439  return m_resultCallback->addSingleResult(rayResult,normalInWorldSpace);
440  }
441 
442  };
443 
444 
445  BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObjectWrap->getCollisionObject(),concaveShape, colObjWorldTransform);
446  rcb.m_hitFraction = resultCallback.m_closestHitFraction;
447 
448  btVector3 rayAabbMinLocal = rayFromLocal;
449  rayAabbMinLocal.setMin(rayToLocal);
450  btVector3 rayAabbMaxLocal = rayFromLocal;
451  rayAabbMaxLocal.setMax(rayToLocal);
452 
453  concaveShape->processAllTriangles(&rcb,rayAabbMinLocal,rayAabbMaxLocal);
454  }
455  } else {
456  // BT_PROFILE("rayTestCompound");
457  if (collisionShape->isCompound())
458  {
459  struct LocalInfoAdder2 : public RayResultCallback
460  {
461  RayResultCallback* m_userCallback;
462  int m_i;
463 
464  LocalInfoAdder2 (int i, RayResultCallback *user)
465  : m_userCallback(user), m_i(i)
466  {
467  m_closestHitFraction = m_userCallback->m_closestHitFraction;
468  m_flags = m_userCallback->m_flags;
469  }
470  virtual bool needsCollision(btBroadphaseProxy* p) const
471  {
472  return m_userCallback->needsCollision(p);
473  }
474 
475  virtual btScalar addSingleResult (btCollisionWorld::LocalRayResult &r, bool b)
476  {
478  shapeInfo.m_shapePart = -1;
479  shapeInfo.m_triangleIndex = m_i;
480  if (r.m_localShapeInfo == NULL)
481  r.m_localShapeInfo = &shapeInfo;
482 
483  const btScalar result = m_userCallback->addSingleResult(r, b);
484  m_closestHitFraction = m_userCallback->m_closestHitFraction;
485  return result;
486  }
487  };
488 
489  struct RayTester : btDbvt::ICollide
490  {
491  const btCollisionObject* m_collisionObject;
492  const btCompoundShape* m_compoundShape;
493  const btTransform& m_colObjWorldTransform;
494  const btTransform& m_rayFromTrans;
495  const btTransform& m_rayToTrans;
496  RayResultCallback& m_resultCallback;
497 
498  RayTester(const btCollisionObject* collisionObject,
499  const btCompoundShape* compoundShape,
500  const btTransform& colObjWorldTransform,
501  const btTransform& rayFromTrans,
502  const btTransform& rayToTrans,
503  RayResultCallback& resultCallback):
504  m_collisionObject(collisionObject),
505  m_compoundShape(compoundShape),
506  m_colObjWorldTransform(colObjWorldTransform),
507  m_rayFromTrans(rayFromTrans),
508  m_rayToTrans(rayToTrans),
509  m_resultCallback(resultCallback)
510  {
511 
512  }
513 
514  void ProcessLeaf(int i)
515  {
516  const btCollisionShape* childCollisionShape = m_compoundShape->getChildShape(i);
517  const btTransform& childTrans = m_compoundShape->getChildTransform(i);
518  btTransform childWorldTrans = m_colObjWorldTransform * childTrans;
519 
520  btCollisionObjectWrapper tmpOb(0,childCollisionShape,m_collisionObject,childWorldTrans,-1,i);
521  // replace collision shape so that callback can determine the triangle
522 
523 
524 
525  LocalInfoAdder2 my_cb(i, &m_resultCallback);
526 
528  m_rayFromTrans,
529  m_rayToTrans,
530  &tmpOb,
531  my_cb);
532 
533  }
534 
535  void Process(const btDbvtNode* leaf)
536  {
537  ProcessLeaf(leaf->dataAsInt);
538  }
539  };
540 
541  const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(collisionShape);
542  const btDbvt* dbvt = compoundShape->getDynamicAabbTree();
543 
544 
545  RayTester rayCB(
546  collisionObjectWrap->getCollisionObject(),
547  compoundShape,
548  colObjWorldTransform,
549  rayFromTrans,
550  rayToTrans,
551  resultCallback);
552 #ifndef DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION
553  if (dbvt)
554  {
555  btVector3 localRayFrom = colObjWorldTransform.inverseTimes(rayFromTrans).getOrigin();
556  btVector3 localRayTo = colObjWorldTransform.inverseTimes(rayToTrans).getOrigin();
557  btDbvt::rayTest(dbvt->m_root, localRayFrom , localRayTo, rayCB);
558  }
559  else
560 #endif //DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION
561  {
562  for (int i = 0, n = compoundShape->getNumChildShapes(); i < n; ++i)
563  {
564  rayCB.ProcessLeaf(i);
565  }
566  }
567  }
568  }
569  }
570 }
571 
572 void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const btTransform& convexFromTrans,const btTransform& convexToTrans,
573  btCollisionObject* collisionObject,
574  const btCollisionShape* collisionShape,
575  const btTransform& colObjWorldTransform,
576  ConvexResultCallback& resultCallback, btScalar allowedPenetration)
577 {
578  btCollisionObjectWrapper tmpOb(0,collisionShape,collisionObject,colObjWorldTransform,-1,-1);
579  btCollisionWorld::objectQuerySingleInternal(castShape,convexFromTrans,convexToTrans,&tmpOb,resultCallback,allowedPenetration);
580 }
581 
582 void btCollisionWorld::objectQuerySingleInternal(const btConvexShape* castShape,const btTransform& convexFromTrans,const btTransform& convexToTrans,
583  const btCollisionObjectWrapper* colObjWrap,
584  ConvexResultCallback& resultCallback, btScalar allowedPenetration)
585 {
586  const btCollisionShape* collisionShape = colObjWrap->getCollisionShape();
587  const btTransform& colObjWorldTransform = colObjWrap->getWorldTransform();
588 
589  if (collisionShape->isConvex())
590  {
591  //BT_PROFILE("convexSweepConvex");
592  btConvexCast::CastResult castResult;
593  castResult.m_allowedPenetration = allowedPenetration;
594  castResult.m_fraction = resultCallback.m_closestHitFraction;//btScalar(1.);//??
595 
596  btConvexShape* convexShape = (btConvexShape*) collisionShape;
597  btVoronoiSimplexSolver simplexSolver;
598  btGjkEpaPenetrationDepthSolver gjkEpaPenetrationSolver;
599 
600  btContinuousConvexCollision convexCaster1(castShape,convexShape,&simplexSolver,&gjkEpaPenetrationSolver);
601  //btGjkConvexCast convexCaster2(castShape,convexShape,&simplexSolver);
602  //btSubsimplexConvexCast convexCaster3(castShape,convexShape,&simplexSolver);
603 
604  btConvexCast* castPtr = &convexCaster1;
605 
606 
607 
608  if (castPtr->calcTimeOfImpact(convexFromTrans,convexToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
609  {
610  //add hit
611  if (castResult.m_normal.length2() > btScalar(0.0001))
612  {
613  if (castResult.m_fraction < resultCallback.m_closestHitFraction)
614  {
615  castResult.m_normal.normalize();
616  btCollisionWorld::LocalConvexResult localConvexResult
617  (
618  colObjWrap->getCollisionObject(),
619  0,
620  castResult.m_normal,
621  castResult.m_hitPoint,
622  castResult.m_fraction
623  );
624 
625  bool normalInWorldSpace = true;
626  resultCallback.addSingleResult(localConvexResult, normalInWorldSpace);
627 
628  }
629  }
630  }
631  } else {
632  if (collisionShape->isConcave())
633  {
634  if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE)
635  {
636  //BT_PROFILE("convexSweepbtBvhTriangleMesh");
637  btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape;
638  btTransform worldTocollisionObject = colObjWorldTransform.inverse();
639  btVector3 convexFromLocal = worldTocollisionObject * convexFromTrans.getOrigin();
640  btVector3 convexToLocal = worldTocollisionObject * convexToTrans.getOrigin();
641  // rotation of box in local mesh space = MeshRotation^-1 * ConvexToRotation
642  btTransform rotationXform = btTransform(worldTocollisionObject.getBasis() * convexToTrans.getBasis());
643 
644  //ConvexCast::CastResult
645  struct BridgeTriangleConvexcastCallback : public btTriangleConvexcastCallback
646  {
647  btCollisionWorld::ConvexResultCallback* m_resultCallback;
648  const btCollisionObject* m_collisionObject;
649  btTriangleMeshShape* m_triangleMesh;
650 
651  BridgeTriangleConvexcastCallback(const btConvexShape* castShape, const btTransform& from,const btTransform& to,
652  btCollisionWorld::ConvexResultCallback* resultCallback, const btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh, const btTransform& triangleToWorld):
653  btTriangleConvexcastCallback(castShape, from,to, triangleToWorld, triangleMesh->getMargin()),
654  m_resultCallback(resultCallback),
655  m_collisionObject(collisionObject),
656  m_triangleMesh(triangleMesh)
657  {
658  }
659 
660 
661  virtual btScalar reportHit(const btVector3& hitNormalLocal, const btVector3& hitPointLocal, btScalar hitFraction, int partId, int triangleIndex )
662  {
664  shapeInfo.m_shapePart = partId;
665  shapeInfo.m_triangleIndex = triangleIndex;
666  if (hitFraction <= m_resultCallback->m_closestHitFraction)
667  {
668 
670  (m_collisionObject,
671  &shapeInfo,
672  hitNormalLocal,
673  hitPointLocal,
674  hitFraction);
675 
676  bool normalInWorldSpace = true;
677 
678 
679  return m_resultCallback->addSingleResult(convexResult,normalInWorldSpace);
680  }
681  return hitFraction;
682  }
683 
684  };
685 
686  BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,colObjWrap->getCollisionObject(),triangleMesh, colObjWorldTransform);
687  tccb.m_hitFraction = resultCallback.m_closestHitFraction;
688  tccb.m_allowedPenetration = allowedPenetration;
689  btVector3 boxMinLocal, boxMaxLocal;
690  castShape->getAabb(rotationXform, boxMinLocal, boxMaxLocal);
691  triangleMesh->performConvexcast(&tccb,convexFromLocal,convexToLocal,boxMinLocal, boxMaxLocal);
692  } else
693  {
694  if (collisionShape->getShapeType()==STATIC_PLANE_PROXYTYPE)
695  {
696  btConvexCast::CastResult castResult;
697  castResult.m_allowedPenetration = allowedPenetration;
698  castResult.m_fraction = resultCallback.m_closestHitFraction;
699  btStaticPlaneShape* planeShape = (btStaticPlaneShape*) collisionShape;
700  btContinuousConvexCollision convexCaster1(castShape,planeShape);
701  btConvexCast* castPtr = &convexCaster1;
702 
703  if (castPtr->calcTimeOfImpact(convexFromTrans,convexToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
704  {
705  //add hit
706  if (castResult.m_normal.length2() > btScalar(0.0001))
707  {
708  if (castResult.m_fraction < resultCallback.m_closestHitFraction)
709  {
710  castResult.m_normal.normalize();
711  btCollisionWorld::LocalConvexResult localConvexResult
712  (
713  colObjWrap->getCollisionObject(),
714  0,
715  castResult.m_normal,
716  castResult.m_hitPoint,
717  castResult.m_fraction
718  );
719 
720  bool normalInWorldSpace = true;
721  resultCallback.addSingleResult(localConvexResult, normalInWorldSpace);
722  }
723  }
724  }
725 
726  } else
727  {
728  //BT_PROFILE("convexSweepConcave");
729  btConcaveShape* concaveShape = (btConcaveShape*)collisionShape;
730  btTransform worldTocollisionObject = colObjWorldTransform.inverse();
731  btVector3 convexFromLocal = worldTocollisionObject * convexFromTrans.getOrigin();
732  btVector3 convexToLocal = worldTocollisionObject * convexToTrans.getOrigin();
733  // rotation of box in local mesh space = MeshRotation^-1 * ConvexToRotation
734  btTransform rotationXform = btTransform(worldTocollisionObject.getBasis() * convexToTrans.getBasis());
735 
736  //ConvexCast::CastResult
737  struct BridgeTriangleConvexcastCallback : public btTriangleConvexcastCallback
738  {
739  btCollisionWorld::ConvexResultCallback* m_resultCallback;
740  const btCollisionObject* m_collisionObject;
741  btConcaveShape* m_triangleMesh;
742 
743  BridgeTriangleConvexcastCallback(const btConvexShape* castShape, const btTransform& from,const btTransform& to,
744  btCollisionWorld::ConvexResultCallback* resultCallback, const btCollisionObject* collisionObject,btConcaveShape* triangleMesh, const btTransform& triangleToWorld):
745  btTriangleConvexcastCallback(castShape, from,to, triangleToWorld, triangleMesh->getMargin()),
746  m_resultCallback(resultCallback),
747  m_collisionObject(collisionObject),
748  m_triangleMesh(triangleMesh)
749  {
750  }
751 
752 
753  virtual btScalar reportHit(const btVector3& hitNormalLocal, const btVector3& hitPointLocal, btScalar hitFraction, int partId, int triangleIndex )
754  {
756  shapeInfo.m_shapePart = partId;
757  shapeInfo.m_triangleIndex = triangleIndex;
758  if (hitFraction <= m_resultCallback->m_closestHitFraction)
759  {
760 
762  (m_collisionObject,
763  &shapeInfo,
764  hitNormalLocal,
765  hitPointLocal,
766  hitFraction);
767 
768  bool normalInWorldSpace = true;
769 
770  return m_resultCallback->addSingleResult(convexResult,normalInWorldSpace);
771  }
772  return hitFraction;
773  }
774 
775  };
776 
777  BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,colObjWrap->getCollisionObject(),concaveShape, colObjWorldTransform);
778  tccb.m_hitFraction = resultCallback.m_closestHitFraction;
779  tccb.m_allowedPenetration = allowedPenetration;
780  btVector3 boxMinLocal, boxMaxLocal;
781  castShape->getAabb(rotationXform, boxMinLocal, boxMaxLocal);
782 
783  btVector3 rayAabbMinLocal = convexFromLocal;
784  rayAabbMinLocal.setMin(convexToLocal);
785  btVector3 rayAabbMaxLocal = convexFromLocal;
786  rayAabbMaxLocal.setMax(convexToLocal);
787  rayAabbMinLocal += boxMinLocal;
788  rayAabbMaxLocal += boxMaxLocal;
789  concaveShape->processAllTriangles(&tccb,rayAabbMinLocal,rayAabbMaxLocal);
790  }
791  }
792  } else {
793  if (collisionShape->isCompound())
794  {
796  {
798  const btCollisionObjectWrapper* colObjWrap,
799  const btConvexShape* castShape,
800  const btTransform& convexFromTrans,
801  const btTransform& convexToTrans,
802  btScalar allowedPenetration,
803  const btCompoundShape* compoundShape,
804  const btTransform& colObjWorldTransform,
805  ConvexResultCallback& resultCallback)
806  :
807  m_colObjWrap(colObjWrap),
808  m_castShape(castShape),
809  m_convexFromTrans(convexFromTrans),
810  m_convexToTrans(convexToTrans),
811  m_allowedPenetration(allowedPenetration),
812  m_compoundShape(compoundShape),
813  m_colObjWorldTransform(colObjWorldTransform),
814  m_resultCallback(resultCallback) {
815  }
816 
817  const btCollisionObjectWrapper* m_colObjWrap;
818  const btConvexShape* m_castShape;
819  const btTransform& m_convexFromTrans;
820  const btTransform& m_convexToTrans;
821  btScalar m_allowedPenetration;
822  const btCompoundShape* m_compoundShape;
823  const btTransform& m_colObjWorldTransform;
824  ConvexResultCallback& m_resultCallback;
825 
826  public:
827 
828  void ProcessChild(int index, const btTransform& childTrans, const btCollisionShape* childCollisionShape)
829  {
830  btTransform childWorldTrans = m_colObjWorldTransform * childTrans;
831 
832  struct LocalInfoAdder : public ConvexResultCallback {
833  ConvexResultCallback* m_userCallback;
834  int m_i;
835 
836  LocalInfoAdder(int i, ConvexResultCallback *user)
837  : m_userCallback(user), m_i(i)
838  {
839  m_closestHitFraction = m_userCallback->m_closestHitFraction;
840  }
841  virtual bool needsCollision(btBroadphaseProxy* p) const
842  {
843  return m_userCallback->needsCollision(p);
844  }
845  virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& r, bool b)
846  {
848  shapeInfo.m_shapePart = -1;
849  shapeInfo.m_triangleIndex = m_i;
850  if (r.m_localShapeInfo == NULL)
851  r.m_localShapeInfo = &shapeInfo;
852  const btScalar result = m_userCallback->addSingleResult(r, b);
853  m_closestHitFraction = m_userCallback->m_closestHitFraction;
854  return result;
855 
856  }
857  };
858 
859  LocalInfoAdder my_cb(index, &m_resultCallback);
860 
861  btCollisionObjectWrapper tmpObj(m_colObjWrap, childCollisionShape, m_colObjWrap->getCollisionObject(), childWorldTrans, -1, index);
862 
863  objectQuerySingleInternal(m_castShape, m_convexFromTrans, m_convexToTrans, &tmpObj, my_cb, m_allowedPenetration);
864  }
865 
866  void Process(const btDbvtNode* leaf)
867  {
868  // Processing leaf node
869  int index = leaf->dataAsInt;
870 
871  btTransform childTrans = m_compoundShape->getChildTransform(index);
872  const btCollisionShape* childCollisionShape = m_compoundShape->getChildShape(index);
873 
874  ProcessChild(index, childTrans, childCollisionShape);
875  }
876  };
877 
878  BT_PROFILE("convexSweepCompound");
879  const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(collisionShape);
880 
881  btVector3 fromLocalAabbMin, fromLocalAabbMax;
882  btVector3 toLocalAabbMin, toLocalAabbMax;
883 
884  castShape->getAabb(colObjWorldTransform.inverse() * convexFromTrans, fromLocalAabbMin, fromLocalAabbMax);
885  castShape->getAabb(colObjWorldTransform.inverse() * convexToTrans, toLocalAabbMin, toLocalAabbMax);
886 
887  fromLocalAabbMin.setMin(toLocalAabbMin);
888  fromLocalAabbMax.setMax(toLocalAabbMax);
889 
890  btCompoundLeafCallback callback(colObjWrap, castShape, convexFromTrans, convexToTrans,
891  allowedPenetration, compoundShape, colObjWorldTransform, resultCallback);
892 
893  const btDbvt* tree = compoundShape->getDynamicAabbTree();
894  if (tree) {
895  const ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds = btDbvtVolume::FromMM(fromLocalAabbMin, fromLocalAabbMax);
896  tree->collideTV(tree->m_root, bounds, callback);
897  } else {
898  int i;
899  for (i=0;i<compoundShape->getNumChildShapes();i++)
900  {
901  const btCollisionShape* childCollisionShape = compoundShape->getChildShape(i);
902  btTransform childTrans = compoundShape->getChildTransform(i);
903  callback.ProcessChild(i, childTrans, childCollisionShape);
904  }
905  }
906  }
907  }
908  }
909 }
910 
911 
913 {
914 
920 
923 
924  btSingleRayCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld,const btCollisionWorld* world,btCollisionWorld::RayResultCallback& resultCallback)
925  :m_rayFromWorld(rayFromWorld),
926  m_rayToWorld(rayToWorld),
927  m_world(world),
928  m_resultCallback(resultCallback)
929  {
930  m_rayFromTrans.setIdentity();
931  m_rayFromTrans.setOrigin(m_rayFromWorld);
932  m_rayToTrans.setIdentity();
933  m_rayToTrans.setOrigin(m_rayToWorld);
934 
935  btVector3 rayDir = (rayToWorld-rayFromWorld);
936 
937  rayDir.normalize ();
939  m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0];
940  m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1];
941  m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[2];
942  m_signs[0] = m_rayDirectionInverse[0] < 0.0;
943  m_signs[1] = m_rayDirectionInverse[1] < 0.0;
944  m_signs[2] = m_rayDirectionInverse[2] < 0.0;
945 
946  m_lambda_max = rayDir.dot(m_rayToWorld-m_rayFromWorld);
947 
948  }
949 
950 
951 
952  virtual bool process(const btBroadphaseProxy* proxy)
953  {
955  if (m_resultCallback.m_closestHitFraction == btScalar(0.f))
956  return false;
957 
958  btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject;
959 
960  //only perform raycast if filterMask matches
961  if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
962  {
963  //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
964  //btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
965 #if 0
966 #ifdef RECALCULATE_AABB
967  btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
968  collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
969 #else
970  //getBroadphase()->getAabb(collisionObject->getBroadphaseHandle(),collisionObjectAabbMin,collisionObjectAabbMax);
971  const btVector3& collisionObjectAabbMin = collisionObject->getBroadphaseHandle()->m_aabbMin;
972  const btVector3& collisionObjectAabbMax = collisionObject->getBroadphaseHandle()->m_aabbMax;
973 #endif
974 #endif
975  //btScalar hitLambda = m_resultCallback.m_closestHitFraction;
976  //culling already done by broadphase
977  //if (btRayAabb(m_rayFromWorld,m_rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,m_hitNormal))
978  {
979  m_world->rayTestSingle(m_rayFromTrans,m_rayToTrans,
980  collisionObject,
981  collisionObject->getCollisionShape(),
982  collisionObject->getWorldTransform(),
983  m_resultCallback);
984  }
985  }
986  return true;
987  }
988 };
989 
990 void btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const
991 {
992  //BT_PROFILE("rayTest");
995  btSingleRayCallback rayCB(rayFromWorld,rayToWorld,this,resultCallback);
996 
997 #ifndef USE_BRUTEFORCE_RAYBROADPHASE
998  m_broadphasePairCache->rayTest(rayFromWorld,rayToWorld,rayCB);
999 #else
1000  for (int i=0;i<this->getNumCollisionObjects();i++)
1001  {
1002  rayCB.process(m_collisionObjects[i]->getBroadphaseHandle());
1003  }
1004 #endif //USE_BRUTEFORCE_RAYBROADPHASE
1005 
1006 }
1007 
1008 
1010 {
1011 
1019 
1020 
1021  btSingleSweepCallback(const btConvexShape* castShape, const btTransform& convexFromTrans,const btTransform& convexToTrans,const btCollisionWorld* world,btCollisionWorld::ConvexResultCallback& resultCallback,btScalar allowedPenetration)
1022  :m_convexFromTrans(convexFromTrans),
1023  m_convexToTrans(convexToTrans),
1024  m_world(world),
1025  m_resultCallback(resultCallback),
1026  m_allowedCcdPenetration(allowedPenetration),
1027  m_castShape(castShape)
1028  {
1029  btVector3 unnormalizedRayDir = (m_convexToTrans.getOrigin()-m_convexFromTrans.getOrigin());
1030  btVector3 rayDir = unnormalizedRayDir.normalized();
1032  m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0];
1033  m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1];
1034  m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[2];
1035  m_signs[0] = m_rayDirectionInverse[0] < 0.0;
1036  m_signs[1] = m_rayDirectionInverse[1] < 0.0;
1037  m_signs[2] = m_rayDirectionInverse[2] < 0.0;
1038 
1039  m_lambda_max = rayDir.dot(unnormalizedRayDir);
1040 
1041  }
1042 
1043  virtual bool process(const btBroadphaseProxy* proxy)
1044  {
1046  if (m_resultCallback.m_closestHitFraction == btScalar(0.f))
1047  return false;
1048 
1049  btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject;
1050 
1051  //only perform raycast if filterMask matches
1052  if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) {
1053  //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
1054  m_world->objectQuerySingle(m_castShape, m_convexFromTrans,m_convexToTrans,
1055  collisionObject,
1056  collisionObject->getCollisionShape(),
1057  collisionObject->getWorldTransform(),
1058  m_resultCallback,
1059  m_allowedCcdPenetration);
1060  }
1061 
1062  return true;
1063  }
1064 };
1065 
1066 
1067 
1068 void btCollisionWorld::convexSweepTest(const btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration) const
1069 {
1070 
1071  BT_PROFILE("convexSweepTest");
1075 
1076 
1077 
1078  btTransform convexFromTrans,convexToTrans;
1079  convexFromTrans = convexFromWorld;
1080  convexToTrans = convexToWorld;
1081  btVector3 castShapeAabbMin, castShapeAabbMax;
1082  /* Compute AABB that encompasses angular movement */
1083  {
1084  btVector3 linVel, angVel;
1085  btTransformUtil::calculateVelocity (convexFromTrans, convexToTrans, 1.0f, linVel, angVel);
1086  btVector3 zeroLinVel;
1087  zeroLinVel.setValue(0,0,0);
1088  btTransform R;
1089  R.setIdentity ();
1090  R.setRotation (convexFromTrans.getRotation());
1091  castShape->calculateTemporalAabb (R, zeroLinVel, angVel, 1.0f, castShapeAabbMin, castShapeAabbMax);
1092  }
1093 
1094 #ifndef USE_BRUTEFORCE_RAYBROADPHASE
1095 
1096  btSingleSweepCallback convexCB(castShape,convexFromWorld,convexToWorld,this,resultCallback,allowedCcdPenetration);
1097 
1098  m_broadphasePairCache->rayTest(convexFromTrans.getOrigin(),convexToTrans.getOrigin(),convexCB,castShapeAabbMin,castShapeAabbMax);
1099 
1100 #else
1101  // do a ray-shape query using convexCaster (CCD)
1103  int i;
1104  for (i=0;i<m_collisionObjects.size();i++)
1105  {
1106  btCollisionObject* collisionObject= m_collisionObjects[i];
1107  //only perform raycast if filterMask matches
1108  if(resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) {
1109  //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
1110  btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
1111  collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
1112  AabbExpand (collisionObjectAabbMin, collisionObjectAabbMax, castShapeAabbMin, castShapeAabbMax);
1113  btScalar hitLambda = btScalar(1.); //could use resultCallback.m_closestHitFraction, but needs testing
1114  btVector3 hitNormal;
1115  if (btRayAabb(convexFromWorld.getOrigin(),convexToWorld.getOrigin(),collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,hitNormal))
1116  {
1117  objectQuerySingle(castShape, convexFromTrans,convexToTrans,
1118  collisionObject,
1119  collisionObject->getCollisionShape(),
1120  collisionObject->getWorldTransform(),
1121  resultCallback,
1122  allowedCcdPenetration);
1123  }
1124  }
1125  }
1126 #endif //USE_BRUTEFORCE_RAYBROADPHASE
1127 }
1128 
1129 
1130 
1132 {
1133 
1135 
1137  :btManifoldResult(obj0Wrap,obj1Wrap),
1138  m_resultCallback(resultCallback)
1139  {
1140  }
1141 
1142  virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)
1143  {
1144  bool isSwapped = m_manifoldPtr->getBody0() != m_body0Wrap->getCollisionObject();
1145  btVector3 pointA = pointInWorld + normalOnBInWorld * depth;
1146  btVector3 localA;
1147  btVector3 localB;
1148  if (isSwapped)
1149  {
1150  localA = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointA );
1151  localB = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld);
1152  } else
1153  {
1154  localA = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointA );
1155  localB = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld);
1156  }
1157 
1158  btManifoldPoint newPt(localA,localB,normalOnBInWorld,depth);
1159  newPt.m_positionWorldOnA = pointA;
1160  newPt.m_positionWorldOnB = pointInWorld;
1161 
1162  //BP mod, store contact triangles.
1163  if (isSwapped)
1164  {
1165  newPt.m_partId0 = m_partId1;
1166  newPt.m_partId1 = m_partId0;
1167  newPt.m_index0 = m_index1;
1168  newPt.m_index1 = m_index0;
1169  } else
1170  {
1171  newPt.m_partId0 = m_partId0;
1172  newPt.m_partId1 = m_partId1;
1173  newPt.m_index0 = m_index0;
1174  newPt.m_index1 = m_index1;
1175  }
1176 
1177  //experimental feature info, for per-triangle material etc.
1178  const btCollisionObjectWrapper* obj0Wrap = isSwapped? m_body1Wrap : m_body0Wrap;
1179  const btCollisionObjectWrapper* obj1Wrap = isSwapped? m_body0Wrap : m_body1Wrap;
1180  m_resultCallback.addSingleResult(newPt,obj0Wrap,newPt.m_partId0,newPt.m_index0,obj1Wrap,newPt.m_partId1,newPt.m_index1);
1181 
1182  }
1183 
1184 };
1185 
1186 
1187 
1189 {
1190 
1194 
1195 
1197  :m_collisionObject(collisionObject),
1198  m_world(world),
1199  m_resultCallback(resultCallback)
1200  {
1201  }
1202 
1203  virtual bool process(const btBroadphaseProxy* proxy)
1204  {
1205  btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject;
1206  if (collisionObject == m_collisionObject)
1207  return true;
1208 
1209  //only perform raycast if filterMask matches
1210  if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
1211  {
1212  btCollisionObjectWrapper ob0(0,m_collisionObject->getCollisionShape(),m_collisionObject,m_collisionObject->getWorldTransform(),-1,-1);
1213  btCollisionObjectWrapper ob1(0,collisionObject->getCollisionShape(),collisionObject,collisionObject->getWorldTransform(),-1,-1);
1214 
1215  btCollisionAlgorithm* algorithm = m_world->getDispatcher()->findAlgorithm(&ob0,&ob1);
1216  if (algorithm)
1217  {
1218  btBridgedManifoldResult contactPointResult(&ob0,&ob1, m_resultCallback);
1219  //discrete collision detection query
1220 
1221  algorithm->processCollision(&ob0,&ob1, m_world->getDispatchInfo(),&contactPointResult);
1222 
1223  algorithm->~btCollisionAlgorithm();
1224  m_world->getDispatcher()->freeCollisionAlgorithm(algorithm);
1225  }
1226  }
1227  return true;
1228  }
1229 };
1230 
1231 
1235 {
1236  btVector3 aabbMin,aabbMax;
1237  colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(),aabbMin,aabbMax);
1238  btSingleContactCallback contactCB(colObj,this,resultCallback);
1239 
1240  m_broadphasePairCache->aabbTest(aabbMin,aabbMax,contactCB);
1241 }
1242 
1243 
1247 {
1248  btCollisionObjectWrapper obA(0,colObjA->getCollisionShape(),colObjA,colObjA->getWorldTransform(),-1,-1);
1249  btCollisionObjectWrapper obB(0,colObjB->getCollisionShape(),colObjB,colObjB->getWorldTransform(),-1,-1);
1250 
1251  btCollisionAlgorithm* algorithm = getDispatcher()->findAlgorithm(&obA,&obB);
1252  if (algorithm)
1253  {
1254  btBridgedManifoldResult contactPointResult(&obA,&obB, resultCallback);
1255  //discrete collision detection query
1256  algorithm->processCollision(&obA,&obB, getDispatchInfo(),&contactPointResult);
1257 
1258  algorithm->~btCollisionAlgorithm();
1259  getDispatcher()->freeCollisionAlgorithm(algorithm);
1260  }
1261 
1262 }
1263 
1264 
1265 
1266 
1268 {
1272 
1273 public:
1274 
1275  DebugDrawcallback(btIDebugDraw* debugDrawer,const btTransform& worldTrans,const btVector3& color) :
1276  m_debugDrawer(debugDrawer),
1277  m_color(color),
1278  m_worldTrans(worldTrans)
1279  {
1280  }
1281 
1282  virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex)
1283  {
1284  processTriangle(triangle,partId,triangleIndex);
1285  }
1286 
1287  virtual void processTriangle(btVector3* triangle,int partId, int triangleIndex)
1288  {
1289  (void)partId;
1290  (void)triangleIndex;
1291 
1292  btVector3 wv0,wv1,wv2;
1293  wv0 = m_worldTrans*triangle[0];
1294  wv1 = m_worldTrans*triangle[1];
1295  wv2 = m_worldTrans*triangle[2];
1296  btVector3 center = (wv0+wv1+wv2)*btScalar(1./3.);
1297 
1298  if (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawNormals )
1299  {
1300  btVector3 normal = (wv1-wv0).cross(wv2-wv0);
1301  normal.normalize();
1302  btVector3 normalColor(1,1,0);
1303  m_debugDrawer->drawLine(center,center+normal,normalColor);
1304  }
1305  m_debugDrawer->drawLine(wv0,wv1,m_color);
1306  m_debugDrawer->drawLine(wv1,wv2,m_color);
1307  m_debugDrawer->drawLine(wv2,wv0,m_color);
1308  }
1309 };
1310 
1311 
1312 void btCollisionWorld::debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color)
1313 {
1314  // Draw a small simplex at the center of the object
1315  if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawFrames)
1316  {
1317  getDebugDrawer()->drawTransform(worldTransform,1);
1318  }
1319 
1320  if (shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE)
1321  {
1322  const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(shape);
1323  for (int i=compoundShape->getNumChildShapes()-1;i>=0;i--)
1324  {
1325  btTransform childTrans = compoundShape->getChildTransform(i);
1326  const btCollisionShape* colShape = compoundShape->getChildShape(i);
1327  debugDrawObject(worldTransform*childTrans,colShape,color);
1328  }
1329 
1330  } else
1331  {
1332 
1333  switch (shape->getShapeType())
1334  {
1335 
1336  case BOX_SHAPE_PROXYTYPE:
1337  {
1338  const btBoxShape* boxShape = static_cast<const btBoxShape*>(shape);
1339  btVector3 halfExtents = boxShape->getHalfExtentsWithMargin();
1340  getDebugDrawer()->drawBox(-halfExtents,halfExtents,worldTransform,color);
1341  break;
1342  }
1343 
1345  {
1346  const btSphereShape* sphereShape = static_cast<const btSphereShape*>(shape);
1347  btScalar radius = sphereShape->getMargin();//radius doesn't include the margin, so draw with margin
1348 
1349  getDebugDrawer()->drawSphere(radius, worldTransform, color);
1350  break;
1351  }
1353  {
1354  const btMultiSphereShape* multiSphereShape = static_cast<const btMultiSphereShape*>(shape);
1355 
1356  btTransform childTransform;
1357  childTransform.setIdentity();
1358 
1359  for (int i = multiSphereShape->getSphereCount()-1; i>=0;i--)
1360  {
1361  childTransform.setOrigin(multiSphereShape->getSpherePosition(i));
1362  getDebugDrawer()->drawSphere(multiSphereShape->getSphereRadius(i), worldTransform*childTransform, color);
1363  }
1364 
1365  break;
1366  }
1368  {
1369  const btCapsuleShape* capsuleShape = static_cast<const btCapsuleShape*>(shape);
1370 
1371  btScalar radius = capsuleShape->getRadius();
1372  btScalar halfHeight = capsuleShape->getHalfHeight();
1373 
1374  int upAxis = capsuleShape->getUpAxis();
1375  getDebugDrawer()->drawCapsule(radius, halfHeight, upAxis, worldTransform, color);
1376  break;
1377  }
1378  case CONE_SHAPE_PROXYTYPE:
1379  {
1380  const btConeShape* coneShape = static_cast<const btConeShape*>(shape);
1381  btScalar radius = coneShape->getRadius();//+coneShape->getMargin();
1382  btScalar height = coneShape->getHeight();//+coneShape->getMargin();
1383 
1384  int upAxis= coneShape->getConeUpIndex();
1385  getDebugDrawer()->drawCone(radius, height, upAxis, worldTransform, color);
1386  break;
1387 
1388  }
1390  {
1391  const btCylinderShape* cylinder = static_cast<const btCylinderShape*>(shape);
1392  int upAxis = cylinder->getUpAxis();
1393  btScalar radius = cylinder->getRadius();
1394  btScalar halfHeight = cylinder->getHalfExtentsWithMargin()[upAxis];
1395  getDebugDrawer()->drawCylinder(radius, halfHeight, upAxis, worldTransform, color);
1396  break;
1397  }
1398 
1400  {
1401  const btStaticPlaneShape* staticPlaneShape = static_cast<const btStaticPlaneShape*>(shape);
1402  btScalar planeConst = staticPlaneShape->getPlaneConstant();
1403  const btVector3& planeNormal = staticPlaneShape->getPlaneNormal();
1404  getDebugDrawer()->drawPlane(planeNormal, planeConst,worldTransform, color);
1405  break;
1406 
1407  }
1408  default:
1409  {
1410 
1412  if (shape->isPolyhedral())
1413  {
1414  btPolyhedralConvexShape* polyshape = (btPolyhedralConvexShape*) shape;
1415 
1416  int i;
1417  if (polyshape->getConvexPolyhedron())
1418  {
1419  const btConvexPolyhedron* poly = polyshape->getConvexPolyhedron();
1420  for (i=0;i<poly->m_faces.size();i++)
1421  {
1422  btVector3 centroid(0,0,0);
1423  int numVerts = poly->m_faces[i].m_indices.size();
1424  if (numVerts)
1425  {
1426  int lastV = poly->m_faces[i].m_indices[numVerts-1];
1427  for (int v=0;v<poly->m_faces[i].m_indices.size();v++)
1428  {
1429  int curVert = poly->m_faces[i].m_indices[v];
1430  centroid+=poly->m_vertices[curVert];
1431  getDebugDrawer()->drawLine(worldTransform*poly->m_vertices[lastV],worldTransform*poly->m_vertices[curVert],color);
1432  lastV = curVert;
1433  }
1434  }
1435  centroid*= btScalar(1.f)/btScalar(numVerts);
1436  if (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawNormals)
1437  {
1438  btVector3 normalColor(1,1,0);
1439  btVector3 faceNormal(poly->m_faces[i].m_plane[0],poly->m_faces[i].m_plane[1],poly->m_faces[i].m_plane[2]);
1440  getDebugDrawer()->drawLine(worldTransform*centroid,worldTransform*(centroid+faceNormal),normalColor);
1441  }
1442 
1443  }
1444 
1445 
1446  } else
1447  {
1448  for (i=0;i<polyshape->getNumEdges();i++)
1449  {
1450  btVector3 a,b;
1451  polyshape->getEdge(i,a,b);
1452  btVector3 wa = worldTransform * a;
1453  btVector3 wb = worldTransform * b;
1454  getDebugDrawer()->drawLine(wa,wb,color);
1455  }
1456  }
1457 
1458 
1459  }
1460 
1461  if (shape->isConcave())
1462  {
1463  btConcaveShape* concaveMesh = (btConcaveShape*) shape;
1464 
1468 
1469  DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color);
1470  concaveMesh->processAllTriangles(&drawCallback,aabbMin,aabbMax);
1471 
1472  }
1473 
1475  {
1477  //todo: pass camera for some culling
1480  //DebugDrawcallback drawCallback;
1481  DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color);
1482  convexMesh->getMeshInterface()->InternalProcessAllTriangles(&drawCallback,aabbMin,aabbMax);
1483  }
1484 
1485 
1486 
1487  }
1488 
1489  }
1490  }
1491 }
1492 
1493 
1495 {
1496  if (getDebugDrawer())
1497  {
1499 
1500  if ( getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints)
1501  {
1502 
1503 
1504  if (getDispatcher())
1505  {
1506  int numManifolds = getDispatcher()->getNumManifolds();
1507 
1508  for (int i=0;i<numManifolds;i++)
1509  {
1511  //btCollisionObject* obA = static_cast<btCollisionObject*>(contactManifold->getBody0());
1512  //btCollisionObject* obB = static_cast<btCollisionObject*>(contactManifold->getBody1());
1513 
1514  int numContacts = contactManifold->getNumContacts();
1515  for (int j=0;j<numContacts;j++)
1516  {
1517  btManifoldPoint& cp = contactManifold->getContactPoint(j);
1519  }
1520  }
1521  }
1522  }
1523 
1525  {
1526  int i;
1527 
1528  for ( i=0;i<m_collisionObjects.size();i++)
1529  {
1532  {
1534  {
1535  btVector3 color(btScalar(0.4),btScalar(0.4),btScalar(0.4));
1536 
1537  switch(colObj->getActivationState())
1538  {
1539  case ACTIVE_TAG:
1540  color = defaultColors.m_activeObject; break;
1541  case ISLAND_SLEEPING:
1542  color = defaultColors.m_deactivatedObject;break;
1543  case WANTS_DEACTIVATION:
1544  color = defaultColors.m_wantsDeactivationObject;break;
1545  case DISABLE_DEACTIVATION:
1546  color = defaultColors.m_disabledDeactivationObject;break;
1547  case DISABLE_SIMULATION:
1548  color = defaultColors.m_disabledSimulationObject;break;
1549  default:
1550  {
1551  color = btVector3(btScalar(.3),btScalar(0.3),btScalar(0.3));
1552  }
1553  };
1554 
1555  debugDrawObject(colObj->getWorldTransform(),colObj->getCollisionShape(),color);
1556  }
1558  {
1559  btVector3 minAabb,maxAabb;
1560  btVector3 colorvec = defaultColors.m_aabb;
1561  colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);
1563  minAabb -= contactThreshold;
1564  maxAabb += contactThreshold;
1565 
1566  btVector3 minAabb2,maxAabb2;
1567 
1568  if(getDispatchInfo().m_useContinuous && colObj->getInternalType()==btCollisionObject::CO_RIGID_BODY && !colObj->isStaticOrKinematicObject())
1569  {
1570  colObj->getCollisionShape()->getAabb(colObj->getInterpolationWorldTransform(),minAabb2,maxAabb2);
1571  minAabb2 -= contactThreshold;
1572  maxAabb2 += contactThreshold;
1573  minAabb.setMin(minAabb2);
1574  maxAabb.setMax(maxAabb2);
1575  }
1576 
1577  m_debugDrawer->drawAabb(minAabb,maxAabb,colorvec);
1578  }
1579  }
1580  }
1581  }
1582  }
1583 }
1584 
1585 
1587 {
1588  int i;
1589 
1591  btHashMap<btHashPtr,btCollisionShape*> serializedShapes;
1592 
1593  for (i=0;i<m_collisionObjects.size();i++)
1594  {
1596  btCollisionShape* shape = colObj->getCollisionShape();
1597 
1598  if (!serializedShapes.find(shape))
1599  {
1600  serializedShapes.insert(shape,shape);
1601  shape->serializeSingleShape(serializer);
1602  }
1603  }
1604 
1605  //serialize all collision objects
1606  for (i=0;i<m_collisionObjects.size();i++)
1607  {
1610  {
1611  colObj->serializeSingleObject(serializer);
1612  }
1613  }
1614 }
1615 
1616 
1618 {
1619 
1620  serializer->startSerialization();
1621 
1622  serializeCollisionObjects(serializer);
1623 
1624  serializer->finishSerialization();
1625 }
1626 
void setOrigin(const btVector3 &origin)
Set the translational element.
Definition: btTransform.h:150
btVector3 getHalfExtentsWithMargin() const
virtual void finishSerialization()=0
#define ACTIVE_TAG
btSingleSweepCallback(const btConvexShape *castShape, const btTransform &convexFromTrans, const btTransform &convexToTrans, const btCollisionWorld *world, btCollisionWorld::ConvexResultCallback &resultCallback, btScalar allowedPenetration)
void serializeCollisionObjects(btSerializer *serializer)
btAlignedObjectArray< btVector3 > m_vertices
btPersistentManifold is a contact point cache, it stays persistent as long as objects are overlapping...
The btConvexTriangleMeshShape is a convex hull of a triangle mesh, but the performance is not as good...
void push_back(const T &_Val)
btScalar getSphereRadius(int index) const
#define BT_LARGE_FLOAT
Definition: btScalar.h:281
btConvexCast is an interface for Casting
Definition: btConvexCast.h:27
virtual DefaultColors getDefaultColors() const
Definition: btIDebugDraw.h:81
virtual btCollisionAlgorithm * findAlgorithm(const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap, btPersistentManifold *sharedManifold=0)=0
btScalar getRadius() const
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
Definition: btVector3.h:650
void performRaycast(btTriangleCallback *callback, const btVector3 &raySource, const btVector3 &rayTarget)
virtual void updateAabbs()
bool isConvex() const
int findLinearSearch(const T &key) const
btCollisionWorld(btDispatcher *dispatcher, btBroadphaseInterface *broadphasePairCache, btCollisionConfiguration *collisionConfiguration)
for debug drawing
btCollisionWorld::ContactResultCallback & m_resultCallback
virtual void reportErrorWarning(const char *warningString)=0
virtual btPersistentManifold * getManifoldByIndexInternal(int index)=0
const Value * find(const Key &key) const
Definition: btHashMap.h:419
bool m_forceUpdateAllAabbs
m_forceUpdateAllAabbs can be set to false as an optimization to only update active object AABBs it is...
btScalar length2() const
Return the length of the vector squared.
Definition: btVector3.h:257
virtual void drawLine(const btVector3 &from, const btVector3 &to, const btVector3 &color)=0
virtual void dispatchAllCollisionPairs(btOverlappingPairCache *pairCache, const btDispatcherInfo &dispatchInfo, btDispatcher *dispatcher)=0
virtual void startSerialization()=0
The btMultiSphereShape represents the convex hull of a collection of spheres.
const btScalar & getPlaneConstant() const
virtual void InternalProcessAllTriangles(btInternalTriangleIndexCallback *callback, const btVector3 &aabbMin, const btVector3 &aabbMax) const
virtual void drawBox(const btVector3 &bbMin, const btVector3 &bbMax, const btVector3 &color)
Definition: btIDebugDraw.h:306
virtual void addCollisionObject(btCollisionObject *collisionObject, short int collisionFilterGroup=btBroadphaseProxy::DefaultFilter, short int collisionFilterMask=btBroadphaseProxy::AllFilter)
The btCapsuleShape represents a capsule around the Y axis, there is also the btCapsuleShapeX aligned ...
const btDbvt * getDynamicAabbTree() const
void setIdentity()
Set this transformation to the identity.
Definition: btTransform.h:172
#define btAssert(x)
Definition: btScalar.h:114
virtual void drawPlane(const btVector3 &planeNormal, btScalar planeConst, const btTransform &transform, const btVector3 &color)
Definition: btIDebugDraw.h:458
btQuaternion getRotation() const
Return a quaternion representing the rotation.
Definition: btTransform.h:122
ContactResultCallback is used to report contact points.
btVector3 getHalfExtentsWithMargin() const
Definition: btBoxShape.h:36
btCollisionConfiguration allows to configure Bullet collision detection stack allocator size...
virtual void serializeSingleShape(btSerializer *serializer) const
The btDbvt class implements a fast dynamic bounding volume tree based on axis aligned bounding boxes ...
Definition: btDbvt.h:198
The btCollisionShape class provides an interface for collision shapes that can be shared among btColl...
RayResultCallback is used to report new raycast results.
btContinuousConvexCollision implements angular and linear time of impact for convex objects...
The btSphereShape implements an implicit sphere, centered around a local origin with radius...
Definition: btSphereShape.h:22
btDbvtNode * m_root
Definition: btDbvt.h:262
btCollisionWorld::RayResultCallback & m_resultCallback
ManifoldContactPoint collects and maintains persistent contactpoints.
const btCollisionWorld * m_world
int getActivationState() const
btDispatcher * m_dispatcher1
btManifoldResult is a helper class to manage contact results.
btVector3 m_disabledSimulationObject
Definition: btIDebugDraw.h:39
static DBVT_PREFIX void rayTest(const btDbvtNode *root, const btVector3 &rayFrom, const btVector3 &rayTo, DBVT_IPOLICY)
rayTest is a re-entrant ray test, and can be called in parallel as long as the btAlignedAlloc is thre...
Definition: btDbvt.h:1054
static void rayTestSingleInternal(const btTransform &rayFromTrans, const btTransform &rayToTrans, const btCollisionObjectWrapper *collisionObjectWrap, RayResultCallback &resultCallback)
int getUpAxis() const
const btCollisionShape * getCollisionShape() const
virtual void computeOverlappingPairs()
the computeOverlappingPairs is usually already called by performDiscreteCollisionDetection (or stepSi...
btCollisionObject * m_collisionObject
#define ISLAND_SLEEPING
bool isStaticOrKinematicObject() const
virtual void drawCapsule(btScalar radius, btScalar halfHeight, int upAxis, const btTransform &transform, const btVector3 &color)
Definition: btIDebugDraw.h:337
int getNumChildShapes() const
btSingleRayCallback(const btVector3 &rayFromWorld, const btVector3 &rayToWorld, const btCollisionWorld *world, btCollisionWorld::RayResultCallback &resultCallback)
int getUpAxis() const
virtual void processAllTriangles(btTriangleCallback *callback, const btVector3 &aabbMin, const btVector3 &aabbMax) const =0
virtual void drawContactPoint(const btVector3 &PointOnB, const btVector3 &normalOnB, btScalar distance, int lifeTime, const btVector3 &color)=0
virtual void getAabb(const btTransform &t, btVector3 &aabbMin, btVector3 &aabbMax) const =0
getAabb returns the axis aligned bounding box in the coordinate frame of the given transform t...
The btHashMap template class implements a generic and lightweight hashmap.
Definition: btHashMap.h:220
btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
Definition: btVector3.h:307
int getNumCollisionObjects() const
btVector3 normalized() const
Return a normalized version of this vector.
Definition: btVector3.h:962
The btConvexShape is an abstract shape interface, implemented by all convex shapes such as btBoxShape...
Definition: btConvexShape.h:31
virtual bool needsCollision(btBroadphaseProxy *proxy0) const
GjkConvexCast performs a raycast on a convex object using support mapping.
const btManifoldPoint & getContactPoint(int index) const
The btTriangleMeshShape is an internal concave triangle mesh interface. Don&#39;t use this class directly...
virtual void getEdge(int i, btVector3 &pa, btVector3 &pb) const =0
void AabbExpand(btVector3 &aabbMin, btVector3 &aabbMax, const btVector3 &expansionMin, const btVector3 &expansionMax)
Definition: btAabbUtil2.h:26
virtual btOverlappingPairCache * getOverlappingPairCache()=0
bool isCompound() const
The btBvhTriangleMeshShape is a static-triangle mesh shape, it can only be used for fixed/non-moving ...
btIDebugDraw * m_debugDrawer
virtual btScalar addSingleResult(LocalRayResult &rayResult, bool normalInWorldSpace)=0
int getSphereCount() const
btTransform & getWorldTransform()
btVector3 m_normalWorldOnB
btScalar getHalfHeight() const
RayResult stores the closest result alternatively, add a callback method to decide about closest/all ...
Definition: btConvexCast.h:36
btVector3 m_positionWorldOnB
virtual void drawCone(btScalar radius, btScalar height, int upAxis, const btTransform &transform, const btVector3 &color)
Definition: btIDebugDraw.h:421
btVector3 & getOrigin()
Return the origin vector translation.
Definition: btTransform.h:117
void getAabb(const btTransform &t, btVector3 &aabbMin, btVector3 &aabbMax) const =0
getAabb&#39;s default implementation is brute force, expected derived classes to implement a fast dedicat...
btBroadphaseProxy * getBroadphaseHandle()
int getConeUpIndex() const
Definition: btConeShape.h:91
btVoronoiSimplexSolver is an implementation of the closest point distance algorithm from a 1-4 points...
const btCollisionWorld * m_world
btCollisionWorld::ConvexResultCallback & m_resultCallback
btIDebugDraw * m_debugDrawer
virtual btIDebugDraw * getDebugDrawer()
void contactPairTest(btCollisionObject *colObjA, btCollisionObject *colObjB, ContactResultCallback &resultCallback)
contactTest performs a discrete collision test between two collision objects and calls the resultCall...
btAlignedObjectArray< btFace > m_faces
The btTriangleCallback provides a callback for each overlapping triangle when calling processAllTrian...
DebugDrawcallback(btIDebugDraw *debugDrawer, const btTransform &worldTrans, const btVector3 &color)
bool isStaticObject() const
btSingleContactCallback(btCollisionObject *collisionObject, btCollisionWorld *world, btCollisionWorld::ContactResultCallback &resultCallback)
The btConeShape implements a cone shape primitive, centered around the origin and aligned with the Y ...
Definition: btConeShape.h:23
btTransform & getChildTransform(int index)
virtual void cleanProxyFromPairs(btBroadphaseProxy *proxy, btDispatcher *dispatcher)=0
static btDbvtAabbMm FromMM(const btVector3 &mi, const btVector3 &mx)
Definition: btDbvt.h:425
virtual bool needsCollision(btBroadphaseProxy *proxy0) const
btScalar dot(const btVector3 &v) const
Return the dot product.
Definition: btVector3.h:235
const btCollisionObject * getCollisionObject() const
virtual void debugDrawObject(const btTransform &worldTransform, const btCollisionShape *shape, const btVector3 &color)
void contactTest(btCollisionObject *colObj, ContactResultCallback &resultCallback)
contactTest performs a discrete collision test between colObj against all objects in the btCollisionW...
btCollisionObject can be used to manage collision detection objects.
void setRotation(const btQuaternion &q)
Set the rotational element by btQuaternion.
Definition: btTransform.h:165
btMatrix3x3 & getBasis()
Return the basis matrix for the rotation.
Definition: btTransform.h:112
void insert(const Key &key, const Value &value)
Definition: btHashMap.h:269
#define DISABLE_SIMULATION
The btPolyhedralConvexShape is an internal interface class for polyhedral convex shapes.
DBVT_PREFIX void collideTV(const btDbvtNode *root, const btDbvtVolume &volume, DBVT_IPOLICY) const
Definition: btDbvt.h:935
static void rayTestSingle(const btTransform &rayFromTrans, const btTransform &rayToTrans, btCollisionObject *collisionObject, const btCollisionShape *collisionShape, const btTransform &colObjWorldTransform, RayResultCallback &resultCallback)
rayTestSingle performs a raycast call and calls the resultCallback.
The btIDebugDraw interface class allows hooking up a debug renderer to visually debug simulations...
Definition: btIDebugDraw.h:29
const btTransform & getInterpolationWorldTransform() const
btScalar getRadius() const
Definition: btConeShape.h:43
bool isConcave() const
LocalShapeInfo gives extra information for complex shapes Currently, only btTriangleMeshShape is avai...
virtual void drawAabb(const btVector3 &from, const btVector3 &to, const btVector3 &color)
Definition: btIDebugDraw.h:137
virtual bool needsCollision(btBroadphaseProxy *proxy0) const
btVector3 m_positionWorldOnA
m_positionWorldOnA is redundant information, see getPositionWorldOnA(), but for clarity ...
btScalar getHeight() const
Definition: btConeShape.h:44
virtual void removeCollisionObject(btCollisionObject *collisionObject)
virtual void freeCollisionAlgorithm(void *ptr)=0
void performConvexcast(btTriangleCallback *callback, const btVector3 &boxSource, const btVector3 &boxTarget, const btVector3 &boxMin, const btVector3 &boxMax)
virtual ~btCollisionWorld()
The btBroadphaseInterface class provides an interface to detect aabb-overlapping object pairs...
btDispatcher * getDispatcher()
int getCollisionFlags() const
The btBroadphaseProxy is the main class that can be used with the Bullet broadphases.
virtual void rayTest(const btVector3 &rayFromWorld, const btVector3 &rayToWorld, RayResultCallback &resultCallback) const
rayTest performs a raycast on all objects in the btCollisionWorld, and calls the resultCallback This ...
virtual void processTriangle(btVector3 *triangle, int partId, int triangleIndex)
virtual btScalar addSingleResult(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1)=0
The btBoxShape is a box primitive around the origin, its sides axis aligned with length specified by ...
Definition: btBoxShape.h:26
virtual void setMargin(btScalar margin)
Definition: btSphereShape.h:58
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:83
#define ATTRIBUTE_ALIGNED16(a)
Definition: btScalar.h:65
virtual void serialize(btSerializer *serializer)
Preliminary serialization test for Bullet 2.76. Loading those files requires a separate parser (Bulle...
int size() const
return the number of elements in the array
bool isPolyhedral() const
virtual int getNumManifolds() const =0
#define BT_PROFILE(name)
Definition: btQuickprof.h:203
static void objectQuerySingle(const btConvexShape *castShape, const btTransform &rayFromTrans, const btTransform &rayToTrans, btCollisionObject *collisionObject, const btCollisionShape *collisionShape, const btTransform &colObjWorldTransform, ConvexResultCallback &resultCallback, btScalar allowedPenetration)
objectQuerySingle performs a collision detection query and calls the resultCallback. It is used internally by rayTest.
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:34
btSubsimplexConvexCast implements Gino van den Bergens&#39; paper "Ray Casting against bteral Convex Obje...
const btVector3 & getPlaneNormal() const
CollisionWorld is interface and container for the collision detection.
void convexSweepTest(const btConvexShape *castShape, const btTransform &from, const btTransform &to, ConvexResultCallback &resultCallback, btScalar allowedCcdPenetration=btScalar(0.)) const
convexTest performs a swept convex cast on all objects in the btCollisionWorld, and calls the resultC...
virtual bool process(const btBroadphaseProxy *proxy)
EpaPenetrationDepthSolver uses the Expanding Polytope Algorithm to calculate the penetration depth be...
void setBroadphaseHandle(btBroadphaseProxy *handle)
btDispatcherInfo & getDispatchInfo()
#define WANTS_DEACTIVATION
The btConcaveShape class provides an interface for non-moving (static) concave shapes.
void remove(const T &key)
virtual void drawTransform(const btTransform &transform, btScalar orthoLen)
Definition: btIDebugDraw.h:166
int getInternalType() const
reserved for Bullet internal usage
virtual btScalar getRadius() const
virtual int getDebugMode() const =0
btAlignedObjectArray< btCollisionObject * > m_collisionObjects
const btTransform & getWorldTransform() const
The btCylinderShape class implements a cylinder shape primitive, centered around the origin...
#define DISABLE_DEACTIVATION
virtual bool process(const btBroadphaseProxy *proxy)
int dataAsInt
Definition: btDbvt.h:188
virtual void performDiscreteCollisionDetection()
virtual void serializeSingleObject(class btSerializer *serializer) const
void calculateTemporalAabb(const btTransform &curTrans, const btVector3 &linvel, const btVector3 &angvel, btScalar timeStep, btVector3 &temporalAabbMin, btVector3 &temporalAabbMax) const
calculateTemporalAabb calculates the enclosing aabb for the moving object over interval [0...
btBroadphaseInterface * m_broadphasePairCache
virtual void setAabb(btBroadphaseProxy *proxy, const btVector3 &aabbMin, const btVector3 &aabbMax, btDispatcher *dispatcher)=0
int getShapeType() const
const btConvexShape * m_castShape
btCollisionWorld * m_world
virtual btScalar addSingleResult(LocalConvexResult &convexResult, bool normalInWorldSpace)=0
void updateSingleAabb(btCollisionObject *colObj)
virtual btScalar getMargin() const
The btCompoundShape allows to store multiple other btCollisionShapes This allows for moving concave c...
void setMax(const btVector3 &other)
Set each element to the max of the current values and the values of another btVector3.
Definition: btVector3.h:619
class btStridingMeshInterface * getMeshInterface()
The btStaticPlaneShape simulates an infinite non-moving (static) collision plane. ...
RayResultCallback is used to report new raycast results.
btBridgedManifoldResult(const btCollisionObjectWrapper *obj0Wrap, const btCollisionObjectWrapper *obj1Wrap, btCollisionWorld::ContactResultCallback &resultCallback)
virtual bool process(const btBroadphaseProxy *proxy)
btCollisionShape * getChildShape(int index)
virtual void internalProcessTriangleIndex(btVector3 *triangle, int partId, int triangleIndex)
virtual void debugDrawWorld()
The btDispatcher interface class can be used in combination with broadphase to dispatch calculations ...
Definition: btDispatcher.h:69
btCollisionAlgorithm is an collision interface that is compatible with the Broadphase and btDispatche...
btScalar gContactBreakingThreshold
static void calculateVelocity(const btTransform &transform0, const btTransform &transform1, btScalar timeStep, btVector3 &linVel, btVector3 &angVel)
virtual void drawSphere(btScalar radius, const btTransform &transform, const btVector3 &color)
Definition: btIDebugDraw.h:93
bool btRayAabb(const btVector3 &rayFrom, const btVector3 &rayTo, const btVector3 &aabbMin, const btVector3 &aabbMax, btScalar &param, btVector3 &normal)
Definition: btAabbUtil2.h:125
btTransform inverse() const
Return the inverse of this transform.
Definition: btTransform.h:188
virtual void destroyProxy(btBroadphaseProxy *proxy, btDispatcher *dispatcher)=0
virtual void addContactPoint(const btVector3 &normalOnBInWorld, const btVector3 &pointInWorld, btScalar depth)
const btBroadphaseInterface * getBroadphase() const
btVector3 m_disabledDeactivationObject
Definition: btIDebugDraw.h:38
btCollisionWorld::ContactResultCallback & m_resultCallback
void setActivationState(int newState) const
virtual void drawCylinder(btScalar radius, btScalar halfHeight, int upAxis, const btTransform &transform, const btVector3 &color)
Definition: btIDebugDraw.h:395
virtual void rayTest(const btVector3 &rayFrom, const btVector3 &rayTo, btBroadphaseRayCallback &rayCallback, const btVector3 &aabbMin=btVector3(0, 0, 0), const btVector3 &aabbMax=btVector3(0, 0, 0))=0
static void objectQuerySingleInternal(const btConvexShape *castShape, const btTransform &convexFromTrans, const btTransform &convexToTrans, const btCollisionObjectWrapper *colObjWrap, ConvexResultCallback &resultCallback, btScalar allowedPenetration)
int getLifeTime() const
btScalar getDistance() const
const btVector3 & getSpherePosition(int index) const
const btConvexPolyhedron * getConvexPolyhedron() const
virtual void calculateOverlappingPairs(btDispatcher *dispatcher)=0
calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during th...
void setMin(const btVector3 &other)
Set each element to the min of the current values and the values of another btVector3.
Definition: btVector3.h:636
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:279
const btCollisionShape * getCollisionShape() const
virtual btScalar getMargin() const
Definition: btSphereShape.h:62
static btDbvtVolume bounds(const tNodeArray &leaves)
Definition: btDbvt.cpp:250
virtual void aabbTest(const btVector3 &aabbMin, const btVector3 &aabbMax, btBroadphaseAabbCallback &callback)=0
virtual bool calcTimeOfImpact(const btTransform &fromA, const btTransform &toA, const btTransform &fromB, const btTransform &toB, CastResult &result)=0
cast a convex against another convex object
virtual int getNumEdges() const =0