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
33 #include "LinearMath/btAabbUtil2.h"
34 #include "LinearMath/btQuickprof.h"
38 
39 //#define DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION
40 
41 
42 //#define USE_BRUTEFORCE_RAYBROADPHASE 1
43 //RECALCULATE_AABB is slower, but benefit is that you don't need to call 'stepSimulation' or 'updateAabbs' before using a rayTest
44 //#define RECALCULATE_AABB_RAYCAST 1
45 
46 //When the user doesn't provide dispatcher or broadphase, create basic versions (and delete them in destructor)
50 
51 
53 
54 //for debug rendering
67 
68 
69 
71 :m_dispatcher1(dispatcher),
72 m_broadphasePairCache(pairCache),
73 m_debugDrawer(0),
74 m_forceUpdateAllAabbs(true)
75 {
76 }
77 
78 
80 {
81 
82  //clean up remaining objects
83  int i;
84  for (i=0;i<m_collisionObjects.size();i++)
85  {
86  btCollisionObject* collisionObject= m_collisionObjects[i];
87 
88  btBroadphaseProxy* bp = collisionObject->getBroadphaseHandle();
89  if (bp)
90  {
91  //
92  // only clear the cached algorithms
93  //
96  collisionObject->setBroadphaseHandle(0);
97  }
98  }
99 
100 
101 }
102 
103 
104 
105 
106 
107 
108 
109 
111 {
112  if (collisionObject->getBroadphaseHandle())
113  {
114  int collisionFilterGroup = collisionObject->getBroadphaseHandle()->m_collisionFilterGroup;
115  int collisionFilterMask = collisionObject->getBroadphaseHandle()->m_collisionFilterMask;
116 
117 
119 
120  //calculate new AABB
121  btTransform trans = collisionObject->getWorldTransform();
122 
123  btVector3 minAabb;
124  btVector3 maxAabb;
125  collisionObject->getCollisionShape()->getAabb(trans,minAabb,maxAabb);
126 
127  int type = collisionObject->getCollisionShape()->getShapeType();
128  collisionObject->setBroadphaseHandle( getBroadphase()->createProxy(
129  minAabb,
130  maxAabb,
131  type,
132  collisionObject,
133  collisionFilterGroup,
134  collisionFilterMask,
135  m_dispatcher1)) ;
136  }
137 }
138 
139 void btCollisionWorld::addCollisionObject(btCollisionObject* collisionObject, int collisionFilterGroup, int collisionFilterMask)
140 {
141 
142  btAssert(collisionObject);
143 
144  //check that the object isn't already added
146  btAssert(collisionObject->getWorldArrayIndex() == -1); // do not add the same object to more than one collision world
147 
148  collisionObject->setWorldArrayIndex(m_collisionObjects.size());
149  m_collisionObjects.push_back(collisionObject);
150 
151  //calculate new AABB
152  btTransform trans = collisionObject->getWorldTransform();
153 
154  btVector3 minAabb;
155  btVector3 maxAabb;
156  collisionObject->getCollisionShape()->getAabb(trans,minAabb,maxAabb);
157 
158  int type = collisionObject->getCollisionShape()->getShapeType();
159  collisionObject->setBroadphaseHandle( getBroadphase()->createProxy(
160  minAabb,
161  maxAabb,
162  type,
163  collisionObject,
164  collisionFilterGroup,
165  collisionFilterMask,
166  m_dispatcher1)) ;
167 
168 
169 
170 
171 
172 }
173 
174 
175 
177 {
178  btVector3 minAabb,maxAabb;
179  colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);
180  //need to increase the aabb for contact thresholds
182  minAabb -= contactThreshold;
183  maxAabb += contactThreshold;
184 
185  if(getDispatchInfo().m_useContinuous && colObj->getInternalType()==btCollisionObject::CO_RIGID_BODY && !colObj->isStaticOrKinematicObject())
186  {
187  btVector3 minAabb2,maxAabb2;
188  colObj->getCollisionShape()->getAabb(colObj->getInterpolationWorldTransform(),minAabb2,maxAabb2);
189  minAabb2 -= contactThreshold;
190  maxAabb2 += contactThreshold;
191  minAabb.setMin(minAabb2);
192  maxAabb.setMax(maxAabb2);
193  }
194 
196 
197  //moving objects should be moderately sized, probably something wrong if not
198  if ( colObj->isStaticObject() || ((maxAabb-minAabb).length2() < btScalar(1e12)))
199  {
200  bp->setAabb(colObj->getBroadphaseHandle(),minAabb,maxAabb, m_dispatcher1);
201  } else
202  {
203  //something went wrong, investigate
204  //this assert is unwanted in 3D modelers (danger of loosing work)
206 
207  static bool reportMe = true;
208  if (reportMe && m_debugDrawer)
209  {
210  reportMe = false;
211  m_debugDrawer->reportErrorWarning("Overflow in AABB, object removed from simulation");
212  m_debugDrawer->reportErrorWarning("If you can reproduce this, please email bugs@continuousphysics.com\n");
213  m_debugDrawer->reportErrorWarning("Please include above information, your Platform, version of OS.\n");
214  m_debugDrawer->reportErrorWarning("Thanks.\n");
215  }
216  }
217 }
218 
220 {
221  BT_PROFILE("updateAabbs");
222 
223  btTransform predictedTrans;
224  for ( int i=0;i<m_collisionObjects.size();i++)
225  {
227  btAssert(colObj->getWorldArrayIndex() == i);
228 
229  //only update aabb of active objects
230  if (m_forceUpdateAllAabbs || colObj->isActive())
231  {
232  updateSingleAabb(colObj);
233  }
234  }
235 }
236 
237 
239 {
240  BT_PROFILE("calculateOverlappingPairs");
242 }
243 
245 {
246  BT_PROFILE("performDiscreteCollisionDetection");
247 
248  btDispatcherInfo& dispatchInfo = getDispatchInfo();
249 
250  updateAabbs();
251 
253 
254  btDispatcher* dispatcher = getDispatcher();
255  {
256  BT_PROFILE("dispatchAllCollisionPairs");
257  if (dispatcher)
259  }
260 
261 }
262 
263 
264 
266 {
267 
268 
269  //bool removeFromBroadphase = false;
270 
271  {
272 
273  btBroadphaseProxy* bp = collisionObject->getBroadphaseHandle();
274  if (bp)
275  {
276  //
277  // only clear the cached algorithms
278  //
281  collisionObject->setBroadphaseHandle(0);
282  }
283  }
284 
285 
286  int iObj = collisionObject->getWorldArrayIndex();
287 // btAssert(iObj >= 0 && iObj < m_collisionObjects.size()); // trying to remove an object that was never added or already removed previously?
288  if (iObj >= 0 && iObj < m_collisionObjects.size())
289  {
290  btAssert(collisionObject == m_collisionObjects[iObj]);
293  if (iObj < m_collisionObjects.size())
294  {
295  m_collisionObjects[iObj]->setWorldArrayIndex(iObj);
296  }
297  }
298  else
299  {
300  // slow linear search
301  //swapremove
302  m_collisionObjects.remove(collisionObject);
303  }
304  collisionObject->setWorldArrayIndex(-1);
305 }
306 
307 
308 void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans,
309  btCollisionObject* collisionObject,
310  const btCollisionShape* collisionShape,
311  const btTransform& colObjWorldTransform,
312  RayResultCallback& resultCallback)
313 {
314  btCollisionObjectWrapper colObWrap(0,collisionShape,collisionObject,colObjWorldTransform,-1,-1);
315  btCollisionWorld::rayTestSingleInternal(rayFromTrans,rayToTrans,&colObWrap,resultCallback);
316 }
317 
318 void btCollisionWorld::rayTestSingleInternal(const btTransform& rayFromTrans,const btTransform& rayToTrans,
319  const btCollisionObjectWrapper* collisionObjectWrap,
320  RayResultCallback& resultCallback)
321 {
322  btSphereShape pointShape(btScalar(0.0));
323  pointShape.setMargin(0.f);
324  const btConvexShape* castShape = &pointShape;
325  const btCollisionShape* collisionShape = collisionObjectWrap->getCollisionShape();
326  const btTransform& colObjWorldTransform = collisionObjectWrap->getWorldTransform();
327 
328  if (collisionShape->isConvex())
329  {
330  // BT_PROFILE("rayTestConvex");
331  btConvexCast::CastResult castResult;
332  castResult.m_fraction = resultCallback.m_closestHitFraction;
333 
334  btConvexShape* convexShape = (btConvexShape*) collisionShape;
335  btVoronoiSimplexSolver simplexSolver;
336  btSubsimplexConvexCast subSimplexConvexCaster(castShape,convexShape,&simplexSolver);
337 
338  btGjkConvexCast gjkConvexCaster(castShape,convexShape,&simplexSolver);
339 
340  //btContinuousConvexCollision convexCaster(castShape,convexShape,&simplexSolver,0);
341 
342  btConvexCast* convexCasterPtr = 0;
343  //use kF_UseSubSimplexConvexCastRaytest by default
345  convexCasterPtr = &gjkConvexCaster;
346  else
347  convexCasterPtr = &subSimplexConvexCaster;
348 
349  btConvexCast& convexCaster = *convexCasterPtr;
350 
351  if (convexCaster.calcTimeOfImpact(rayFromTrans,rayToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
352  {
353  //add hit
354  if (castResult.m_normal.length2() > btScalar(0.0001))
355  {
356  if (castResult.m_fraction < resultCallback.m_closestHitFraction)
357  {
358  //todo: figure out what this is about. When is rayFromTest.getBasis() not identity?
359 #ifdef USE_SUBSIMPLEX_CONVEX_CAST
360  //rotate normal into worldspace
361  castResult.m_normal = rayFromTrans.getBasis() * castResult.m_normal;
362 #endif //USE_SUBSIMPLEX_CONVEX_CAST
363 
364  castResult.m_normal.normalize();
365  btCollisionWorld::LocalRayResult localRayResult
366  (
367  collisionObjectWrap->getCollisionObject(),
368  0,
369  castResult.m_normal,
370  castResult.m_fraction
371  );
372 
373  bool normalInWorldSpace = true;
374  resultCallback.addSingleResult(localRayResult, normalInWorldSpace);
375 
376  }
377  }
378  }
379  } else {
380  if (collisionShape->isConcave())
381  {
382 
383  //ConvexCast::CastResult
384  struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback
385  {
386  btCollisionWorld::RayResultCallback* m_resultCallback;
387  const btCollisionObject* m_collisionObject;
388  const btConcaveShape* m_triangleMesh;
389 
390  btTransform m_colObjWorldTransform;
391 
392  BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,
393  btCollisionWorld::RayResultCallback* resultCallback, const btCollisionObject* collisionObject,const btConcaveShape* triangleMesh,const btTransform& colObjWorldTransform):
394  //@BP Mod
395  btTriangleRaycastCallback(from,to, resultCallback->m_flags),
396  m_resultCallback(resultCallback),
397  m_collisionObject(collisionObject),
398  m_triangleMesh(triangleMesh),
399  m_colObjWorldTransform(colObjWorldTransform)
400  {
401  }
402 
403 
404  virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex )
405  {
407  shapeInfo.m_shapePart = partId;
408  shapeInfo.m_triangleIndex = triangleIndex;
409 
410  btVector3 hitNormalWorld = m_colObjWorldTransform.getBasis() * hitNormalLocal;
411 
413  (m_collisionObject,
414  &shapeInfo,
415  hitNormalWorld,
416  hitFraction);
417 
418  bool normalInWorldSpace = true;
419  return m_resultCallback->addSingleResult(rayResult,normalInWorldSpace);
420  }
421 
422  };
423 
424  btTransform worldTocollisionObject = colObjWorldTransform.inverse();
425  btVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin();
426  btVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin();
427 
428  // BT_PROFILE("rayTestConcave");
429  if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE)
430  {
432  btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape;
433 
434  BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObjectWrap->getCollisionObject(),triangleMesh,colObjWorldTransform);
435  rcb.m_hitFraction = resultCallback.m_closestHitFraction;
436  triangleMesh->performRaycast(&rcb,rayFromLocal,rayToLocal);
437  }
438  else if (collisionShape->getShapeType() == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE)
439  {
441  btScaledBvhTriangleMeshShape* scaledTriangleMesh = (btScaledBvhTriangleMeshShape*)collisionShape;
442  btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)scaledTriangleMesh->getChildShape();
443 
444  //scale the ray positions
445  btVector3 scale = scaledTriangleMesh->getLocalScaling();
446  btVector3 rayFromLocalScaled = rayFromLocal / scale;
447  btVector3 rayToLocalScaled = rayToLocal / scale;
448 
449  //perform raycast in the underlying btBvhTriangleMeshShape
450  BridgeTriangleRaycastCallback rcb(rayFromLocalScaled, rayToLocalScaled, &resultCallback, collisionObjectWrap->getCollisionObject(), triangleMesh, colObjWorldTransform);
451  rcb.m_hitFraction = resultCallback.m_closestHitFraction;
452  triangleMesh->performRaycast(&rcb, rayFromLocalScaled, rayToLocalScaled);
453  }
454  else
455  {
456  //generic (slower) case
457  btConcaveShape* concaveShape = (btConcaveShape*)collisionShape;
458 
459  btTransform worldTocollisionObject = colObjWorldTransform.inverse();
460 
461  btVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin();
462  btVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin();
463 
464  //ConvexCast::CastResult
465 
466  struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback
467  {
468  btCollisionWorld::RayResultCallback* m_resultCallback;
469  const btCollisionObject* m_collisionObject;
470  btConcaveShape* m_triangleMesh;
471 
472  btTransform m_colObjWorldTransform;
473 
474  BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,
475  btCollisionWorld::RayResultCallback* resultCallback, const btCollisionObject* collisionObject,btConcaveShape* triangleMesh, const btTransform& colObjWorldTransform):
476  //@BP Mod
477  btTriangleRaycastCallback(from,to, resultCallback->m_flags),
478  m_resultCallback(resultCallback),
479  m_collisionObject(collisionObject),
480  m_triangleMesh(triangleMesh),
481  m_colObjWorldTransform(colObjWorldTransform)
482  {
483  }
484 
485 
486  virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex )
487  {
489  shapeInfo.m_shapePart = partId;
490  shapeInfo.m_triangleIndex = triangleIndex;
491 
492  btVector3 hitNormalWorld = m_colObjWorldTransform.getBasis() * hitNormalLocal;
493 
495  (m_collisionObject,
496  &shapeInfo,
497  hitNormalWorld,
498  hitFraction);
499 
500  bool normalInWorldSpace = true;
501  return m_resultCallback->addSingleResult(rayResult,normalInWorldSpace);
502  }
503 
504  };
505 
506 
507  BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObjectWrap->getCollisionObject(),concaveShape, colObjWorldTransform);
508  rcb.m_hitFraction = resultCallback.m_closestHitFraction;
509 
510  btVector3 rayAabbMinLocal = rayFromLocal;
511  rayAabbMinLocal.setMin(rayToLocal);
512  btVector3 rayAabbMaxLocal = rayFromLocal;
513  rayAabbMaxLocal.setMax(rayToLocal);
514 
515  concaveShape->processAllTriangles(&rcb,rayAabbMinLocal,rayAabbMaxLocal);
516  }
517  } else {
518  // BT_PROFILE("rayTestCompound");
519  if (collisionShape->isCompound())
520  {
521  struct LocalInfoAdder2 : public RayResultCallback
522  {
523  RayResultCallback* m_userCallback;
524  int m_i;
525 
526  LocalInfoAdder2 (int i, RayResultCallback *user)
527  : m_userCallback(user), m_i(i)
528  {
529  m_closestHitFraction = m_userCallback->m_closestHitFraction;
530  m_flags = m_userCallback->m_flags;
531  }
532  virtual bool needsCollision(btBroadphaseProxy* p) const
533  {
534  return m_userCallback->needsCollision(p);
535  }
536 
537  virtual btScalar addSingleResult (btCollisionWorld::LocalRayResult &r, bool b)
538  {
540  shapeInfo.m_shapePart = -1;
541  shapeInfo.m_triangleIndex = m_i;
542  if (r.m_localShapeInfo == NULL)
543  r.m_localShapeInfo = &shapeInfo;
544 
545  const btScalar result = m_userCallback->addSingleResult(r, b);
546  m_closestHitFraction = m_userCallback->m_closestHitFraction;
547  return result;
548  }
549  };
550 
551  struct RayTester : btDbvt::ICollide
552  {
553  const btCollisionObject* m_collisionObject;
554  const btCompoundShape* m_compoundShape;
555  const btTransform& m_colObjWorldTransform;
556  const btTransform& m_rayFromTrans;
557  const btTransform& m_rayToTrans;
558  RayResultCallback& m_resultCallback;
559 
560  RayTester(const btCollisionObject* collisionObject,
561  const btCompoundShape* compoundShape,
562  const btTransform& colObjWorldTransform,
563  const btTransform& rayFromTrans,
564  const btTransform& rayToTrans,
565  RayResultCallback& resultCallback):
566  m_collisionObject(collisionObject),
567  m_compoundShape(compoundShape),
568  m_colObjWorldTransform(colObjWorldTransform),
569  m_rayFromTrans(rayFromTrans),
570  m_rayToTrans(rayToTrans),
571  m_resultCallback(resultCallback)
572  {
573 
574  }
575 
576  void ProcessLeaf(int i)
577  {
578  const btCollisionShape* childCollisionShape = m_compoundShape->getChildShape(i);
579  const btTransform& childTrans = m_compoundShape->getChildTransform(i);
580  btTransform childWorldTrans = m_colObjWorldTransform * childTrans;
581 
582  btCollisionObjectWrapper tmpOb(0,childCollisionShape,m_collisionObject,childWorldTrans,-1,i);
583  // replace collision shape so that callback can determine the triangle
584 
585 
586 
587  LocalInfoAdder2 my_cb(i, &m_resultCallback);
588 
590  m_rayFromTrans,
591  m_rayToTrans,
592  &tmpOb,
593  my_cb);
594 
595  }
596 
597  void Process(const btDbvtNode* leaf)
598  {
599  ProcessLeaf(leaf->dataAsInt);
600  }
601  };
602 
603  const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(collisionShape);
604  const btDbvt* dbvt = compoundShape->getDynamicAabbTree();
605 
606 
607  RayTester rayCB(
608  collisionObjectWrap->getCollisionObject(),
609  compoundShape,
610  colObjWorldTransform,
611  rayFromTrans,
612  rayToTrans,
613  resultCallback);
614 #ifndef DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION
615  if (dbvt)
616  {
617  btVector3 localRayFrom = colObjWorldTransform.inverseTimes(rayFromTrans).getOrigin();
618  btVector3 localRayTo = colObjWorldTransform.inverseTimes(rayToTrans).getOrigin();
619  btDbvt::rayTest(dbvt->m_root, localRayFrom , localRayTo, rayCB);
620  }
621  else
622 #endif //DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION
623  {
624  for (int i = 0, n = compoundShape->getNumChildShapes(); i < n; ++i)
625  {
626  rayCB.ProcessLeaf(i);
627  }
628  }
629  }
630  }
631  }
632 }
633 
634 void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const btTransform& convexFromTrans,const btTransform& convexToTrans,
635  btCollisionObject* collisionObject,
636  const btCollisionShape* collisionShape,
637  const btTransform& colObjWorldTransform,
638  ConvexResultCallback& resultCallback, btScalar allowedPenetration)
639 {
640  btCollisionObjectWrapper tmpOb(0,collisionShape,collisionObject,colObjWorldTransform,-1,-1);
641  btCollisionWorld::objectQuerySingleInternal(castShape,convexFromTrans,convexToTrans,&tmpOb,resultCallback,allowedPenetration);
642 }
643 
644 void btCollisionWorld::objectQuerySingleInternal(const btConvexShape* castShape,const btTransform& convexFromTrans,const btTransform& convexToTrans,
645  const btCollisionObjectWrapper* colObjWrap,
646  ConvexResultCallback& resultCallback, btScalar allowedPenetration)
647 {
648  const btCollisionShape* collisionShape = colObjWrap->getCollisionShape();
649  const btTransform& colObjWorldTransform = colObjWrap->getWorldTransform();
650 
651  if (collisionShape->isConvex())
652  {
653  //BT_PROFILE("convexSweepConvex");
654  btConvexCast::CastResult castResult;
655  castResult.m_allowedPenetration = allowedPenetration;
656  castResult.m_fraction = resultCallback.m_closestHitFraction;//btScalar(1.);//??
657 
658  btConvexShape* convexShape = (btConvexShape*) collisionShape;
659  btVoronoiSimplexSolver simplexSolver;
660  btGjkEpaPenetrationDepthSolver gjkEpaPenetrationSolver;
661 
662  btContinuousConvexCollision convexCaster1(castShape,convexShape,&simplexSolver,&gjkEpaPenetrationSolver);
663  //btGjkConvexCast convexCaster2(castShape,convexShape,&simplexSolver);
664  //btSubsimplexConvexCast convexCaster3(castShape,convexShape,&simplexSolver);
665 
666  btConvexCast* castPtr = &convexCaster1;
667 
668 
669 
670  if (castPtr->calcTimeOfImpact(convexFromTrans,convexToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
671  {
672  //add hit
673  if (castResult.m_normal.length2() > btScalar(0.0001))
674  {
675  if (castResult.m_fraction < resultCallback.m_closestHitFraction)
676  {
677  castResult.m_normal.normalize();
678  btCollisionWorld::LocalConvexResult localConvexResult
679  (
680  colObjWrap->getCollisionObject(),
681  0,
682  castResult.m_normal,
683  castResult.m_hitPoint,
684  castResult.m_fraction
685  );
686 
687  bool normalInWorldSpace = true;
688  resultCallback.addSingleResult(localConvexResult, normalInWorldSpace);
689 
690  }
691  }
692  }
693  } else {
694  if (collisionShape->isConcave())
695  {
696  if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE)
697  {
698  //BT_PROFILE("convexSweepbtBvhTriangleMesh");
699  btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape;
700  btTransform worldTocollisionObject = colObjWorldTransform.inverse();
701  btVector3 convexFromLocal = worldTocollisionObject * convexFromTrans.getOrigin();
702  btVector3 convexToLocal = worldTocollisionObject * convexToTrans.getOrigin();
703  // rotation of box in local mesh space = MeshRotation^-1 * ConvexToRotation
704  btTransform rotationXform = btTransform(worldTocollisionObject.getBasis() * convexToTrans.getBasis());
705 
706  //ConvexCast::CastResult
707  struct BridgeTriangleConvexcastCallback : public btTriangleConvexcastCallback
708  {
709  btCollisionWorld::ConvexResultCallback* m_resultCallback;
710  const btCollisionObject* m_collisionObject;
711  btTriangleMeshShape* m_triangleMesh;
712 
713  BridgeTriangleConvexcastCallback(const btConvexShape* castShape, const btTransform& from,const btTransform& to,
714  btCollisionWorld::ConvexResultCallback* resultCallback, const btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh, const btTransform& triangleToWorld):
715  btTriangleConvexcastCallback(castShape, from,to, triangleToWorld, triangleMesh->getMargin()),
716  m_resultCallback(resultCallback),
717  m_collisionObject(collisionObject),
718  m_triangleMesh(triangleMesh)
719  {
720  }
721 
722 
723  virtual btScalar reportHit(const btVector3& hitNormalLocal, const btVector3& hitPointLocal, btScalar hitFraction, int partId, int triangleIndex )
724  {
726  shapeInfo.m_shapePart = partId;
727  shapeInfo.m_triangleIndex = triangleIndex;
728  if (hitFraction <= m_resultCallback->m_closestHitFraction)
729  {
730 
732  (m_collisionObject,
733  &shapeInfo,
734  hitNormalLocal,
735  hitPointLocal,
736  hitFraction);
737 
738  bool normalInWorldSpace = true;
739 
740 
741  return m_resultCallback->addSingleResult(convexResult,normalInWorldSpace);
742  }
743  return hitFraction;
744  }
745 
746  };
747 
748  BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,colObjWrap->getCollisionObject(),triangleMesh, colObjWorldTransform);
749  tccb.m_hitFraction = resultCallback.m_closestHitFraction;
750  tccb.m_allowedPenetration = allowedPenetration;
751  btVector3 boxMinLocal, boxMaxLocal;
752  castShape->getAabb(rotationXform, boxMinLocal, boxMaxLocal);
753  triangleMesh->performConvexcast(&tccb,convexFromLocal,convexToLocal,boxMinLocal, boxMaxLocal);
754  } else
755  {
756  if (collisionShape->getShapeType()==STATIC_PLANE_PROXYTYPE)
757  {
758  btConvexCast::CastResult castResult;
759  castResult.m_allowedPenetration = allowedPenetration;
760  castResult.m_fraction = resultCallback.m_closestHitFraction;
761  btStaticPlaneShape* planeShape = (btStaticPlaneShape*) collisionShape;
762  btContinuousConvexCollision convexCaster1(castShape,planeShape);
763  btConvexCast* castPtr = &convexCaster1;
764 
765  if (castPtr->calcTimeOfImpact(convexFromTrans,convexToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
766  {
767  //add hit
768  if (castResult.m_normal.length2() > btScalar(0.0001))
769  {
770  if (castResult.m_fraction < resultCallback.m_closestHitFraction)
771  {
772  castResult.m_normal.normalize();
773  btCollisionWorld::LocalConvexResult localConvexResult
774  (
775  colObjWrap->getCollisionObject(),
776  0,
777  castResult.m_normal,
778  castResult.m_hitPoint,
779  castResult.m_fraction
780  );
781 
782  bool normalInWorldSpace = true;
783  resultCallback.addSingleResult(localConvexResult, normalInWorldSpace);
784  }
785  }
786  }
787 
788  } else
789  {
790  //BT_PROFILE("convexSweepConcave");
791  btConcaveShape* concaveShape = (btConcaveShape*)collisionShape;
792  btTransform worldTocollisionObject = colObjWorldTransform.inverse();
793  btVector3 convexFromLocal = worldTocollisionObject * convexFromTrans.getOrigin();
794  btVector3 convexToLocal = worldTocollisionObject * convexToTrans.getOrigin();
795  // rotation of box in local mesh space = MeshRotation^-1 * ConvexToRotation
796  btTransform rotationXform = btTransform(worldTocollisionObject.getBasis() * convexToTrans.getBasis());
797 
798  //ConvexCast::CastResult
799  struct BridgeTriangleConvexcastCallback : public btTriangleConvexcastCallback
800  {
801  btCollisionWorld::ConvexResultCallback* m_resultCallback;
802  const btCollisionObject* m_collisionObject;
803  btConcaveShape* m_triangleMesh;
804 
805  BridgeTriangleConvexcastCallback(const btConvexShape* castShape, const btTransform& from,const btTransform& to,
806  btCollisionWorld::ConvexResultCallback* resultCallback, const btCollisionObject* collisionObject,btConcaveShape* triangleMesh, const btTransform& triangleToWorld):
807  btTriangleConvexcastCallback(castShape, from,to, triangleToWorld, triangleMesh->getMargin()),
808  m_resultCallback(resultCallback),
809  m_collisionObject(collisionObject),
810  m_triangleMesh(triangleMesh)
811  {
812  }
813 
814 
815  virtual btScalar reportHit(const btVector3& hitNormalLocal, const btVector3& hitPointLocal, btScalar hitFraction, int partId, int triangleIndex )
816  {
818  shapeInfo.m_shapePart = partId;
819  shapeInfo.m_triangleIndex = triangleIndex;
820  if (hitFraction <= m_resultCallback->m_closestHitFraction)
821  {
822 
824  (m_collisionObject,
825  &shapeInfo,
826  hitNormalLocal,
827  hitPointLocal,
828  hitFraction);
829 
830  bool normalInWorldSpace = true;
831 
832  return m_resultCallback->addSingleResult(convexResult,normalInWorldSpace);
833  }
834  return hitFraction;
835  }
836 
837  };
838 
839  BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,colObjWrap->getCollisionObject(),concaveShape, colObjWorldTransform);
840  tccb.m_hitFraction = resultCallback.m_closestHitFraction;
841  tccb.m_allowedPenetration = allowedPenetration;
842  btVector3 boxMinLocal, boxMaxLocal;
843  castShape->getAabb(rotationXform, boxMinLocal, boxMaxLocal);
844 
845  btVector3 rayAabbMinLocal = convexFromLocal;
846  rayAabbMinLocal.setMin(convexToLocal);
847  btVector3 rayAabbMaxLocal = convexFromLocal;
848  rayAabbMaxLocal.setMax(convexToLocal);
849  rayAabbMinLocal += boxMinLocal;
850  rayAabbMaxLocal += boxMaxLocal;
851  concaveShape->processAllTriangles(&tccb,rayAabbMinLocal,rayAabbMaxLocal);
852  }
853  }
854  } else {
855  if (collisionShape->isCompound())
856  {
858  {
860  const btCollisionObjectWrapper* colObjWrap,
861  const btConvexShape* castShape,
862  const btTransform& convexFromTrans,
863  const btTransform& convexToTrans,
864  btScalar allowedPenetration,
865  const btCompoundShape* compoundShape,
866  const btTransform& colObjWorldTransform,
867  ConvexResultCallback& resultCallback)
868  :
869  m_colObjWrap(colObjWrap),
870  m_castShape(castShape),
871  m_convexFromTrans(convexFromTrans),
872  m_convexToTrans(convexToTrans),
873  m_allowedPenetration(allowedPenetration),
874  m_compoundShape(compoundShape),
875  m_colObjWorldTransform(colObjWorldTransform),
876  m_resultCallback(resultCallback) {
877  }
878 
879  const btCollisionObjectWrapper* m_colObjWrap;
880  const btConvexShape* m_castShape;
881  const btTransform& m_convexFromTrans;
882  const btTransform& m_convexToTrans;
883  btScalar m_allowedPenetration;
884  const btCompoundShape* m_compoundShape;
885  const btTransform& m_colObjWorldTransform;
886  ConvexResultCallback& m_resultCallback;
887 
888  public:
889 
890  void ProcessChild(int index, const btTransform& childTrans, const btCollisionShape* childCollisionShape)
891  {
892  btTransform childWorldTrans = m_colObjWorldTransform * childTrans;
893 
894  struct LocalInfoAdder : public ConvexResultCallback {
895  ConvexResultCallback* m_userCallback;
896  int m_i;
897 
898  LocalInfoAdder(int i, ConvexResultCallback *user)
899  : m_userCallback(user), m_i(i)
900  {
901  m_closestHitFraction = m_userCallback->m_closestHitFraction;
902  }
903  virtual bool needsCollision(btBroadphaseProxy* p) const
904  {
905  return m_userCallback->needsCollision(p);
906  }
907  virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& r, bool b)
908  {
910  shapeInfo.m_shapePart = -1;
911  shapeInfo.m_triangleIndex = m_i;
912  if (r.m_localShapeInfo == NULL)
913  r.m_localShapeInfo = &shapeInfo;
914  const btScalar result = m_userCallback->addSingleResult(r, b);
915  m_closestHitFraction = m_userCallback->m_closestHitFraction;
916  return result;
917 
918  }
919  };
920 
921  LocalInfoAdder my_cb(index, &m_resultCallback);
922 
923  btCollisionObjectWrapper tmpObj(m_colObjWrap, childCollisionShape, m_colObjWrap->getCollisionObject(), childWorldTrans, -1, index);
924 
925  objectQuerySingleInternal(m_castShape, m_convexFromTrans, m_convexToTrans, &tmpObj, my_cb, m_allowedPenetration);
926  }
927 
928  void Process(const btDbvtNode* leaf)
929  {
930  // Processing leaf node
931  int index = leaf->dataAsInt;
932 
933  btTransform childTrans = m_compoundShape->getChildTransform(index);
934  const btCollisionShape* childCollisionShape = m_compoundShape->getChildShape(index);
935 
936  ProcessChild(index, childTrans, childCollisionShape);
937  }
938  };
939 
940  BT_PROFILE("convexSweepCompound");
941  const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(collisionShape);
942 
943  btVector3 fromLocalAabbMin, fromLocalAabbMax;
944  btVector3 toLocalAabbMin, toLocalAabbMax;
945 
946  castShape->getAabb(colObjWorldTransform.inverse() * convexFromTrans, fromLocalAabbMin, fromLocalAabbMax);
947  castShape->getAabb(colObjWorldTransform.inverse() * convexToTrans, toLocalAabbMin, toLocalAabbMax);
948 
949  fromLocalAabbMin.setMin(toLocalAabbMin);
950  fromLocalAabbMax.setMax(toLocalAabbMax);
951 
952  btCompoundLeafCallback callback(colObjWrap, castShape, convexFromTrans, convexToTrans,
953  allowedPenetration, compoundShape, colObjWorldTransform, resultCallback);
954 
955  const btDbvt* tree = compoundShape->getDynamicAabbTree();
956  if (tree) {
957  const ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds = btDbvtVolume::FromMM(fromLocalAabbMin, fromLocalAabbMax);
958  tree->collideTV(tree->m_root, bounds, callback);
959  } else {
960  int i;
961  for (i=0;i<compoundShape->getNumChildShapes();i++)
962  {
963  const btCollisionShape* childCollisionShape = compoundShape->getChildShape(i);
964  btTransform childTrans = compoundShape->getChildTransform(i);
965  callback.ProcessChild(i, childTrans, childCollisionShape);
966  }
967  }
968  }
969  }
970  }
971 }
972 
973 
975 {
976 
982 
985 
986  btSingleRayCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld,const btCollisionWorld* world,btCollisionWorld::RayResultCallback& resultCallback)
987  :m_rayFromWorld(rayFromWorld),
988  m_rayToWorld(rayToWorld),
989  m_world(world),
990  m_resultCallback(resultCallback)
991  {
992  m_rayFromTrans.setIdentity();
993  m_rayFromTrans.setOrigin(m_rayFromWorld);
994  m_rayToTrans.setIdentity();
995  m_rayToTrans.setOrigin(m_rayToWorld);
996 
997  btVector3 rayDir = (rayToWorld-rayFromWorld);
998 
999  rayDir.normalize ();
1001  m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0];
1002  m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1];
1003  m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[2];
1004  m_signs[0] = m_rayDirectionInverse[0] < 0.0;
1005  m_signs[1] = m_rayDirectionInverse[1] < 0.0;
1006  m_signs[2] = m_rayDirectionInverse[2] < 0.0;
1007 
1008  m_lambda_max = rayDir.dot(m_rayToWorld-m_rayFromWorld);
1009 
1010  }
1011 
1012 
1013 
1014  virtual bool process(const btBroadphaseProxy* proxy)
1015  {
1017  if (m_resultCallback.m_closestHitFraction == btScalar(0.f))
1018  return false;
1019 
1020  btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject;
1021 
1022  //only perform raycast if filterMask matches
1023  if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
1024  {
1025  //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
1026  //btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
1027 #if 0
1028 #ifdef RECALCULATE_AABB
1029  btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
1030  collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
1031 #else
1032  //getBroadphase()->getAabb(collisionObject->getBroadphaseHandle(),collisionObjectAabbMin,collisionObjectAabbMax);
1033  const btVector3& collisionObjectAabbMin = collisionObject->getBroadphaseHandle()->m_aabbMin;
1034  const btVector3& collisionObjectAabbMax = collisionObject->getBroadphaseHandle()->m_aabbMax;
1035 #endif
1036 #endif
1037  //btScalar hitLambda = m_resultCallback.m_closestHitFraction;
1038  //culling already done by broadphase
1039  //if (btRayAabb(m_rayFromWorld,m_rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,m_hitNormal))
1040  {
1041  m_world->rayTestSingle(m_rayFromTrans,m_rayToTrans,
1042  collisionObject,
1043  collisionObject->getCollisionShape(),
1044  collisionObject->getWorldTransform(),
1045  m_resultCallback);
1046  }
1047  }
1048  return true;
1049  }
1050 };
1051 
1052 void btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const
1053 {
1054  //BT_PROFILE("rayTest");
1057  btSingleRayCallback rayCB(rayFromWorld,rayToWorld,this,resultCallback);
1058 
1059 #ifndef USE_BRUTEFORCE_RAYBROADPHASE
1060  m_broadphasePairCache->rayTest(rayFromWorld,rayToWorld,rayCB);
1061 #else
1062  for (int i=0;i<this->getNumCollisionObjects();i++)
1063  {
1064  rayCB.process(m_collisionObjects[i]->getBroadphaseHandle());
1065  }
1066 #endif //USE_BRUTEFORCE_RAYBROADPHASE
1067 
1068 }
1069 
1070 
1072 {
1073 
1081 
1082 
1083  btSingleSweepCallback(const btConvexShape* castShape, const btTransform& convexFromTrans,const btTransform& convexToTrans,const btCollisionWorld* world,btCollisionWorld::ConvexResultCallback& resultCallback,btScalar allowedPenetration)
1084  :m_convexFromTrans(convexFromTrans),
1085  m_convexToTrans(convexToTrans),
1086  m_world(world),
1087  m_resultCallback(resultCallback),
1088  m_allowedCcdPenetration(allowedPenetration),
1089  m_castShape(castShape)
1090  {
1091  btVector3 unnormalizedRayDir = (m_convexToTrans.getOrigin()-m_convexFromTrans.getOrigin());
1092  btVector3 rayDir = unnormalizedRayDir.normalized();
1094  m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0];
1095  m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1];
1096  m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[2];
1097  m_signs[0] = m_rayDirectionInverse[0] < 0.0;
1098  m_signs[1] = m_rayDirectionInverse[1] < 0.0;
1099  m_signs[2] = m_rayDirectionInverse[2] < 0.0;
1100 
1101  m_lambda_max = rayDir.dot(unnormalizedRayDir);
1102 
1103  }
1104 
1105  virtual bool process(const btBroadphaseProxy* proxy)
1106  {
1108  if (m_resultCallback.m_closestHitFraction == btScalar(0.f))
1109  return false;
1110 
1111  btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject;
1112 
1113  //only perform raycast if filterMask matches
1114  if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) {
1115  //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
1116  m_world->objectQuerySingle(m_castShape, m_convexFromTrans,m_convexToTrans,
1117  collisionObject,
1118  collisionObject->getCollisionShape(),
1119  collisionObject->getWorldTransform(),
1120  m_resultCallback,
1121  m_allowedCcdPenetration);
1122  }
1123 
1124  return true;
1125  }
1126 };
1127 
1128 
1129 
1130 void btCollisionWorld::convexSweepTest(const btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration) const
1131 {
1132 
1133  BT_PROFILE("convexSweepTest");
1137 
1138 
1139 
1140  btTransform convexFromTrans,convexToTrans;
1141  convexFromTrans = convexFromWorld;
1142  convexToTrans = convexToWorld;
1143  btVector3 castShapeAabbMin, castShapeAabbMax;
1144  /* Compute AABB that encompasses angular movement */
1145  {
1146  btVector3 linVel, angVel;
1147  btTransformUtil::calculateVelocity (convexFromTrans, convexToTrans, 1.0f, linVel, angVel);
1148  btVector3 zeroLinVel;
1149  zeroLinVel.setValue(0,0,0);
1150  btTransform R;
1151  R.setIdentity ();
1152  R.setRotation (convexFromTrans.getRotation());
1153  castShape->calculateTemporalAabb (R, zeroLinVel, angVel, 1.0f, castShapeAabbMin, castShapeAabbMax);
1154  }
1155 
1156 #ifndef USE_BRUTEFORCE_RAYBROADPHASE
1157 
1158  btSingleSweepCallback convexCB(castShape,convexFromWorld,convexToWorld,this,resultCallback,allowedCcdPenetration);
1159 
1160  m_broadphasePairCache->rayTest(convexFromTrans.getOrigin(),convexToTrans.getOrigin(),convexCB,castShapeAabbMin,castShapeAabbMax);
1161 
1162 #else
1163  // do a ray-shape query using convexCaster (CCD)
1165  int i;
1166  for (i=0;i<m_collisionObjects.size();i++)
1167  {
1168  btCollisionObject* collisionObject= m_collisionObjects[i];
1169  //only perform raycast if filterMask matches
1170  if(resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) {
1171  //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
1172  btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
1173  collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
1174  AabbExpand (collisionObjectAabbMin, collisionObjectAabbMax, castShapeAabbMin, castShapeAabbMax);
1175  btScalar hitLambda = btScalar(1.); //could use resultCallback.m_closestHitFraction, but needs testing
1176  btVector3 hitNormal;
1177  if (btRayAabb(convexFromWorld.getOrigin(),convexToWorld.getOrigin(),collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,hitNormal))
1178  {
1179  objectQuerySingle(castShape, convexFromTrans,convexToTrans,
1180  collisionObject,
1181  collisionObject->getCollisionShape(),
1182  collisionObject->getWorldTransform(),
1183  resultCallback,
1184  allowedCcdPenetration);
1185  }
1186  }
1187  }
1188 #endif //USE_BRUTEFORCE_RAYBROADPHASE
1189 }
1190 
1191 
1192 
1194 {
1195 
1197 
1199  :btManifoldResult(obj0Wrap,obj1Wrap),
1200  m_resultCallback(resultCallback)
1201  {
1202  }
1203 
1204  virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)
1205  {
1206  bool isSwapped = m_manifoldPtr->getBody0() != m_body0Wrap->getCollisionObject();
1207  btVector3 pointA = pointInWorld + normalOnBInWorld * depth;
1208  btVector3 localA;
1209  btVector3 localB;
1210  if (isSwapped)
1211  {
1212  localA = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointA );
1213  localB = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld);
1214  } else
1215  {
1216  localA = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointA );
1217  localB = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld);
1218  }
1219 
1220  btManifoldPoint newPt(localA,localB,normalOnBInWorld,depth);
1221  newPt.m_positionWorldOnA = pointA;
1222  newPt.m_positionWorldOnB = pointInWorld;
1223 
1224  //BP mod, store contact triangles.
1225  if (isSwapped)
1226  {
1227  newPt.m_partId0 = m_partId1;
1228  newPt.m_partId1 = m_partId0;
1229  newPt.m_index0 = m_index1;
1230  newPt.m_index1 = m_index0;
1231  } else
1232  {
1233  newPt.m_partId0 = m_partId0;
1234  newPt.m_partId1 = m_partId1;
1235  newPt.m_index0 = m_index0;
1236  newPt.m_index1 = m_index1;
1237  }
1238 
1239  //experimental feature info, for per-triangle material etc.
1240  const btCollisionObjectWrapper* obj0Wrap = isSwapped? m_body1Wrap : m_body0Wrap;
1241  const btCollisionObjectWrapper* obj1Wrap = isSwapped? m_body0Wrap : m_body1Wrap;
1242  m_resultCallback.addSingleResult(newPt,obj0Wrap,newPt.m_partId0,newPt.m_index0,obj1Wrap,newPt.m_partId1,newPt.m_index1);
1243 
1244  }
1245 
1246 };
1247 
1248 
1249 
1251 {
1252 
1256 
1257 
1259  :m_collisionObject(collisionObject),
1260  m_world(world),
1261  m_resultCallback(resultCallback)
1262  {
1263  }
1264 
1265  virtual bool process(const btBroadphaseProxy* proxy)
1266  {
1267  btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject;
1268  if (collisionObject == m_collisionObject)
1269  return true;
1270 
1271  //only perform raycast if filterMask matches
1272  if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
1273  {
1274  btCollisionObjectWrapper ob0(0,m_collisionObject->getCollisionShape(),m_collisionObject,m_collisionObject->getWorldTransform(),-1,-1);
1275  btCollisionObjectWrapper ob1(0,collisionObject->getCollisionShape(),collisionObject,collisionObject->getWorldTransform(),-1,-1);
1276 
1277  btCollisionAlgorithm* algorithm = m_world->getDispatcher()->findAlgorithm(&ob0,&ob1,0, BT_CLOSEST_POINT_ALGORITHMS);
1278  if (algorithm)
1279  {
1280  btBridgedManifoldResult contactPointResult(&ob0,&ob1, m_resultCallback);
1281  //discrete collision detection query
1282 
1283  algorithm->processCollision(&ob0,&ob1, m_world->getDispatchInfo(),&contactPointResult);
1284 
1285  algorithm->~btCollisionAlgorithm();
1286  m_world->getDispatcher()->freeCollisionAlgorithm(algorithm);
1287  }
1288  }
1289  return true;
1290  }
1291 };
1292 
1293 
1297 {
1298  btVector3 aabbMin,aabbMax;
1299  colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(),aabbMin,aabbMax);
1300  btSingleContactCallback contactCB(colObj,this,resultCallback);
1301 
1302  m_broadphasePairCache->aabbTest(aabbMin,aabbMax,contactCB);
1303 }
1304 
1305 
1309 {
1310  btCollisionObjectWrapper obA(0,colObjA->getCollisionShape(),colObjA,colObjA->getWorldTransform(),-1,-1);
1311  btCollisionObjectWrapper obB(0,colObjB->getCollisionShape(),colObjB,colObjB->getWorldTransform(),-1,-1);
1312 
1314  if (algorithm)
1315  {
1316  btBridgedManifoldResult contactPointResult(&obA,&obB, resultCallback);
1317  contactPointResult.m_closestPointDistanceThreshold = resultCallback.m_closestDistanceThreshold;
1318  //discrete collision detection query
1319  algorithm->processCollision(&obA,&obB, getDispatchInfo(),&contactPointResult);
1320 
1321  algorithm->~btCollisionAlgorithm();
1322  getDispatcher()->freeCollisionAlgorithm(algorithm);
1323  }
1324 
1325 }
1326 
1327 
1328 
1329 
1331 {
1335 
1336 public:
1337 
1338  DebugDrawcallback(btIDebugDraw* debugDrawer,const btTransform& worldTrans,const btVector3& color) :
1339  m_debugDrawer(debugDrawer),
1340  m_color(color),
1341  m_worldTrans(worldTrans)
1342  {
1343  }
1344 
1345  virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex)
1346  {
1347  processTriangle(triangle,partId,triangleIndex);
1348  }
1349 
1350  virtual void processTriangle(btVector3* triangle,int partId, int triangleIndex)
1351  {
1352  (void)partId;
1353  (void)triangleIndex;
1354 
1355  btVector3 wv0,wv1,wv2;
1356  wv0 = m_worldTrans*triangle[0];
1357  wv1 = m_worldTrans*triangle[1];
1358  wv2 = m_worldTrans*triangle[2];
1359  btVector3 center = (wv0+wv1+wv2)*btScalar(1./3.);
1360 
1361  if (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawNormals )
1362  {
1363  btVector3 normal = (wv1-wv0).cross(wv2-wv0);
1364  normal.normalize();
1365  btVector3 normalColor(1,1,0);
1366  m_debugDrawer->drawLine(center,center+normal,normalColor);
1367  }
1368  m_debugDrawer->drawLine(wv0,wv1,m_color);
1369  m_debugDrawer->drawLine(wv1,wv2,m_color);
1370  m_debugDrawer->drawLine(wv2,wv0,m_color);
1371  }
1372 };
1373 
1374 
1375 void btCollisionWorld::debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color)
1376 {
1377  // Draw a small simplex at the center of the object
1378  if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawFrames)
1379  {
1380  getDebugDrawer()->drawTransform(worldTransform,.1);
1381  }
1382 
1383  if (shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE)
1384  {
1385  const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(shape);
1386  for (int i=compoundShape->getNumChildShapes()-1;i>=0;i--)
1387  {
1388  btTransform childTrans = compoundShape->getChildTransform(i);
1389  const btCollisionShape* colShape = compoundShape->getChildShape(i);
1390  debugDrawObject(worldTransform*childTrans,colShape,color);
1391  }
1392 
1393  } else
1394  {
1395 
1396  switch (shape->getShapeType())
1397  {
1398 
1399  case BOX_SHAPE_PROXYTYPE:
1400  {
1401  const btBoxShape* boxShape = static_cast<const btBoxShape*>(shape);
1402  btVector3 halfExtents = boxShape->getHalfExtentsWithMargin();
1403  getDebugDrawer()->drawBox(-halfExtents,halfExtents,worldTransform,color);
1404  break;
1405  }
1406 
1408  {
1409  const btSphereShape* sphereShape = static_cast<const btSphereShape*>(shape);
1410  btScalar radius = sphereShape->getMargin();//radius doesn't include the margin, so draw with margin
1411 
1412  getDebugDrawer()->drawSphere(radius, worldTransform, color);
1413  break;
1414  }
1416  {
1417  const btMultiSphereShape* multiSphereShape = static_cast<const btMultiSphereShape*>(shape);
1418 
1419  btTransform childTransform;
1420  childTransform.setIdentity();
1421 
1422  for (int i = multiSphereShape->getSphereCount()-1; i>=0;i--)
1423  {
1424  childTransform.setOrigin(multiSphereShape->getSpherePosition(i));
1425  getDebugDrawer()->drawSphere(multiSphereShape->getSphereRadius(i), worldTransform*childTransform, color);
1426  }
1427 
1428  break;
1429  }
1431  {
1432  const btCapsuleShape* capsuleShape = static_cast<const btCapsuleShape*>(shape);
1433 
1434  btScalar radius = capsuleShape->getRadius();
1435  btScalar halfHeight = capsuleShape->getHalfHeight();
1436 
1437  int upAxis = capsuleShape->getUpAxis();
1438  getDebugDrawer()->drawCapsule(radius, halfHeight, upAxis, worldTransform, color);
1439  break;
1440  }
1441  case CONE_SHAPE_PROXYTYPE:
1442  {
1443  const btConeShape* coneShape = static_cast<const btConeShape*>(shape);
1444  btScalar radius = coneShape->getRadius();//+coneShape->getMargin();
1445  btScalar height = coneShape->getHeight();//+coneShape->getMargin();
1446 
1447  int upAxis= coneShape->getConeUpIndex();
1448  getDebugDrawer()->drawCone(radius, height, upAxis, worldTransform, color);
1449  break;
1450 
1451  }
1453  {
1454  const btCylinderShape* cylinder = static_cast<const btCylinderShape*>(shape);
1455  int upAxis = cylinder->getUpAxis();
1456  btScalar radius = cylinder->getRadius();
1457  btScalar halfHeight = cylinder->getHalfExtentsWithMargin()[upAxis];
1458  getDebugDrawer()->drawCylinder(radius, halfHeight, upAxis, worldTransform, color);
1459  break;
1460  }
1461 
1463  {
1464  const btStaticPlaneShape* staticPlaneShape = static_cast<const btStaticPlaneShape*>(shape);
1465  btScalar planeConst = staticPlaneShape->getPlaneConstant();
1466  const btVector3& planeNormal = staticPlaneShape->getPlaneNormal();
1467  getDebugDrawer()->drawPlane(planeNormal, planeConst,worldTransform, color);
1468  break;
1469 
1470  }
1471  default:
1472  {
1473 
1475  if (shape->isPolyhedral())
1476  {
1477  btPolyhedralConvexShape* polyshape = (btPolyhedralConvexShape*) shape;
1478 
1479  int i;
1480  if (polyshape->getConvexPolyhedron())
1481  {
1482  const btConvexPolyhedron* poly = polyshape->getConvexPolyhedron();
1483  for (i=0;i<poly->m_faces.size();i++)
1484  {
1485  btVector3 centroid(0,0,0);
1486  int numVerts = poly->m_faces[i].m_indices.size();
1487  if (numVerts)
1488  {
1489  int lastV = poly->m_faces[i].m_indices[numVerts-1];
1490  for (int v=0;v<poly->m_faces[i].m_indices.size();v++)
1491  {
1492  int curVert = poly->m_faces[i].m_indices[v];
1493  centroid+=poly->m_vertices[curVert];
1494  getDebugDrawer()->drawLine(worldTransform*poly->m_vertices[lastV],worldTransform*poly->m_vertices[curVert],color);
1495  lastV = curVert;
1496  }
1497  }
1498  centroid*= btScalar(1.f)/btScalar(numVerts);
1499  if (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawNormals)
1500  {
1501  btVector3 normalColor(1,1,0);
1502  btVector3 faceNormal(poly->m_faces[i].m_plane[0],poly->m_faces[i].m_plane[1],poly->m_faces[i].m_plane[2]);
1503  getDebugDrawer()->drawLine(worldTransform*centroid,worldTransform*(centroid+faceNormal),normalColor);
1504  }
1505 
1506  }
1507 
1508 
1509  } else
1510  {
1511  for (i=0;i<polyshape->getNumEdges();i++)
1512  {
1513  btVector3 a,b;
1514  polyshape->getEdge(i,a,b);
1515  btVector3 wa = worldTransform * a;
1516  btVector3 wb = worldTransform * b;
1517  getDebugDrawer()->drawLine(wa,wb,color);
1518  }
1519  }
1520 
1521 
1522  }
1523 
1524  if (shape->isConcave())
1525  {
1526  btConcaveShape* concaveMesh = (btConcaveShape*) shape;
1527 
1531 
1532  DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color);
1533  concaveMesh->processAllTriangles(&drawCallback,aabbMin,aabbMax);
1534 
1535  }
1536 
1538  {
1540  //todo: pass camera for some culling
1543  //DebugDrawcallback drawCallback;
1544  DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color);
1545  convexMesh->getMeshInterface()->InternalProcessAllTriangles(&drawCallback,aabbMin,aabbMax);
1546  }
1547 
1548 
1549 
1550  }
1551 
1552  }
1553  }
1554 }
1555 
1556 
1558 {
1559  if (getDebugDrawer())
1560  {
1562 
1564 
1565  if ( getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints)
1566  {
1567 
1568 
1569  if (getDispatcher())
1570  {
1571  int numManifolds = getDispatcher()->getNumManifolds();
1572 
1573  for (int i=0;i<numManifolds;i++)
1574  {
1576  //btCollisionObject* obA = static_cast<btCollisionObject*>(contactManifold->getBody0());
1577  //btCollisionObject* obB = static_cast<btCollisionObject*>(contactManifold->getBody1());
1578 
1579  int numContacts = contactManifold->getNumContacts();
1580  for (int j=0;j<numContacts;j++)
1581  {
1582  btManifoldPoint& cp = contactManifold->getContactPoint(j);
1584  }
1585  }
1586  }
1587  }
1588 
1590  {
1591  int i;
1592 
1593  for ( i=0;i<m_collisionObjects.size();i++)
1594  {
1597  {
1599  {
1600  btVector3 color(btScalar(0.4),btScalar(0.4),btScalar(0.4));
1601 
1602  switch(colObj->getActivationState())
1603  {
1604  case ACTIVE_TAG:
1605  color = defaultColors.m_activeObject; break;
1606  case ISLAND_SLEEPING:
1607  color = defaultColors.m_deactivatedObject;break;
1608  case WANTS_DEACTIVATION:
1609  color = defaultColors.m_wantsDeactivationObject;break;
1610  case DISABLE_DEACTIVATION:
1611  color = defaultColors.m_disabledDeactivationObject;break;
1612  case DISABLE_SIMULATION:
1613  color = defaultColors.m_disabledSimulationObject;break;
1614  default:
1615  {
1616  color = btVector3(btScalar(.3),btScalar(0.3),btScalar(0.3));
1617  }
1618  };
1619 
1620  colObj->getCustomDebugColor(color);
1621 
1622  debugDrawObject(colObj->getWorldTransform(),colObj->getCollisionShape(),color);
1623  }
1625  {
1626  btVector3 minAabb,maxAabb;
1627  btVector3 colorvec = defaultColors.m_aabb;
1628  colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);
1630  minAabb -= contactThreshold;
1631  maxAabb += contactThreshold;
1632 
1633  btVector3 minAabb2,maxAabb2;
1634 
1635  if(getDispatchInfo().m_useContinuous && colObj->getInternalType()==btCollisionObject::CO_RIGID_BODY && !colObj->isStaticOrKinematicObject())
1636  {
1637  colObj->getCollisionShape()->getAabb(colObj->getInterpolationWorldTransform(),minAabb2,maxAabb2);
1638  minAabb2 -= contactThreshold;
1639  maxAabb2 += contactThreshold;
1640  minAabb.setMin(minAabb2);
1641  maxAabb.setMax(maxAabb2);
1642  }
1643 
1644  m_debugDrawer->drawAabb(minAabb,maxAabb,colorvec);
1645  }
1646  }
1647  }
1648  }
1649  }
1650 }
1651 
1652 
1654 {
1655  int i;
1656 
1658  btHashMap<btHashPtr,btCollisionShape*> serializedShapes;
1659 
1660  for (i=0;i<m_collisionObjects.size();i++)
1661  {
1663  btCollisionShape* shape = colObj->getCollisionShape();
1664 
1665  if (!serializedShapes.find(shape))
1666  {
1667  serializedShapes.insert(shape,shape);
1668  shape->serializeSingleShape(serializer);
1669  }
1670  }
1671 
1672  //serialize all collision objects
1673  for (i=0;i<m_collisionObjects.size();i++)
1674  {
1677  {
1678  colObj->serializeSingleObject(serializer);
1679  }
1680  }
1681 }
1682 
1683 
1684 
1686 {
1688  {
1689  int numManifolds = getDispatcher()->getNumManifolds();
1690  for (int i = 0; i < numManifolds; i++)
1691  {
1693  //don't serialize empty manifolds, they just take space
1694  //(may have to do it anyway if it destroys determinism)
1695  if (manifold->getNumContacts() == 0)
1696  continue;
1697 
1698  btChunk* chunk = serializer->allocate(manifold->calculateSerializeBufferSize(), 1);
1699  const char* structType = manifold->serialize(manifold, chunk->m_oldPtr, serializer);
1700  serializer->finalizeChunk(chunk, structType, BT_CONTACTMANIFOLD_CODE, (void*)manifold);
1701  }
1702  }
1703 }
1704 
1705 
1707 {
1708 
1709  serializer->startSerialization();
1710 
1711  serializeCollisionObjects(serializer);
1712 
1713  serializeContactManifolds(serializer);
1714 
1715  serializer->finishSerialization();
1716 }
1717 
virtual const btVector3 & getLocalScaling() const
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:294
btConvexCast is an interface for Casting
Definition: btConvexCast.h:27
#define BT_CONTACTMANIFOLD_CODE
Definition: btSerializer.h:132
void serializeContactManifolds(btSerializer *serializer)
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:652
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
virtual void clearLines()
Definition: btIDebugDraw.h:472
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...
virtual void addCollisionObject(btCollisionObject *collisionObject, int collisionFilterGroup=btBroadphaseProxy::DefaultFilter, int collisionFilterMask=btBroadphaseProxy::AllFilter)
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 btCollisionAlgorithm * findAlgorithm(const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap, btPersistentManifold *sharedManifold, ebtDispatcherQueryType queryType)=0
virtual void drawBox(const btVector3 &bbMin, const btVector3 &bbMax, const btVector3 &color)
Definition: btIDebugDraw.h:306
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:131
virtual void drawPlane(const btVector3 &planeNormal, btScalar planeConst, const btTransform &transform, const btVector3 &color)
Definition: btIDebugDraw.h:458
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:198
The btCollisionShape class provides an interface for collision shapes that can be shared among btColl...
RayResultCallback is used to report new raycast results.
const char * serialize(const class btPersistentManifold *manifold, void *dataBuffer, class btSerializer *serializer) const
btContinuousConvexCollision implements angular and linear time of impact for convex objects...
void setWorldArrayIndex(int ix)
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:262
btCollisionWorld::RayResultCallback & m_resultCallback
ManifoldContactPoint collects and maintains persistent contactpoints.
btScalar getRadius() const
const btCollisionWorld * m_world
int getCollisionFlags() const
btDispatcher * m_dispatcher1
btManifoldResult is a helper class to manage contact results.
virtual void serializeSingleShape(btSerializer *serializer) const
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:1060
static void rayTestSingleInternal(const btTransform &rayFromTrans, const btTransform &rayToTrans, const btCollisionObjectWrapper *collisionObjectWrap, RayResultCallback &resultCallback)
const btDbvt * getDynamicAabbTree() const
int getConeUpIndex() const
Definition: btConeShape.h:91
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:337
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
void swap(int index0, int index1)
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
btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
Definition: btVector3.h:309
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&#39;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
int getWorldArrayIndex() const
btBvhTriangleMeshShape * getChildShape()
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
btScalar m_closestPointDistanceThreshold
btVector3 m_positionWorldOnB
virtual void drawCone(btScalar radius, btScalar height, int upAxis, const btTransform &transform, const btVector3 &color)
Definition: btIDebugDraw.h:421
int size() const
return the number of elements in the array
virtual int getSerializationFlags() const =0
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 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)
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
static btDbvtAabbMm FromMM(const btVector3 &mi, const btVector3 &mx)
Definition: btDbvt.h:425
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:262
#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:29
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
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 btPersistentManifold ** getInternalManifoldPointer()=0
virtual void setMargin(btScalar margin)
Definition: btSphereShape.h:61
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:83
#define ATTRIBUTE_ALIGNED16(a)
Definition: btScalar.h:82
const Value * find(const Key &key) const
Definition: btHashMap.h:422
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
int calculateSerializeBufferSize() const
const btBroadphaseInterface * getBroadphase() const
#define BT_PROFILE(name)
Definition: btQuickprof.h:216
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...
virtual void finalizeChunk(btChunk *chunk, const char *structType, int chunkCode, void *oldPtr)=0
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:966
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:166
virtual bool needsCollision(btBroadphaseProxy *proxy0) const
int findLinearSearch(const T &key) const
virtual btScalar getMargin() const
Definition: btSphereShape.h:65
virtual int getDebugMode() const =0
btAlignedObjectArray< btCollisionObject * > m_collisionObjects
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
int dataAsInt
Definition: btDbvt.h:188
virtual void performDiscreteCollisionDetection()
virtual void refreshBroadphaseProxy(btCollisionObject *collisionObject)
The btScaledBvhTriangleMeshShape allows to instance a scaled version of an existing btBvhTriangleMesh...
btBroadphaseInterface * m_broadphasePairCache
virtual void setAabb(btBroadphaseProxy *proxy, const btVector3 &aabbMin, const btVector3 &aabbMax, btDispatcher *dispatcher)=0
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
Definition: btDbvt.cpp:284
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:621
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:77
btScalar getHalfHeight() const
btCollisionAlgorithm is an collision interface that is compatible with the Broadphase and btDispatche...
const btCollisionShape * getCollisionShape() const
bool getCustomDebugColor(btVector3 &colorRGB) 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:93
DBVT_PREFIX void collideTV(const btDbvtNode *root, const btDbvtVolume &volume, DBVT_IPOLICY) const
Definition: btDbvt.h:935
bool btRayAabb(const btVector3 &rayFrom, const btVector3 &rayTo, const btVector3 &aabbMin, const btVector3 &aabbMax, btScalar &param, btVector3 &normal)
Definition: btAabbUtil2.h:125
virtual DefaultColors getDefaultColors() const
Definition: btIDebugDraw.h:81
void * m_oldPtr
Definition: btSerializer.h:56
int getActivationState() const
virtual void destroyProxy(btBroadphaseProxy *proxy, btDispatcher *dispatcher)=0
virtual void addContactPoint(const btVector3 &normalOnBInWorld, const btVector3 &pointInWorld, btScalar depth)
btVector3 m_disabledDeactivationObject
Definition: btIDebugDraw.h:38
btCollisionWorld::ContactResultCallback & m_resultCallback
virtual btChunk * allocate(size_t size, int numElements)=0
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)
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:638
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:292
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