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"
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  bool condition = true;
296  btConvexCast* convexCasterPtr = 0;
298  convexCasterPtr = &subSimplexConvexCaster;
299  else
300  convexCasterPtr = &gjkConvexCaster;
301 
302  btConvexCast& convexCaster = *convexCasterPtr;
303 
304  if (convexCaster.calcTimeOfImpact(rayFromTrans,rayToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
305  {
306  //add hit
307  if (castResult.m_normal.length2() > btScalar(0.0001))
308  {
309  if (castResult.m_fraction < resultCallback.m_closestHitFraction)
310  {
311 #ifdef USE_SUBSIMPLEX_CONVEX_CAST
312  //rotate normal into worldspace
313  castResult.m_normal = rayFromTrans.getBasis() * castResult.m_normal;
314 #endif //USE_SUBSIMPLEX_CONVEX_CAST
315 
316  castResult.m_normal.normalize();
317  btCollisionWorld::LocalRayResult localRayResult
318  (
319  collisionObjectWrap->getCollisionObject(),
320  0,
321  castResult.m_normal,
322  castResult.m_fraction
323  );
324 
325  bool normalInWorldSpace = true;
326  resultCallback.addSingleResult(localRayResult, normalInWorldSpace);
327 
328  }
329  }
330  }
331  } else {
332  if (collisionShape->isConcave())
333  {
334 
335  //ConvexCast::CastResult
336  struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback
337  {
338  btCollisionWorld::RayResultCallback* m_resultCallback;
339  const btCollisionObject* m_collisionObject;
340  const btConcaveShape* m_triangleMesh;
341 
342  btTransform m_colObjWorldTransform;
343 
344  BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,
345  btCollisionWorld::RayResultCallback* resultCallback, const btCollisionObject* collisionObject,const btConcaveShape* triangleMesh,const btTransform& colObjWorldTransform):
346  //@BP Mod
347  btTriangleRaycastCallback(from,to, resultCallback->m_flags),
348  m_resultCallback(resultCallback),
349  m_collisionObject(collisionObject),
350  m_triangleMesh(triangleMesh),
351  m_colObjWorldTransform(colObjWorldTransform)
352  {
353  }
354 
355 
356  virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex )
357  {
359  shapeInfo.m_shapePart = partId;
360  shapeInfo.m_triangleIndex = triangleIndex;
361 
362  btVector3 hitNormalWorld = m_colObjWorldTransform.getBasis() * hitNormalLocal;
363 
365  (m_collisionObject,
366  &shapeInfo,
367  hitNormalWorld,
368  hitFraction);
369 
370  bool normalInWorldSpace = true;
371  return m_resultCallback->addSingleResult(rayResult,normalInWorldSpace);
372  }
373 
374  };
375 
376  btTransform worldTocollisionObject = colObjWorldTransform.inverse();
377  btVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin();
378  btVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin();
379 
380  // BT_PROFILE("rayTestConcave");
381  if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE)
382  {
384  btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape;
385 
386  BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObjectWrap->getCollisionObject(),triangleMesh,colObjWorldTransform);
387  rcb.m_hitFraction = resultCallback.m_closestHitFraction;
388  triangleMesh->performRaycast(&rcb,rayFromLocal,rayToLocal);
389  }
390  else if(collisionShape->getShapeType()==GIMPACT_SHAPE_PROXYTYPE)
391  {
392  btGImpactMeshShape* concaveShape = (btGImpactMeshShape*)collisionShape;
393 
394  BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObjectWrap->getCollisionObject(),concaveShape, colObjWorldTransform);
395  rcb.m_hitFraction = resultCallback.m_closestHitFraction;
396  concaveShape->processAllTrianglesRay(&rcb,rayFromLocal,rayToLocal);
397  }else
398  {
399  //generic (slower) case
400  btConcaveShape* concaveShape = (btConcaveShape*)collisionShape;
401 
402  btTransform worldTocollisionObject = colObjWorldTransform.inverse();
403 
404  btVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin();
405  btVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin();
406 
407  //ConvexCast::CastResult
408 
409  struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback
410  {
411  btCollisionWorld::RayResultCallback* m_resultCallback;
412  const btCollisionObject* m_collisionObject;
413  btConcaveShape* m_triangleMesh;
414 
415  btTransform m_colObjWorldTransform;
416 
417  BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,
418  btCollisionWorld::RayResultCallback* resultCallback, const btCollisionObject* collisionObject,btConcaveShape* triangleMesh, const btTransform& colObjWorldTransform):
419  //@BP Mod
420  btTriangleRaycastCallback(from,to, resultCallback->m_flags),
421  m_resultCallback(resultCallback),
422  m_collisionObject(collisionObject),
423  m_triangleMesh(triangleMesh),
424  m_colObjWorldTransform(colObjWorldTransform)
425  {
426  }
427 
428 
429  virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex )
430  {
432  shapeInfo.m_shapePart = partId;
433  shapeInfo.m_triangleIndex = triangleIndex;
434 
435  btVector3 hitNormalWorld = m_colObjWorldTransform.getBasis() * hitNormalLocal;
436 
438  (m_collisionObject,
439  &shapeInfo,
440  hitNormalWorld,
441  hitFraction);
442 
443  bool normalInWorldSpace = true;
444  return m_resultCallback->addSingleResult(rayResult,normalInWorldSpace);
445  }
446 
447  };
448 
449 
450  BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObjectWrap->getCollisionObject(),concaveShape, colObjWorldTransform);
451  rcb.m_hitFraction = resultCallback.m_closestHitFraction;
452 
453  btVector3 rayAabbMinLocal = rayFromLocal;
454  rayAabbMinLocal.setMin(rayToLocal);
455  btVector3 rayAabbMaxLocal = rayFromLocal;
456  rayAabbMaxLocal.setMax(rayToLocal);
457 
458  concaveShape->processAllTriangles(&rcb,rayAabbMinLocal,rayAabbMaxLocal);
459  }
460  } else {
461  // BT_PROFILE("rayTestCompound");
462  if (collisionShape->isCompound())
463  {
464  struct LocalInfoAdder2 : public RayResultCallback
465  {
466  RayResultCallback* m_userCallback;
467  int m_i;
468 
469  LocalInfoAdder2 (int i, RayResultCallback *user)
470  : m_userCallback(user), m_i(i)
471  {
472  m_closestHitFraction = m_userCallback->m_closestHitFraction;
473  m_flags = m_userCallback->m_flags;
474  }
475  virtual bool needsCollision(btBroadphaseProxy* p) const
476  {
477  return m_userCallback->needsCollision(p);
478  }
479 
480  virtual btScalar addSingleResult (btCollisionWorld::LocalRayResult &r, bool b)
481  {
483  shapeInfo.m_shapePart = -1;
484  shapeInfo.m_triangleIndex = m_i;
485  if (r.m_localShapeInfo == NULL)
486  r.m_localShapeInfo = &shapeInfo;
487 
488  const btScalar result = m_userCallback->addSingleResult(r, b);
489  m_closestHitFraction = m_userCallback->m_closestHitFraction;
490  return result;
491  }
492  };
493 
494  struct RayTester : btDbvt::ICollide
495  {
496  const btCollisionObject* m_collisionObject;
497  const btCompoundShape* m_compoundShape;
498  const btTransform& m_colObjWorldTransform;
499  const btTransform& m_rayFromTrans;
500  const btTransform& m_rayToTrans;
501  RayResultCallback& m_resultCallback;
502 
503  RayTester(const btCollisionObject* collisionObject,
504  const btCompoundShape* compoundShape,
505  const btTransform& colObjWorldTransform,
506  const btTransform& rayFromTrans,
507  const btTransform& rayToTrans,
508  RayResultCallback& resultCallback):
509  m_collisionObject(collisionObject),
510  m_compoundShape(compoundShape),
511  m_colObjWorldTransform(colObjWorldTransform),
512  m_rayFromTrans(rayFromTrans),
513  m_rayToTrans(rayToTrans),
514  m_resultCallback(resultCallback)
515  {
516 
517  }
518 
519  void ProcessLeaf(int i)
520  {
521  const btCollisionShape* childCollisionShape = m_compoundShape->getChildShape(i);
522  const btTransform& childTrans = m_compoundShape->getChildTransform(i);
523  btTransform childWorldTrans = m_colObjWorldTransform * childTrans;
524 
525  btCollisionObjectWrapper tmpOb(0,childCollisionShape,m_collisionObject,childWorldTrans,-1,i);
526  // replace collision shape so that callback can determine the triangle
527 
528 
529 
530  LocalInfoAdder2 my_cb(i, &m_resultCallback);
531 
533  m_rayFromTrans,
534  m_rayToTrans,
535  &tmpOb,
536  my_cb);
537 
538  }
539 
540  void Process(const btDbvtNode* leaf)
541  {
542  ProcessLeaf(leaf->dataAsInt);
543  }
544  };
545 
546  const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(collisionShape);
547  const btDbvt* dbvt = compoundShape->getDynamicAabbTree();
548 
549 
550  RayTester rayCB(
551  collisionObjectWrap->getCollisionObject(),
552  compoundShape,
553  colObjWorldTransform,
554  rayFromTrans,
555  rayToTrans,
556  resultCallback);
557 #ifndef DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION
558  if (dbvt)
559  {
560  btVector3 localRayFrom = colObjWorldTransform.inverseTimes(rayFromTrans).getOrigin();
561  btVector3 localRayTo = colObjWorldTransform.inverseTimes(rayToTrans).getOrigin();
562  btDbvt::rayTest(dbvt->m_root, localRayFrom , localRayTo, rayCB);
563  }
564  else
565 #endif //DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION
566  {
567  for (int i = 0, n = compoundShape->getNumChildShapes(); i < n; ++i)
568  {
569  rayCB.ProcessLeaf(i);
570  }
571  }
572  }
573  }
574  }
575 }
576 
577 void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const btTransform& convexFromTrans,const btTransform& convexToTrans,
578  btCollisionObject* collisionObject,
579  const btCollisionShape* collisionShape,
580  const btTransform& colObjWorldTransform,
581  ConvexResultCallback& resultCallback, btScalar allowedPenetration)
582 {
583  btCollisionObjectWrapper tmpOb(0,collisionShape,collisionObject,colObjWorldTransform,-1,-1);
584  btCollisionWorld::objectQuerySingleInternal(castShape,convexFromTrans,convexToTrans,&tmpOb,resultCallback,allowedPenetration);
585 }
586 
587 void btCollisionWorld::objectQuerySingleInternal(const btConvexShape* castShape,const btTransform& convexFromTrans,const btTransform& convexToTrans,
588  const btCollisionObjectWrapper* colObjWrap,
589  ConvexResultCallback& resultCallback, btScalar allowedPenetration)
590 {
591  const btCollisionShape* collisionShape = colObjWrap->getCollisionShape();
592  const btTransform& colObjWorldTransform = colObjWrap->getWorldTransform();
593 
594  if (collisionShape->isConvex())
595  {
596  //BT_PROFILE("convexSweepConvex");
597  btConvexCast::CastResult castResult;
598  castResult.m_allowedPenetration = allowedPenetration;
599  castResult.m_fraction = resultCallback.m_closestHitFraction;//btScalar(1.);//??
600 
601  btConvexShape* convexShape = (btConvexShape*) collisionShape;
602  btVoronoiSimplexSolver simplexSolver;
603  btGjkEpaPenetrationDepthSolver gjkEpaPenetrationSolver;
604 
605  btContinuousConvexCollision convexCaster1(castShape,convexShape,&simplexSolver,&gjkEpaPenetrationSolver);
606  //btGjkConvexCast convexCaster2(castShape,convexShape,&simplexSolver);
607  //btSubsimplexConvexCast convexCaster3(castShape,convexShape,&simplexSolver);
608 
609  btConvexCast* castPtr = &convexCaster1;
610 
611 
612 
613  if (castPtr->calcTimeOfImpact(convexFromTrans,convexToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
614  {
615  //add hit
616  if (castResult.m_normal.length2() > btScalar(0.0001))
617  {
618  if (castResult.m_fraction < resultCallback.m_closestHitFraction)
619  {
620  castResult.m_normal.normalize();
621  btCollisionWorld::LocalConvexResult localConvexResult
622  (
623  colObjWrap->getCollisionObject(),
624  0,
625  castResult.m_normal,
626  castResult.m_hitPoint,
627  castResult.m_fraction
628  );
629 
630  bool normalInWorldSpace = true;
631  resultCallback.addSingleResult(localConvexResult, normalInWorldSpace);
632 
633  }
634  }
635  }
636  } else {
637  if (collisionShape->isConcave())
638  {
639  if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE)
640  {
641  //BT_PROFILE("convexSweepbtBvhTriangleMesh");
642  btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape;
643  btTransform worldTocollisionObject = colObjWorldTransform.inverse();
644  btVector3 convexFromLocal = worldTocollisionObject * convexFromTrans.getOrigin();
645  btVector3 convexToLocal = worldTocollisionObject * convexToTrans.getOrigin();
646  // rotation of box in local mesh space = MeshRotation^-1 * ConvexToRotation
647  btTransform rotationXform = btTransform(worldTocollisionObject.getBasis() * convexToTrans.getBasis());
648 
649  //ConvexCast::CastResult
650  struct BridgeTriangleConvexcastCallback : public btTriangleConvexcastCallback
651  {
652  btCollisionWorld::ConvexResultCallback* m_resultCallback;
653  const btCollisionObject* m_collisionObject;
654  btTriangleMeshShape* m_triangleMesh;
655 
656  BridgeTriangleConvexcastCallback(const btConvexShape* castShape, const btTransform& from,const btTransform& to,
657  btCollisionWorld::ConvexResultCallback* resultCallback, const btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh, const btTransform& triangleToWorld):
658  btTriangleConvexcastCallback(castShape, from,to, triangleToWorld, triangleMesh->getMargin()),
659  m_resultCallback(resultCallback),
660  m_collisionObject(collisionObject),
661  m_triangleMesh(triangleMesh)
662  {
663  }
664 
665 
666  virtual btScalar reportHit(const btVector3& hitNormalLocal, const btVector3& hitPointLocal, btScalar hitFraction, int partId, int triangleIndex )
667  {
669  shapeInfo.m_shapePart = partId;
670  shapeInfo.m_triangleIndex = triangleIndex;
671  if (hitFraction <= m_resultCallback->m_closestHitFraction)
672  {
673 
675  (m_collisionObject,
676  &shapeInfo,
677  hitNormalLocal,
678  hitPointLocal,
679  hitFraction);
680 
681  bool normalInWorldSpace = true;
682 
683 
684  return m_resultCallback->addSingleResult(convexResult,normalInWorldSpace);
685  }
686  return hitFraction;
687  }
688 
689  };
690 
691  BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,colObjWrap->getCollisionObject(),triangleMesh, colObjWorldTransform);
692  tccb.m_hitFraction = resultCallback.m_closestHitFraction;
693  tccb.m_allowedPenetration = allowedPenetration;
694  btVector3 boxMinLocal, boxMaxLocal;
695  castShape->getAabb(rotationXform, boxMinLocal, boxMaxLocal);
696  triangleMesh->performConvexcast(&tccb,convexFromLocal,convexToLocal,boxMinLocal, boxMaxLocal);
697  } else
698  {
699  if (collisionShape->getShapeType()==STATIC_PLANE_PROXYTYPE)
700  {
701  btConvexCast::CastResult castResult;
702  castResult.m_allowedPenetration = allowedPenetration;
703  castResult.m_fraction = resultCallback.m_closestHitFraction;
704  btStaticPlaneShape* planeShape = (btStaticPlaneShape*) collisionShape;
705  btContinuousConvexCollision convexCaster1(castShape,planeShape);
706  btConvexCast* castPtr = &convexCaster1;
707 
708  if (castPtr->calcTimeOfImpact(convexFromTrans,convexToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
709  {
710  //add hit
711  if (castResult.m_normal.length2() > btScalar(0.0001))
712  {
713  if (castResult.m_fraction < resultCallback.m_closestHitFraction)
714  {
715  castResult.m_normal.normalize();
716  btCollisionWorld::LocalConvexResult localConvexResult
717  (
718  colObjWrap->getCollisionObject(),
719  0,
720  castResult.m_normal,
721  castResult.m_hitPoint,
722  castResult.m_fraction
723  );
724 
725  bool normalInWorldSpace = true;
726  resultCallback.addSingleResult(localConvexResult, normalInWorldSpace);
727  }
728  }
729  }
730 
731  } else
732  {
733  //BT_PROFILE("convexSweepConcave");
734  btConcaveShape* concaveShape = (btConcaveShape*)collisionShape;
735  btTransform worldTocollisionObject = colObjWorldTransform.inverse();
736  btVector3 convexFromLocal = worldTocollisionObject * convexFromTrans.getOrigin();
737  btVector3 convexToLocal = worldTocollisionObject * convexToTrans.getOrigin();
738  // rotation of box in local mesh space = MeshRotation^-1 * ConvexToRotation
739  btTransform rotationXform = btTransform(worldTocollisionObject.getBasis() * convexToTrans.getBasis());
740 
741  //ConvexCast::CastResult
742  struct BridgeTriangleConvexcastCallback : public btTriangleConvexcastCallback
743  {
744  btCollisionWorld::ConvexResultCallback* m_resultCallback;
745  const btCollisionObject* m_collisionObject;
746  btConcaveShape* m_triangleMesh;
747 
748  BridgeTriangleConvexcastCallback(const btConvexShape* castShape, const btTransform& from,const btTransform& to,
749  btCollisionWorld::ConvexResultCallback* resultCallback, const btCollisionObject* collisionObject,btConcaveShape* triangleMesh, const btTransform& triangleToWorld):
750  btTriangleConvexcastCallback(castShape, from,to, triangleToWorld, triangleMesh->getMargin()),
751  m_resultCallback(resultCallback),
752  m_collisionObject(collisionObject),
753  m_triangleMesh(triangleMesh)
754  {
755  }
756 
757 
758  virtual btScalar reportHit(const btVector3& hitNormalLocal, const btVector3& hitPointLocal, btScalar hitFraction, int partId, int triangleIndex )
759  {
761  shapeInfo.m_shapePart = partId;
762  shapeInfo.m_triangleIndex = triangleIndex;
763  if (hitFraction <= m_resultCallback->m_closestHitFraction)
764  {
765 
767  (m_collisionObject,
768  &shapeInfo,
769  hitNormalLocal,
770  hitPointLocal,
771  hitFraction);
772 
773  bool normalInWorldSpace = false;
774 
775  return m_resultCallback->addSingleResult(convexResult,normalInWorldSpace);
776  }
777  return hitFraction;
778  }
779 
780  };
781 
782  BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,colObjWrap->getCollisionObject(),concaveShape, colObjWorldTransform);
783  tccb.m_hitFraction = resultCallback.m_closestHitFraction;
784  tccb.m_allowedPenetration = allowedPenetration;
785  btVector3 boxMinLocal, boxMaxLocal;
786  castShape->getAabb(rotationXform, boxMinLocal, boxMaxLocal);
787 
788  btVector3 rayAabbMinLocal = convexFromLocal;
789  rayAabbMinLocal.setMin(convexToLocal);
790  btVector3 rayAabbMaxLocal = convexFromLocal;
791  rayAabbMaxLocal.setMax(convexToLocal);
792  rayAabbMinLocal += boxMinLocal;
793  rayAabbMaxLocal += boxMaxLocal;
794  concaveShape->processAllTriangles(&tccb,rayAabbMinLocal,rayAabbMaxLocal);
795  }
796  }
797  } else {
799  if (collisionShape->isCompound())
800  {
801  BT_PROFILE("convexSweepCompound");
802  const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(collisionShape);
803  int i=0;
804  for (i=0;i<compoundShape->getNumChildShapes();i++)
805  {
806  btTransform childTrans = compoundShape->getChildTransform(i);
807  const btCollisionShape* childCollisionShape = compoundShape->getChildShape(i);
808  btTransform childWorldTrans = colObjWorldTransform * childTrans;
809 
810  struct LocalInfoAdder : public ConvexResultCallback {
811  ConvexResultCallback* m_userCallback;
812  int m_i;
813 
814  LocalInfoAdder (int i, ConvexResultCallback *user)
815  : m_userCallback(user), m_i(i)
816  {
817  m_closestHitFraction = m_userCallback->m_closestHitFraction;
818  }
819  virtual bool needsCollision(btBroadphaseProxy* p) const
820  {
821  return m_userCallback->needsCollision(p);
822  }
823  virtual btScalar addSingleResult (btCollisionWorld::LocalConvexResult& r, bool b)
824  {
826  shapeInfo.m_shapePart = -1;
827  shapeInfo.m_triangleIndex = m_i;
828  if (r.m_localShapeInfo == NULL)
829  r.m_localShapeInfo = &shapeInfo;
830  const btScalar result = m_userCallback->addSingleResult(r, b);
831  m_closestHitFraction = m_userCallback->m_closestHitFraction;
832  return result;
833 
834  }
835  };
836 
837  LocalInfoAdder my_cb(i, &resultCallback);
838 
839  btCollisionObjectWrapper tmpObj(colObjWrap,childCollisionShape,colObjWrap->getCollisionObject(),childWorldTrans,-1,i);
840 
841  objectQuerySingleInternal(castShape, convexFromTrans,convexToTrans,
842  &tmpObj,my_cb, allowedPenetration);
843 
844  }
845  }
846  }
847  }
848 }
849 
850 
852 {
853 
859 
862 
863  btSingleRayCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld,const btCollisionWorld* world,btCollisionWorld::RayResultCallback& resultCallback)
864  :m_rayFromWorld(rayFromWorld),
865  m_rayToWorld(rayToWorld),
866  m_world(world),
867  m_resultCallback(resultCallback)
868  {
873 
874  btVector3 rayDir = (rayToWorld-rayFromWorld);
875 
876  rayDir.normalize ();
878  m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0];
879  m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1];
880  m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[2];
881  m_signs[0] = m_rayDirectionInverse[0] < 0.0;
882  m_signs[1] = m_rayDirectionInverse[1] < 0.0;
883  m_signs[2] = m_rayDirectionInverse[2] < 0.0;
884 
886 
887  }
888 
889 
890 
891  virtual bool process(const btBroadphaseProxy* proxy)
892  {
895  return false;
896 
897  btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject;
898 
899  //only perform raycast if filterMask matches
900  if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
901  {
902  //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
903  //btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
904 #if 0
905 #ifdef RECALCULATE_AABB
906  btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
907  collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
908 #else
909  //getBroadphase()->getAabb(collisionObject->getBroadphaseHandle(),collisionObjectAabbMin,collisionObjectAabbMax);
910  const btVector3& collisionObjectAabbMin = collisionObject->getBroadphaseHandle()->m_aabbMin;
911  const btVector3& collisionObjectAabbMax = collisionObject->getBroadphaseHandle()->m_aabbMax;
912 #endif
913 #endif
914  //btScalar hitLambda = m_resultCallback.m_closestHitFraction;
915  //culling already done by broadphase
916  //if (btRayAabb(m_rayFromWorld,m_rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,m_hitNormal))
917  {
919  collisionObject,
920  collisionObject->getCollisionShape(),
921  collisionObject->getWorldTransform(),
923  }
924  }
925  return true;
926  }
927 };
928 
929 void btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const
930 {
931  //BT_PROFILE("rayTest");
934  btSingleRayCallback rayCB(rayFromWorld,rayToWorld,this,resultCallback);
935 
936 #ifndef USE_BRUTEFORCE_RAYBROADPHASE
937  m_broadphasePairCache->rayTest(rayFromWorld,rayToWorld,rayCB);
938 #else
939  for (int i=0;i<this->getNumCollisionObjects();i++)
940  {
941  rayCB.process(m_collisionObjects[i]->getBroadphaseHandle());
942  }
943 #endif //USE_BRUTEFORCE_RAYBROADPHASE
944 
945 }
946 
947 
949 {
950 
958 
959 
960  btSingleSweepCallback(const btConvexShape* castShape, const btTransform& convexFromTrans,const btTransform& convexToTrans,const btCollisionWorld* world,btCollisionWorld::ConvexResultCallback& resultCallback,btScalar allowedPenetration)
961  :m_convexFromTrans(convexFromTrans),
962  m_convexToTrans(convexToTrans),
963  m_world(world),
964  m_resultCallback(resultCallback),
965  m_allowedCcdPenetration(allowedPenetration),
966  m_castShape(castShape)
967  {
969  btVector3 rayDir = unnormalizedRayDir.normalized();
971  m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0];
972  m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1];
973  m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[2];
974  m_signs[0] = m_rayDirectionInverse[0] < 0.0;
975  m_signs[1] = m_rayDirectionInverse[1] < 0.0;
976  m_signs[2] = m_rayDirectionInverse[2] < 0.0;
977 
978  m_lambda_max = rayDir.dot(unnormalizedRayDir);
979 
980  }
981 
982  virtual bool process(const btBroadphaseProxy* proxy)
983  {
986  return false;
987 
988  btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject;
989 
990  //only perform raycast if filterMask matches
991  if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) {
992  //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
994  collisionObject,
995  collisionObject->getCollisionShape(),
996  collisionObject->getWorldTransform(),
999  }
1000 
1001  return true;
1002  }
1003 };
1004 
1005 
1006 
1007 void btCollisionWorld::convexSweepTest(const btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration) const
1008 {
1009 
1010  BT_PROFILE("convexSweepTest");
1014 
1015 
1016 
1017  btTransform convexFromTrans,convexToTrans;
1018  convexFromTrans = convexFromWorld;
1019  convexToTrans = convexToWorld;
1020  btVector3 castShapeAabbMin, castShapeAabbMax;
1021  /* Compute AABB that encompasses angular movement */
1022  {
1023  btVector3 linVel, angVel;
1024  btTransformUtil::calculateVelocity (convexFromTrans, convexToTrans, 1.0f, linVel, angVel);
1025  btVector3 zeroLinVel;
1026  zeroLinVel.setValue(0,0,0);
1027  btTransform R;
1028  R.setIdentity ();
1029  R.setRotation (convexFromTrans.getRotation());
1030  castShape->calculateTemporalAabb (R, zeroLinVel, angVel, 1.0f, castShapeAabbMin, castShapeAabbMax);
1031  }
1032 
1033 #ifndef USE_BRUTEFORCE_RAYBROADPHASE
1034 
1035  btSingleSweepCallback convexCB(castShape,convexFromWorld,convexToWorld,this,resultCallback,allowedCcdPenetration);
1036 
1037  m_broadphasePairCache->rayTest(convexFromTrans.getOrigin(),convexToTrans.getOrigin(),convexCB,castShapeAabbMin,castShapeAabbMax);
1038 
1039 #else
1040  // do a ray-shape query using convexCaster (CCD)
1042  int i;
1043  for (i=0;i<m_collisionObjects.size();i++)
1044  {
1045  btCollisionObject* collisionObject= m_collisionObjects[i];
1046  //only perform raycast if filterMask matches
1047  if(resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) {
1048  //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
1049  btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
1050  collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
1051  AabbExpand (collisionObjectAabbMin, collisionObjectAabbMax, castShapeAabbMin, castShapeAabbMax);
1052  btScalar hitLambda = btScalar(1.); //could use resultCallback.m_closestHitFraction, but needs testing
1053  btVector3 hitNormal;
1054  if (btRayAabb(convexFromWorld.getOrigin(),convexToWorld.getOrigin(),collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,hitNormal))
1055  {
1056  objectQuerySingle(castShape, convexFromTrans,convexToTrans,
1057  collisionObject,
1058  collisionObject->getCollisionShape(),
1059  collisionObject->getWorldTransform(),
1060  resultCallback,
1061  allowedCcdPenetration);
1062  }
1063  }
1064  }
1065 #endif //USE_BRUTEFORCE_RAYBROADPHASE
1066 }
1067 
1068 
1069 
1071 {
1072 
1074 
1076  :btManifoldResult(obj0Wrap,obj1Wrap),
1077  m_resultCallback(resultCallback)
1078  {
1079  }
1080 
1081  virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)
1082  {
1083  bool isSwapped = m_manifoldPtr->getBody0() != m_body0Wrap->getCollisionObject();
1084  btVector3 pointA = pointInWorld + normalOnBInWorld * depth;
1085  btVector3 localA;
1086  btVector3 localB;
1087  if (isSwapped)
1088  {
1089  localA = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointA );
1090  localB = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld);
1091  } else
1092  {
1093  localA = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointA );
1094  localB = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld);
1095  }
1096 
1097  btManifoldPoint newPt(localA,localB,normalOnBInWorld,depth);
1098  newPt.m_positionWorldOnA = pointA;
1099  newPt.m_positionWorldOnB = pointInWorld;
1100 
1101  //BP mod, store contact triangles.
1102  if (isSwapped)
1103  {
1104  newPt.m_partId0 = m_partId1;
1105  newPt.m_partId1 = m_partId0;
1106  newPt.m_index0 = m_index1;
1107  newPt.m_index1 = m_index0;
1108  } else
1109  {
1110  newPt.m_partId0 = m_partId0;
1111  newPt.m_partId1 = m_partId1;
1112  newPt.m_index0 = m_index0;
1113  newPt.m_index1 = m_index1;
1114  }
1115 
1116  //experimental feature info, for per-triangle material etc.
1117  const btCollisionObjectWrapper* obj0Wrap = isSwapped? m_body1Wrap : m_body0Wrap;
1118  const btCollisionObjectWrapper* obj1Wrap = isSwapped? m_body0Wrap : m_body1Wrap;
1119  m_resultCallback.addSingleResult(newPt,obj0Wrap,newPt.m_partId0,newPt.m_index0,obj1Wrap,newPt.m_partId1,newPt.m_index1);
1120 
1121  }
1122 
1123 };
1124 
1125 
1126 
1128 {
1129 
1133 
1134 
1136  :m_collisionObject(collisionObject),
1137  m_world(world),
1138  m_resultCallback(resultCallback)
1139  {
1140  }
1141 
1142  virtual bool process(const btBroadphaseProxy* proxy)
1143  {
1144  btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject;
1145  if (collisionObject == m_collisionObject)
1146  return true;
1147 
1148  //only perform raycast if filterMask matches
1149  if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
1150  {
1152  btCollisionObjectWrapper ob1(0,collisionObject->getCollisionShape(),collisionObject,collisionObject->getWorldTransform(),-1,-1);
1153 
1154  btCollisionAlgorithm* algorithm = m_world->getDispatcher()->findAlgorithm(&ob0,&ob1);
1155  if (algorithm)
1156  {
1157  btBridgedManifoldResult contactPointResult(&ob0,&ob1, m_resultCallback);
1158  //discrete collision detection query
1159 
1160  algorithm->processCollision(&ob0,&ob1, m_world->getDispatchInfo(),&contactPointResult);
1161 
1162  algorithm->~btCollisionAlgorithm();
1164  }
1165  }
1166  return true;
1167  }
1168 };
1169 
1170 
1174 {
1175  btVector3 aabbMin,aabbMax;
1176  colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(),aabbMin,aabbMax);
1177  btSingleContactCallback contactCB(colObj,this,resultCallback);
1178 
1179  m_broadphasePairCache->aabbTest(aabbMin,aabbMax,contactCB);
1180 }
1181 
1182 
1186 {
1187  btCollisionObjectWrapper obA(0,colObjA->getCollisionShape(),colObjA,colObjA->getWorldTransform(),-1,-1);
1188  btCollisionObjectWrapper obB(0,colObjB->getCollisionShape(),colObjB,colObjB->getWorldTransform(),-1,-1);
1189 
1190  btCollisionAlgorithm* algorithm = getDispatcher()->findAlgorithm(&obA,&obB);
1191  if (algorithm)
1192  {
1193  btBridgedManifoldResult contactPointResult(&obA,&obB, resultCallback);
1194  //discrete collision detection query
1195  algorithm->processCollision(&obA,&obB, getDispatchInfo(),&contactPointResult);
1196 
1197  algorithm->~btCollisionAlgorithm();
1198  getDispatcher()->freeCollisionAlgorithm(algorithm);
1199  }
1200 
1201 }
1202 
1203 
1204 
1205 
1207 {
1211 
1212 public:
1213 
1214  DebugDrawcallback(btIDebugDraw* debugDrawer,const btTransform& worldTrans,const btVector3& color) :
1215  m_debugDrawer(debugDrawer),
1216  m_color(color),
1217  m_worldTrans(worldTrans)
1218  {
1219  }
1220 
1221  virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex)
1222  {
1223  processTriangle(triangle,partId,triangleIndex);
1224  }
1225 
1226  virtual void processTriangle(btVector3* triangle,int partId, int triangleIndex)
1227  {
1228  (void)partId;
1229  (void)triangleIndex;
1230 
1231  btVector3 wv0,wv1,wv2;
1232  wv0 = m_worldTrans*triangle[0];
1233  wv1 = m_worldTrans*triangle[1];
1234  wv2 = m_worldTrans*triangle[2];
1235  btVector3 center = (wv0+wv1+wv2)*btScalar(1./3.);
1236 
1238  {
1239  btVector3 normal = (wv1-wv0).cross(wv2-wv0);
1240  normal.normalize();
1241  btVector3 normalColor(1,1,0);
1242  m_debugDrawer->drawLine(center,center+normal,normalColor);
1243  }
1244  m_debugDrawer->drawLine(wv0,wv1,m_color);
1245  m_debugDrawer->drawLine(wv1,wv2,m_color);
1246  m_debugDrawer->drawLine(wv2,wv0,m_color);
1247  }
1248 };
1249 
1250 
1251 void btCollisionWorld::debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color)
1252 {
1253  // Draw a small simplex at the center of the object
1254  getDebugDrawer()->drawTransform(worldTransform,1);
1255 
1256  if (shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE)
1257  {
1258  const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(shape);
1259  for (int i=compoundShape->getNumChildShapes()-1;i>=0;i--)
1260  {
1261  btTransform childTrans = compoundShape->getChildTransform(i);
1262  const btCollisionShape* colShape = compoundShape->getChildShape(i);
1263  debugDrawObject(worldTransform*childTrans,colShape,color);
1264  }
1265 
1266  } else
1267  {
1268 
1269  switch (shape->getShapeType())
1270  {
1271 
1272  case BOX_SHAPE_PROXYTYPE:
1273  {
1274  const btBoxShape* boxShape = static_cast<const btBoxShape*>(shape);
1275  btVector3 halfExtents = boxShape->getHalfExtentsWithMargin();
1276  getDebugDrawer()->drawBox(-halfExtents,halfExtents,worldTransform,color);
1277  break;
1278  }
1279 
1281  {
1282  const btSphereShape* sphereShape = static_cast<const btSphereShape*>(shape);
1283  btScalar radius = sphereShape->getMargin();//radius doesn't include the margin, so draw with margin
1284 
1285  getDebugDrawer()->drawSphere(radius, worldTransform, color);
1286  break;
1287  }
1289  {
1290  const btMultiSphereShape* multiSphereShape = static_cast<const btMultiSphereShape*>(shape);
1291 
1292  btTransform childTransform;
1293  childTransform.setIdentity();
1294 
1295  for (int i = multiSphereShape->getSphereCount()-1; i>=0;i--)
1296  {
1297  childTransform.setOrigin(multiSphereShape->getSpherePosition(i));
1298  getDebugDrawer()->drawSphere(multiSphereShape->getSphereRadius(i), worldTransform*childTransform, color);
1299  }
1300 
1301  break;
1302  }
1304  {
1305  const btCapsuleShape* capsuleShape = static_cast<const btCapsuleShape*>(shape);
1306 
1307  btScalar radius = capsuleShape->getRadius();
1308  btScalar halfHeight = capsuleShape->getHalfHeight();
1309 
1310  int upAxis = capsuleShape->getUpAxis();
1311  getDebugDrawer()->drawCapsule(radius, halfHeight, upAxis, worldTransform, color);
1312  break;
1313  }
1314  case CONE_SHAPE_PROXYTYPE:
1315  {
1316  const btConeShape* coneShape = static_cast<const btConeShape*>(shape);
1317  btScalar radius = coneShape->getRadius();//+coneShape->getMargin();
1318  btScalar height = coneShape->getHeight();//+coneShape->getMargin();
1319 
1320  int upAxis= coneShape->getConeUpIndex();
1321  getDebugDrawer()->drawCone(radius, height, upAxis, worldTransform, color);
1322  break;
1323 
1324  }
1326  {
1327  const btCylinderShape* cylinder = static_cast<const btCylinderShape*>(shape);
1328  int upAxis = cylinder->getUpAxis();
1329  btScalar radius = cylinder->getRadius();
1330  btScalar halfHeight = cylinder->getHalfExtentsWithMargin()[upAxis];
1331  getDebugDrawer()->drawCylinder(radius, halfHeight, upAxis, worldTransform, color);
1332  break;
1333  }
1334 
1336  {
1337  const btStaticPlaneShape* staticPlaneShape = static_cast<const btStaticPlaneShape*>(shape);
1338  btScalar planeConst = staticPlaneShape->getPlaneConstant();
1339  const btVector3& planeNormal = staticPlaneShape->getPlaneNormal();
1340  getDebugDrawer()->drawPlane(planeNormal, planeConst,worldTransform, color);
1341  break;
1342 
1343  }
1344  default:
1345  {
1346 
1348  if (shape->isPolyhedral())
1349  {
1350  btPolyhedralConvexShape* polyshape = (btPolyhedralConvexShape*) shape;
1351 
1352  int i;
1353  if (polyshape->getConvexPolyhedron())
1354  {
1355  const btConvexPolyhedron* poly = polyshape->getConvexPolyhedron();
1356  for (i=0;i<poly->m_faces.size();i++)
1357  {
1358  btVector3 centroid(0,0,0);
1359  int numVerts = poly->m_faces[i].m_indices.size();
1360  if (numVerts)
1361  {
1362  int lastV = poly->m_faces[i].m_indices[numVerts-1];
1363  for (int v=0;v<poly->m_faces[i].m_indices.size();v++)
1364  {
1365  int curVert = poly->m_faces[i].m_indices[v];
1366  centroid+=poly->m_vertices[curVert];
1367  getDebugDrawer()->drawLine(worldTransform*poly->m_vertices[lastV],worldTransform*poly->m_vertices[curVert],color);
1368  lastV = curVert;
1369  }
1370  }
1371  centroid*= btScalar(1.f)/btScalar(numVerts);
1372  if (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawNormals)
1373  {
1374  btVector3 normalColor(1,1,0);
1375  btVector3 faceNormal(poly->m_faces[i].m_plane[0],poly->m_faces[i].m_plane[1],poly->m_faces[i].m_plane[2]);
1376  getDebugDrawer()->drawLine(worldTransform*centroid,worldTransform*(centroid+faceNormal),normalColor);
1377  }
1378 
1379  }
1380 
1381 
1382  } else
1383  {
1384  for (i=0;i<polyshape->getNumEdges();i++)
1385  {
1386  btVector3 a,b;
1387  polyshape->getEdge(i,a,b);
1388  btVector3 wa = worldTransform * a;
1389  btVector3 wb = worldTransform * b;
1390  getDebugDrawer()->drawLine(wa,wb,color);
1391  }
1392  }
1393 
1394 
1395  }
1396 
1397  if (shape->isConcave())
1398  {
1399  btConcaveShape* concaveMesh = (btConcaveShape*) shape;
1400 
1404 
1405  DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color);
1406  concaveMesh->processAllTriangles(&drawCallback,aabbMin,aabbMax);
1407 
1408  }
1409 
1411  {
1413  //todo: pass camera for some culling
1416  //DebugDrawcallback drawCallback;
1417  DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color);
1418  convexMesh->getMeshInterface()->InternalProcessAllTriangles(&drawCallback,aabbMin,aabbMax);
1419  }
1420 
1421 
1422 
1423  }
1424 
1425  }
1426  }
1427 }
1428 
1429 
1431 {
1433  {
1434  int numManifolds = getDispatcher()->getNumManifolds();
1435  btVector3 color(1,1,0);
1436  for (int i=0;i<numManifolds;i++)
1437  {
1439  //btCollisionObject* obA = static_cast<btCollisionObject*>(contactManifold->getBody0());
1440  //btCollisionObject* obB = static_cast<btCollisionObject*>(contactManifold->getBody1());
1441 
1442  int numContacts = contactManifold->getNumContacts();
1443  for (int j=0;j<numContacts;j++)
1444  {
1445  btManifoldPoint& cp = contactManifold->getContactPoint(j);
1447  }
1448  }
1449  }
1450 
1452  {
1453  int i;
1454 
1455  for ( i=0;i<m_collisionObjects.size();i++)
1456  {
1459  {
1461  {
1462  btVector3 color(btScalar(1.),btScalar(1.),btScalar(1.));
1463  switch(colObj->getActivationState())
1464  {
1465  case ACTIVE_TAG:
1466  color = btVector3(btScalar(1.),btScalar(1.),btScalar(1.)); break;
1467  case ISLAND_SLEEPING:
1468  color = btVector3(btScalar(0.),btScalar(1.),btScalar(0.));break;
1469  case WANTS_DEACTIVATION:
1470  color = btVector3(btScalar(0.),btScalar(1.),btScalar(1.));break;
1471  case DISABLE_DEACTIVATION:
1472  color = btVector3(btScalar(1.),btScalar(0.),btScalar(0.));break;
1473  case DISABLE_SIMULATION:
1474  color = btVector3(btScalar(1.),btScalar(1.),btScalar(0.));break;
1475  default:
1476  {
1477  color = btVector3(btScalar(1),btScalar(0.),btScalar(0.));
1478  }
1479  };
1480 
1481  debugDrawObject(colObj->getWorldTransform(),colObj->getCollisionShape(),color);
1482  }
1484  {
1485  btVector3 minAabb,maxAabb;
1486  btVector3 colorvec(1,0,0);
1487  colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);
1489  minAabb -= contactThreshold;
1490  maxAabb += contactThreshold;
1491 
1492  btVector3 minAabb2,maxAabb2;
1493 
1494  if(getDispatchInfo().m_useContinuous && colObj->getInternalType()==btCollisionObject::CO_RIGID_BODY && !colObj->isStaticOrKinematicObject())
1495  {
1496  colObj->getCollisionShape()->getAabb(colObj->getInterpolationWorldTransform(),minAabb2,maxAabb2);
1497  minAabb2 -= contactThreshold;
1498  maxAabb2 += contactThreshold;
1499  minAabb.setMin(minAabb2);
1500  maxAabb.setMax(maxAabb2);
1501  }
1502 
1503  m_debugDrawer->drawAabb(minAabb,maxAabb,colorvec);
1504  }
1505  }
1506 
1507  }
1508  }
1509 }
1510 
1511 
1513 {
1514  int i;
1515  //serialize all collision objects
1516  for (i=0;i<m_collisionObjects.size();i++)
1517  {
1520  {
1521  colObj->serializeSingleObject(serializer);
1522  }
1523  }
1524 
1526  btHashMap<btHashPtr,btCollisionShape*> serializedShapes;
1527 
1528  for (i=0;i<m_collisionObjects.size();i++)
1529  {
1531  btCollisionShape* shape = colObj->getCollisionShape();
1532 
1533  if (!serializedShapes.find(shape))
1534  {
1535  serializedShapes.insert(shape,shape);
1536  shape->serializeSingleShape(serializer);
1537  }
1538  }
1539 
1540 }
1541 
1542 
1544 {
1545 
1546  serializer->startSerialization();
1547 
1548  serializeCollisionObjects(serializer);
1549 
1550  serializer->finishSerialization();
1551 }
1552 
void setOrigin(const btVector3 &origin)
Set the translational element.
Definition: btTransform.h:150
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)
btVector3 getHalfExtentsWithMargin() const
int getShapeType() const
#define BT_LARGE_FLOAT
Definition: btScalar.h:268
btConvexCast is an interface for Casting
Definition: btConvexCast.h:27
virtual btCollisionAlgorithm * findAlgorithm(const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap, btPersistentManifold *sharedManifold=0)=0
btQuaternion getRotation() const
Return a quaternion representing the rotation.
Definition: btTransform.h:122
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
Definition: btVector3.h:640
void performRaycast(btTriangleCallback *callback, const btVector3 &raySource, const btVector3 &rayTarget)
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 updateAabbs()
btScalar getRadius() const
Definition: btConeShape.h:43
btPersistentManifold * m_manifoldPtr
virtual btScalar getRadius() 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
int getLifeTime() const
bool m_forceUpdateAllAabbs
m_forceUpdateAllAabbs can be set to false as an optimization to only update active object AABBs it is...
btVector3 getHalfExtentsWithMargin() const
Definition: btBoxShape.h:36
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
int getInternalType() const
reserved for Bullet internal usage
The btMultiSphereShape represents the convex hull of a collection of spheres.
virtual void drawBox(const btVector3 &bbMin, const btVector3 &bbMax, const btVector3 &color)
Definition: btIDebugDraw.h:276
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 btVector3 & getPlaneNormal() const
btScalar getSphereRadius(int index) const
void setIdentity()
Set this transformation to the identity.
Definition: btTransform.h:172
#define btAssert(x)
Definition: btScalar.h:101
virtual void drawPlane(const btVector3 &planeNormal, btScalar planeConst, const btTransform &transform, const btVector3 &color)
Definition: btIDebugDraw.h:428
ContactResultCallback is used to report contact points.
btCollisionConfiguration allows to configure Bullet collision detection stack allocator size...
The btDbvt class implements a fast dynamic bounding volume tree based on axis aligned bounding boxes ...
Definition: btDbvt.h:194
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...
int getNumCollisionObjects() const
The btSphereShape implements an implicit sphere, centered around a local origin with radius...
Definition: btSphereShape.h:22
btDbvtNode * m_root
Definition: btDbvt.h:258
btCollisionWorld::RayResultCallback & m_resultCallback
ManifoldContactPoint collects and maintains persistent contactpoints.
btScalar getRadius() const
const btCollisionWorld * m_world
int getCollisionFlags() const
const btCollisionObject * getBody0() const
btDispatcher * m_dispatcher1
btManifoldResult is a helper class to manage contact results.
virtual void serializeSingleShape(btSerializer *serializer) const
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:1007
static void rayTestSingleInternal(const btTransform &rayFromTrans, const btTransform &rayToTrans, const btCollisionObjectWrapper *collisionObjectWrap, RayResultCallback &resultCallback)
const btDbvt * getDynamicAabbTree() const
int getConeUpIndex() const
Definition: btConeShape.h:82
This class manages a mesh supplied by the btStridingMeshInterface interface.
Used for GIMPACT Trimesh integration.
virtual void computeOverlappingPairs()
the computeOverlappingPairs is usually already called by performDiscreteCollisionDetection (or stepSi...
btCollisionObject * m_collisionObject
#define ISLAND_SLEEPING
virtual void drawCapsule(btScalar radius, btScalar halfHeight, int upAxis, const btTransform &transform, const btVector3 &color)
Definition: btIDebugDraw.h:307
btSingleRayCallback(const btVector3 &rayFromWorld, const btVector3 &rayToWorld, const btCollisionWorld *world, btCollisionWorld::RayResultCallback &resultCallback)
virtual void processAllTriangles(btTriangleCallback *callback, const btVector3 &aabbMin, const btVector3 &aabbMax) const =0
int getUpAxis() const
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...
btScalar dot(const btVector3 &v) const
Return the dot product.
Definition: btVector3.h:235
const btCollisionObjectWrapper * m_body1Wrap
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:297
The btConvexShape is an abstract shape interface, implemented by all convex shapes such as btBoxShape...
Definition: btConvexShape.h:31
const btTransform & getInterpolationWorldTransform() const
GjkConvexCast performs a raycast on a convex object using support mapping.
The btTriangleMeshShape is an internal concave triangle mesh interface. Don't use this class directly...
bool isConcave() const
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
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
void setActivationState(int newState) const
btTransform & getWorldTransform()
btVector3 m_normalWorldOnB
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:391
int size() const
return the number of elements in the array
btVector3 & getOrigin()
Return the origin vector translation.
Definition: btTransform.h:117
void getAabb(const btTransform &t, btVector3 &aabbMin, btVector3 &aabbMax) const =0
getAabb's default implementation is brute force, expected derived classes to implement a fast dedicat...
btBroadphaseProxy * getBroadphaseHandle()
int getUpAxis() const
btVoronoiSimplexSolver is an implementation of the closest point distance algorithm from a 1-4 points...
const btCollisionWorld * m_world
btCollisionWorld::ConvexResultCallback & m_resultCallback
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...
btIDebugDraw * m_debugDrawer
virtual btIDebugDraw * getDebugDrawer()
int getSphereCount() const
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)
virtual void processAllTrianglesRay(btTriangleCallback *callback, const btVector3 &rayFrom, const btVector3 &rayTo) const
Function for retrieve triangles.
btSingleContactCallback(btCollisionObject *collisionObject, btCollisionWorld *world, btCollisionWorld::ContactResultCallback &resultCallback)
bool isStaticObject() const
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
btScalar getHeight() const
Definition: btConeShape.h:44
const btConvexPolyhedron * getConvexPolyhedron() 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...
bool isStaticOrKinematicObject() const
const btTransform & getWorldTransform() const
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.
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:28
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:107
btVector3 m_positionWorldOnA
m_positionWorldOnA is redundant information, see getPositionWorldOnA(), but for clarity ...
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()
btTransform inverse() const
Return the inverse of this transform.
Definition: btTransform.h:188
The btBroadphaseInterface class provides an interface to detect aabb-overlapping object pairs...
const btManifoldPoint & getContactPoint(int index) const
virtual bool needsCollision(btBroadphaseProxy *proxy0) const
btDispatcher * getDispatcher()
The btBroadphaseProxy is the main class that can be used with the Bullet broadphases.
const btCollisionShape * getCollisionShape() const
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 invXform(const btVector3 &inVec) const
Definition: btTransform.h:223
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:83
const Value * find(const Key &key) const
Definition: btHashMap.h:402
btScalar length2() const
Return the length of the vector squared.
Definition: btVector3.h:257
virtual bool needsCollision(btBroadphaseProxy *proxy0) const
virtual void serialize(btSerializer *serializer)
Preliminary serialization test for Bullet 2.76. Loading those files requires a separate parser (Bulle...
virtual int getNumManifolds() const =0
const btBroadphaseInterface * getBroadphase() const
#define BT_PROFILE(name)
Definition: btQuickprof.h:191
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' paper "Ray Casting against bteral Convex Obje...
CollisionWorld is interface and container for the collision detection.
virtual bool process(const btBroadphaseProxy *proxy)
EpaPenetrationDepthSolver uses the Expanding Polytope Algorithm to calculate the penetration depth be...
bool isConvex() const
void setBroadphaseHandle(btBroadphaseProxy *handle)
btDispatcherInfo & getDispatchInfo()
bool isCompound() const
btVector3 normalized() const
Return a normalized version of this vector.
Definition: btVector3.h:951
bool isPolyhedral() const
#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:136
virtual bool needsCollision(btBroadphaseProxy *proxy0) const
int findLinearSearch(const T &key) const
virtual btScalar getMargin() const
Definition: btSphereShape.h:62
virtual int getDebugMode() const =0
btAlignedObjectArray< btCollisionObject * > m_collisionObjects
static float4 cross(const float4 &a, const float4 &b)
The btCylinderShape class implements a cylinder shape primitive, centered around the origin...
#define DISABLE_DEACTIVATION
virtual bool process(const btBroadphaseProxy *proxy)
virtual void serializeSingleObject(class btSerializer *serializer) const
btVector3 m_rayDirectionInverse
added some cached data to accelerate ray-AABB tests
int dataAsInt
Definition: btDbvt.h:187
virtual void performDiscreteCollisionDetection()
btBroadphaseInterface * m_broadphasePairCache
virtual void setAabb(btBroadphaseProxy *proxy, const btVector3 &aabbMin, const btVector3 &aabbMax, btDispatcher *dispatcher)=0
const btCollisionObjectWrapper * m_body0Wrap
const btConvexShape * m_castShape
btCollisionWorld * m_world
virtual btScalar getMargin() const
virtual btScalar addSingleResult(LocalConvexResult &convexResult, bool normalInWorldSpace)=0
void updateSingleAabb(btCollisionObject *colObj)
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:609
class btStridingMeshInterface * getMeshInterface()
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...
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)
btScalar getDistance() const
virtual bool process(const btBroadphaseProxy *proxy)
btCollisionShape * getChildShape(int index)
const btVector3 & getSpherePosition(int index) const
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
btScalar getHalfHeight() const
btCollisionAlgorithm is an collision interface that is compatible with the Broadphase and btDispatche...
const btCollisionShape * getCollisionShape() const
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:63
bool btRayAabb(const btVector3 &rayFrom, const btVector3 &rayTo, const btVector3 &aabbMin, const btVector3 &aabbMax, btScalar &param, btVector3 &normal)
Definition: btAabbUtil2.h:125
int getActivationState() const
virtual void destroyProxy(btBroadphaseProxy *proxy, btDispatcher *dispatcher)=0
virtual void addContactPoint(const btVector3 &normalOnBInWorld, const btVector3 &pointInWorld, btScalar depth)
btCollisionWorld::ContactResultCallback & m_resultCallback
virtual void drawCylinder(btScalar radius, btScalar halfHeight, int upAxis, const btTransform &transform, const btVector3 &color)
Definition: btIDebugDraw.h:365
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)
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:626
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:266
bool isActive() const
virtual void InternalProcessAllTriangles(btInternalTriangleIndexCallback *callback, const btVector3 &aabbMin, const btVector3 &aabbMax) const
const btScalar & getPlaneConstant() const
virtual void aabbTest(const btVector3 &aabbMin, const btVector3 &aabbMax, btBroadphaseAabbCallback &callback)=0
const btCollisionObject * getCollisionObject() const
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
int getNumChildShapes() const
virtual int getNumEdges() const =0