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