00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "btCollisionWorld.h"
00017 #include "btCollisionDispatcher.h"
00018 #include "BulletCollision/CollisionDispatch/btCollisionObject.h"
00019 #include "BulletCollision/CollisionShapes/btCollisionShape.h"
00020 #include "BulletCollision/CollisionShapes/btConvexShape.h"
00021 #include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
00022 #include "BulletCollision/CollisionShapes/btSphereShape.h"
00023 #include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h"
00024 #include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h"
00025 #include "BulletCollision/CollisionShapes/btCompoundShape.h"
00026 #include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
00027 #include "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h"
00028 #include "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h"
00029 #include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
00030 #include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
00031 #include "LinearMath/btAabbUtil2.h"
00032 #include "LinearMath/btQuickprof.h"
00033 #include "LinearMath/btStackAlloc.h"
00034 #include "LinearMath/btSerializer.h"
00035
00036
00037
00038
00039
00040
00041 #include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
00042 #include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h"
00043 #include "BulletCollision/CollisionDispatch/btCollisionConfiguration.h"
00044
00045
00047
00048
00049 #include "BulletCollision/CollisionShapes/btBoxShape.h"
00050 #include "BulletCollision/CollisionShapes/btCapsuleShape.h"
00051 #include "BulletCollision/CollisionShapes/btCompoundShape.h"
00052 #include "BulletCollision/CollisionShapes/btConeShape.h"
00053 #include "BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h"
00054 #include "BulletCollision/CollisionShapes/btCylinderShape.h"
00055 #include "BulletCollision/CollisionShapes/btMultiSphereShape.h"
00056 #include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.h"
00057 #include "BulletCollision/CollisionShapes/btSphereShape.h"
00058 #include "BulletCollision/CollisionShapes/btTriangleCallback.h"
00059 #include "BulletCollision/CollisionShapes/btTriangleMeshShape.h"
00060 #include "BulletCollision/CollisionShapes/btStaticPlaneShape.h"
00061
00062
00063
00064 btCollisionWorld::btCollisionWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache, btCollisionConfiguration* collisionConfiguration)
00065 :m_dispatcher1(dispatcher),
00066 m_broadphasePairCache(pairCache),
00067 m_debugDrawer(0),
00068 m_forceUpdateAllAabbs(true)
00069 {
00070 m_stackAlloc = collisionConfiguration->getStackAllocator();
00071 m_dispatchInfo.m_stackAllocator = m_stackAlloc;
00072 }
00073
00074
00075 btCollisionWorld::~btCollisionWorld()
00076 {
00077
00078
00079 int i;
00080 for (i=0;i<m_collisionObjects.size();i++)
00081 {
00082 btCollisionObject* collisionObject= m_collisionObjects[i];
00083
00084 btBroadphaseProxy* bp = collisionObject->getBroadphaseHandle();
00085 if (bp)
00086 {
00087
00088
00089
00090 getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(bp,m_dispatcher1);
00091 getBroadphase()->destroyProxy(bp,m_dispatcher1);
00092 collisionObject->setBroadphaseHandle(0);
00093 }
00094 }
00095
00096
00097 }
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 void btCollisionWorld::addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup,short int collisionFilterMask)
00109 {
00110
00111 btAssert(collisionObject);
00112
00113
00114 btAssert( m_collisionObjects.findLinearSearch(collisionObject) == m_collisionObjects.size());
00115
00116 m_collisionObjects.push_back(collisionObject);
00117
00118
00119 btTransform trans = collisionObject->getWorldTransform();
00120
00121 btVector3 minAabb;
00122 btVector3 maxAabb;
00123 collisionObject->getCollisionShape()->getAabb(trans,minAabb,maxAabb);
00124
00125 int type = collisionObject->getCollisionShape()->getShapeType();
00126 collisionObject->setBroadphaseHandle( getBroadphase()->createProxy(
00127 minAabb,
00128 maxAabb,
00129 type,
00130 collisionObject,
00131 collisionFilterGroup,
00132 collisionFilterMask,
00133 m_dispatcher1,0
00134 )) ;
00135
00136
00137
00138
00139
00140 }
00141
00142
00143
00144 void btCollisionWorld::updateSingleAabb(btCollisionObject* colObj)
00145 {
00146 btVector3 minAabb,maxAabb;
00147 colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);
00148
00149 btVector3 contactThreshold(gContactBreakingThreshold,gContactBreakingThreshold,gContactBreakingThreshold);
00150 minAabb -= contactThreshold;
00151 maxAabb += contactThreshold;
00152
00153 btBroadphaseInterface* bp = (btBroadphaseInterface*)m_broadphasePairCache;
00154
00155
00156 if ( colObj->isStaticObject() || ((maxAabb-minAabb).length2() < btScalar(1e12)))
00157 {
00158 bp->setAabb(colObj->getBroadphaseHandle(),minAabb,maxAabb, m_dispatcher1);
00159 } else
00160 {
00161
00162
00163 colObj->setActivationState(DISABLE_SIMULATION);
00164
00165 static bool reportMe = true;
00166 if (reportMe && m_debugDrawer)
00167 {
00168 reportMe = false;
00169 m_debugDrawer->reportErrorWarning("Overflow in AABB, object removed from simulation");
00170 m_debugDrawer->reportErrorWarning("If you can reproduce this, please email bugs@continuousphysics.com\n");
00171 m_debugDrawer->reportErrorWarning("Please include above information, your Platform, version of OS.\n");
00172 m_debugDrawer->reportErrorWarning("Thanks.\n");
00173 }
00174 }
00175 }
00176
00177 void btCollisionWorld::updateAabbs()
00178 {
00179 BT_PROFILE("updateAabbs");
00180
00181 btTransform predictedTrans;
00182 for ( int i=0;i<m_collisionObjects.size();i++)
00183 {
00184 btCollisionObject* colObj = m_collisionObjects[i];
00185
00186
00187 if (m_forceUpdateAllAabbs || colObj->isActive())
00188 {
00189 updateSingleAabb(colObj);
00190 }
00191 }
00192 }
00193
00194
00195
00196 void btCollisionWorld::performDiscreteCollisionDetection()
00197 {
00198 BT_PROFILE("performDiscreteCollisionDetection");
00199
00200 btDispatcherInfo& dispatchInfo = getDispatchInfo();
00201
00202 updateAabbs();
00203
00204 {
00205 BT_PROFILE("calculateOverlappingPairs");
00206 m_broadphasePairCache->calculateOverlappingPairs(m_dispatcher1);
00207 }
00208
00209
00210 btDispatcher* dispatcher = getDispatcher();
00211 {
00212 BT_PROFILE("dispatchAllCollisionPairs");
00213 if (dispatcher)
00214 dispatcher->dispatchAllCollisionPairs(m_broadphasePairCache->getOverlappingPairCache(),dispatchInfo,m_dispatcher1);
00215 }
00216
00217 }
00218
00219
00220
00221 void btCollisionWorld::removeCollisionObject(btCollisionObject* collisionObject)
00222 {
00223
00224
00225
00226
00227 {
00228
00229 btBroadphaseProxy* bp = collisionObject->getBroadphaseHandle();
00230 if (bp)
00231 {
00232
00233
00234
00235 getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(bp,m_dispatcher1);
00236 getBroadphase()->destroyProxy(bp,m_dispatcher1);
00237 collisionObject->setBroadphaseHandle(0);
00238 }
00239 }
00240
00241
00242
00243 m_collisionObjects.remove(collisionObject);
00244
00245 }
00246
00247
00248
00249 void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans,
00250 btCollisionObject* collisionObject,
00251 const btCollisionShape* collisionShape,
00252 const btTransform& colObjWorldTransform,
00253 RayResultCallback& resultCallback)
00254 {
00255 btSphereShape pointShape(btScalar(0.0));
00256 pointShape.setMargin(0.f);
00257 const btConvexShape* castShape = &pointShape;
00258
00259 if (collisionShape->isConvex())
00260 {
00261
00262 btConvexCast::CastResult castResult;
00263 castResult.m_fraction = resultCallback.m_closestHitFraction;
00264
00265 btConvexShape* convexShape = (btConvexShape*) collisionShape;
00266 btVoronoiSimplexSolver simplexSolver;
00267 #define USE_SUBSIMPLEX_CONVEX_CAST 1
00268 #ifdef USE_SUBSIMPLEX_CONVEX_CAST
00269 btSubsimplexConvexCast convexCaster(castShape,convexShape,&simplexSolver);
00270 #else
00271
00272
00273 #endif //#USE_SUBSIMPLEX_CONVEX_CAST
00274
00275 if (convexCaster.calcTimeOfImpact(rayFromTrans,rayToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
00276 {
00277
00278 if (castResult.m_normal.length2() > btScalar(0.0001))
00279 {
00280 if (castResult.m_fraction < resultCallback.m_closestHitFraction)
00281 {
00282 #ifdef USE_SUBSIMPLEX_CONVEX_CAST
00283
00284 castResult.m_normal = rayFromTrans.getBasis() * castResult.m_normal;
00285 #endif //USE_SUBSIMPLEX_CONVEX_CAST
00286
00287 castResult.m_normal.normalize();
00288 btCollisionWorld::LocalRayResult localRayResult
00289 (
00290 collisionObject,
00291 0,
00292 castResult.m_normal,
00293 castResult.m_fraction
00294 );
00295
00296 bool normalInWorldSpace = true;
00297 resultCallback.addSingleResult(localRayResult, normalInWorldSpace);
00298
00299 }
00300 }
00301 }
00302 } else {
00303 if (collisionShape->isConcave())
00304 {
00305
00306 if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE)
00307 {
00309 btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape;
00310 btTransform worldTocollisionObject = colObjWorldTransform.inverse();
00311 btVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin();
00312 btVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin();
00313
00314
00315 struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback
00316 {
00317 btCollisionWorld::RayResultCallback* m_resultCallback;
00318 btCollisionObject* m_collisionObject;
00319 btTriangleMeshShape* m_triangleMesh;
00320
00321 btTransform m_colObjWorldTransform;
00322
00323 BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,
00324 btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh,const btTransform& colObjWorldTransform):
00325
00326 btTriangleRaycastCallback(from,to, resultCallback->m_flags),
00327 m_resultCallback(resultCallback),
00328 m_collisionObject(collisionObject),
00329 m_triangleMesh(triangleMesh),
00330 m_colObjWorldTransform(colObjWorldTransform)
00331 {
00332 }
00333
00334
00335 virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex )
00336 {
00337 btCollisionWorld::LocalShapeInfo shapeInfo;
00338 shapeInfo.m_shapePart = partId;
00339 shapeInfo.m_triangleIndex = triangleIndex;
00340
00341 btVector3 hitNormalWorld = m_colObjWorldTransform.getBasis() * hitNormalLocal;
00342
00343 btCollisionWorld::LocalRayResult rayResult
00344 (m_collisionObject,
00345 &shapeInfo,
00346 hitNormalWorld,
00347 hitFraction);
00348
00349 bool normalInWorldSpace = true;
00350 return m_resultCallback->addSingleResult(rayResult,normalInWorldSpace);
00351 }
00352
00353 };
00354
00355 BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,triangleMesh,colObjWorldTransform);
00356 rcb.m_hitFraction = resultCallback.m_closestHitFraction;
00357 triangleMesh->performRaycast(&rcb,rayFromLocal,rayToLocal);
00358 } else
00359 {
00360
00361 btConcaveShape* concaveShape = (btConcaveShape*)collisionShape;
00362
00363 btTransform worldTocollisionObject = colObjWorldTransform.inverse();
00364
00365 btVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin();
00366 btVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin();
00367
00368
00369
00370 struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback
00371 {
00372 btCollisionWorld::RayResultCallback* m_resultCallback;
00373 btCollisionObject* m_collisionObject;
00374 btConcaveShape* m_triangleMesh;
00375
00376 btTransform m_colObjWorldTransform;
00377
00378 BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,
00379 btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btConcaveShape* triangleMesh, const btTransform& colObjWorldTransform):
00380
00381 btTriangleRaycastCallback(from,to, resultCallback->m_flags),
00382 m_resultCallback(resultCallback),
00383 m_collisionObject(collisionObject),
00384 m_triangleMesh(triangleMesh),
00385 m_colObjWorldTransform(colObjWorldTransform)
00386 {
00387 }
00388
00389
00390 virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex )
00391 {
00392 btCollisionWorld::LocalShapeInfo shapeInfo;
00393 shapeInfo.m_shapePart = partId;
00394 shapeInfo.m_triangleIndex = triangleIndex;
00395
00396 btVector3 hitNormalWorld = m_colObjWorldTransform.getBasis() * hitNormalLocal;
00397
00398 btCollisionWorld::LocalRayResult rayResult
00399 (m_collisionObject,
00400 &shapeInfo,
00401 hitNormalWorld,
00402 hitFraction);
00403
00404 bool normalInWorldSpace = true;
00405 return m_resultCallback->addSingleResult(rayResult,normalInWorldSpace);
00406 }
00407
00408 };
00409
00410
00411 BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,concaveShape, colObjWorldTransform);
00412 rcb.m_hitFraction = resultCallback.m_closestHitFraction;
00413
00414 btVector3 rayAabbMinLocal = rayFromLocal;
00415 rayAabbMinLocal.setMin(rayToLocal);
00416 btVector3 rayAabbMaxLocal = rayFromLocal;
00417 rayAabbMaxLocal.setMax(rayToLocal);
00418
00419 concaveShape->processAllTriangles(&rcb,rayAabbMinLocal,rayAabbMaxLocal);
00420 }
00421 } else {
00422
00424 if (collisionShape->isCompound())
00425 {
00426 const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(collisionShape);
00427 int i=0;
00428 for (i=0;i<compoundShape->getNumChildShapes();i++)
00429 {
00430 btTransform childTrans = compoundShape->getChildTransform(i);
00431 const btCollisionShape* childCollisionShape = compoundShape->getChildShape(i);
00432 btTransform childWorldTrans = colObjWorldTransform * childTrans;
00433
00434 btCollisionShape* saveCollisionShape = collisionObject->getCollisionShape();
00435 collisionObject->internalSetTemporaryCollisionShape((btCollisionShape*)childCollisionShape);
00436 struct LocalInfoAdder2 : public RayResultCallback {
00437 int m_i;
00438 RayResultCallback* m_userCallback;
00439 LocalInfoAdder2 (int i, RayResultCallback *user)
00440 : m_i(i), m_userCallback(user)
00441 {
00442 }
00443 virtual btScalar addSingleResult (btCollisionWorld::LocalRayResult &r, bool b)
00444 {
00445 btCollisionWorld::LocalShapeInfo shapeInfo;
00446 shapeInfo.m_shapePart = -1;
00447 shapeInfo.m_triangleIndex = m_i;
00448 if (r.m_localShapeInfo == NULL)
00449 r.m_localShapeInfo = &shapeInfo;
00450 return m_userCallback->addSingleResult(r, b);
00451 }
00452 };
00453
00454 LocalInfoAdder2 my_cb(i, &resultCallback);
00455 my_cb.m_closestHitFraction = resultCallback.m_closestHitFraction;
00456
00457
00458 rayTestSingle(rayFromTrans,rayToTrans,
00459 collisionObject,
00460 childCollisionShape,
00461 childWorldTrans,
00462 my_cb);
00463
00464 collisionObject->internalSetTemporaryCollisionShape(saveCollisionShape);
00465 }
00466 }
00467 }
00468 }
00469 }
00470
00471 void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const btTransform& convexFromTrans,const btTransform& convexToTrans,
00472 btCollisionObject* collisionObject,
00473 const btCollisionShape* collisionShape,
00474 const btTransform& colObjWorldTransform,
00475 ConvexResultCallback& resultCallback, btScalar allowedPenetration)
00476 {
00477 if (collisionShape->isConvex())
00478 {
00479
00480 btConvexCast::CastResult castResult;
00481 castResult.m_allowedPenetration = allowedPenetration;
00482 castResult.m_fraction = resultCallback.m_closestHitFraction;
00483
00484 btConvexShape* convexShape = (btConvexShape*) collisionShape;
00485 btVoronoiSimplexSolver simplexSolver;
00486 btGjkEpaPenetrationDepthSolver gjkEpaPenetrationSolver;
00487
00488 btContinuousConvexCollision convexCaster1(castShape,convexShape,&simplexSolver,&gjkEpaPenetrationSolver);
00489
00490
00491
00492 btConvexCast* castPtr = &convexCaster1;
00493
00494
00495
00496 if (castPtr->calcTimeOfImpact(convexFromTrans,convexToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
00497 {
00498
00499 if (castResult.m_normal.length2() > btScalar(0.0001))
00500 {
00501 if (castResult.m_fraction < resultCallback.m_closestHitFraction)
00502 {
00503 castResult.m_normal.normalize();
00504 btCollisionWorld::LocalConvexResult localConvexResult
00505 (
00506 collisionObject,
00507 0,
00508 castResult.m_normal,
00509 castResult.m_hitPoint,
00510 castResult.m_fraction
00511 );
00512
00513 bool normalInWorldSpace = true;
00514 resultCallback.addSingleResult(localConvexResult, normalInWorldSpace);
00515
00516 }
00517 }
00518 }
00519 } else {
00520 if (collisionShape->isConcave())
00521 {
00522 if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE)
00523 {
00524
00525 btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape;
00526 btTransform worldTocollisionObject = colObjWorldTransform.inverse();
00527 btVector3 convexFromLocal = worldTocollisionObject * convexFromTrans.getOrigin();
00528 btVector3 convexToLocal = worldTocollisionObject * convexToTrans.getOrigin();
00529
00530 btTransform rotationXform = btTransform(worldTocollisionObject.getBasis() * convexToTrans.getBasis());
00531
00532
00533 struct BridgeTriangleConvexcastCallback : public btTriangleConvexcastCallback
00534 {
00535 btCollisionWorld::ConvexResultCallback* m_resultCallback;
00536 btCollisionObject* m_collisionObject;
00537 btTriangleMeshShape* m_triangleMesh;
00538
00539 BridgeTriangleConvexcastCallback(const btConvexShape* castShape, const btTransform& from,const btTransform& to,
00540 btCollisionWorld::ConvexResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh, const btTransform& triangleToWorld):
00541 btTriangleConvexcastCallback(castShape, from,to, triangleToWorld, triangleMesh->getMargin()),
00542 m_resultCallback(resultCallback),
00543 m_collisionObject(collisionObject),
00544 m_triangleMesh(triangleMesh)
00545 {
00546 }
00547
00548
00549 virtual btScalar reportHit(const btVector3& hitNormalLocal, const btVector3& hitPointLocal, btScalar hitFraction, int partId, int triangleIndex )
00550 {
00551 btCollisionWorld::LocalShapeInfo shapeInfo;
00552 shapeInfo.m_shapePart = partId;
00553 shapeInfo.m_triangleIndex = triangleIndex;
00554 if (hitFraction <= m_resultCallback->m_closestHitFraction)
00555 {
00556
00557 btCollisionWorld::LocalConvexResult convexResult
00558 (m_collisionObject,
00559 &shapeInfo,
00560 hitNormalLocal,
00561 hitPointLocal,
00562 hitFraction);
00563
00564 bool normalInWorldSpace = true;
00565
00566
00567 return m_resultCallback->addSingleResult(convexResult,normalInWorldSpace);
00568 }
00569 return hitFraction;
00570 }
00571
00572 };
00573
00574 BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,collisionObject,triangleMesh, colObjWorldTransform);
00575 tccb.m_hitFraction = resultCallback.m_closestHitFraction;
00576 btVector3 boxMinLocal, boxMaxLocal;
00577 castShape->getAabb(rotationXform, boxMinLocal, boxMaxLocal);
00578 triangleMesh->performConvexcast(&tccb,convexFromLocal,convexToLocal,boxMinLocal, boxMaxLocal);
00579 } else
00580 {
00581
00582 btConcaveShape* concaveShape = (btConcaveShape*)collisionShape;
00583 btTransform worldTocollisionObject = colObjWorldTransform.inverse();
00584 btVector3 convexFromLocal = worldTocollisionObject * convexFromTrans.getOrigin();
00585 btVector3 convexToLocal = worldTocollisionObject * convexToTrans.getOrigin();
00586
00587 btTransform rotationXform = btTransform(worldTocollisionObject.getBasis() * convexToTrans.getBasis());
00588
00589
00590 struct BridgeTriangleConvexcastCallback : public btTriangleConvexcastCallback
00591 {
00592 btCollisionWorld::ConvexResultCallback* m_resultCallback;
00593 btCollisionObject* m_collisionObject;
00594 btConcaveShape* m_triangleMesh;
00595
00596 BridgeTriangleConvexcastCallback(const btConvexShape* castShape, const btTransform& from,const btTransform& to,
00597 btCollisionWorld::ConvexResultCallback* resultCallback, btCollisionObject* collisionObject,btConcaveShape* triangleMesh, const btTransform& triangleToWorld):
00598 btTriangleConvexcastCallback(castShape, from,to, triangleToWorld, triangleMesh->getMargin()),
00599 m_resultCallback(resultCallback),
00600 m_collisionObject(collisionObject),
00601 m_triangleMesh(triangleMesh)
00602 {
00603 }
00604
00605
00606 virtual btScalar reportHit(const btVector3& hitNormalLocal, const btVector3& hitPointLocal, btScalar hitFraction, int partId, int triangleIndex )
00607 {
00608 btCollisionWorld::LocalShapeInfo shapeInfo;
00609 shapeInfo.m_shapePart = partId;
00610 shapeInfo.m_triangleIndex = triangleIndex;
00611 if (hitFraction <= m_resultCallback->m_closestHitFraction)
00612 {
00613
00614 btCollisionWorld::LocalConvexResult convexResult
00615 (m_collisionObject,
00616 &shapeInfo,
00617 hitNormalLocal,
00618 hitPointLocal,
00619 hitFraction);
00620
00621 bool normalInWorldSpace = false;
00622
00623 return m_resultCallback->addSingleResult(convexResult,normalInWorldSpace);
00624 }
00625 return hitFraction;
00626 }
00627
00628 };
00629
00630 BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,collisionObject,concaveShape, colObjWorldTransform);
00631 tccb.m_hitFraction = resultCallback.m_closestHitFraction;
00632 btVector3 boxMinLocal, boxMaxLocal;
00633 castShape->getAabb(rotationXform, boxMinLocal, boxMaxLocal);
00634
00635 btVector3 rayAabbMinLocal = convexFromLocal;
00636 rayAabbMinLocal.setMin(convexToLocal);
00637 btVector3 rayAabbMaxLocal = convexFromLocal;
00638 rayAabbMaxLocal.setMax(convexToLocal);
00639 rayAabbMinLocal += boxMinLocal;
00640 rayAabbMaxLocal += boxMaxLocal;
00641 concaveShape->processAllTriangles(&tccb,rayAabbMinLocal,rayAabbMaxLocal);
00642 }
00643 } else {
00645 if (collisionShape->isCompound())
00646 {
00647 BT_PROFILE("convexSweepCompound");
00648 const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(collisionShape);
00649 int i=0;
00650 for (i=0;i<compoundShape->getNumChildShapes();i++)
00651 {
00652 btTransform childTrans = compoundShape->getChildTransform(i);
00653 const btCollisionShape* childCollisionShape = compoundShape->getChildShape(i);
00654 btTransform childWorldTrans = colObjWorldTransform * childTrans;
00655
00656 btCollisionShape* saveCollisionShape = collisionObject->getCollisionShape();
00657 collisionObject->internalSetTemporaryCollisionShape((btCollisionShape*)childCollisionShape);
00658 struct LocalInfoAdder : public ConvexResultCallback {
00659 ConvexResultCallback* m_userCallback;
00660 int m_i;
00661
00662 LocalInfoAdder (int i, ConvexResultCallback *user)
00663 : m_userCallback(user),m_i(i) { }
00664 virtual btScalar addSingleResult (btCollisionWorld::LocalConvexResult& r, bool b)
00665 {
00666 btCollisionWorld::LocalShapeInfo shapeInfo;
00667 shapeInfo.m_shapePart = -1;
00668 shapeInfo.m_triangleIndex = m_i;
00669 if (r.m_localShapeInfo == NULL)
00670 r.m_localShapeInfo = &shapeInfo;
00671 return m_userCallback->addSingleResult(r, b);
00672 }
00673 };
00674
00675 LocalInfoAdder my_cb(i, &resultCallback);
00676 my_cb.m_closestHitFraction = resultCallback.m_closestHitFraction;
00677
00678 objectQuerySingle(castShape, convexFromTrans,convexToTrans,
00679 collisionObject,
00680 childCollisionShape,
00681 childWorldTrans,
00682 my_cb, allowedPenetration);
00683
00684 collisionObject->internalSetTemporaryCollisionShape(saveCollisionShape);
00685 }
00686 }
00687 }
00688 }
00689 }
00690
00691
00692 struct btSingleRayCallback : public btBroadphaseRayCallback
00693 {
00694
00695 btVector3 m_rayFromWorld;
00696 btVector3 m_rayToWorld;
00697 btTransform m_rayFromTrans;
00698 btTransform m_rayToTrans;
00699 btVector3 m_hitNormal;
00700
00701 const btCollisionWorld* m_world;
00702 btCollisionWorld::RayResultCallback& m_resultCallback;
00703
00704 btSingleRayCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld,const btCollisionWorld* world,btCollisionWorld::RayResultCallback& resultCallback)
00705 :m_rayFromWorld(rayFromWorld),
00706 m_rayToWorld(rayToWorld),
00707 m_world(world),
00708 m_resultCallback(resultCallback)
00709 {
00710 m_rayFromTrans.setIdentity();
00711 m_rayFromTrans.setOrigin(m_rayFromWorld);
00712 m_rayToTrans.setIdentity();
00713 m_rayToTrans.setOrigin(m_rayToWorld);
00714
00715 btVector3 rayDir = (rayToWorld-rayFromWorld);
00716
00717 rayDir.normalize ();
00719 m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0];
00720 m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1];
00721 m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[2];
00722 m_signs[0] = m_rayDirectionInverse[0] < 0.0;
00723 m_signs[1] = m_rayDirectionInverse[1] < 0.0;
00724 m_signs[2] = m_rayDirectionInverse[2] < 0.0;
00725
00726 m_lambda_max = rayDir.dot(m_rayToWorld-m_rayFromWorld);
00727
00728 }
00729
00730
00731
00732 virtual bool process(const btBroadphaseProxy* proxy)
00733 {
00735 if (m_resultCallback.m_closestHitFraction == btScalar(0.f))
00736 return false;
00737
00738 btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject;
00739
00740
00741 if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
00742 {
00743
00744
00745 #if 0
00746 #ifdef RECALCULATE_AABB
00747 btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
00748 collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
00749 #else
00750
00751 const btVector3& collisionObjectAabbMin = collisionObject->getBroadphaseHandle()->m_aabbMin;
00752 const btVector3& collisionObjectAabbMax = collisionObject->getBroadphaseHandle()->m_aabbMax;
00753 #endif
00754 #endif
00755
00756
00757
00758 {
00759 m_world->rayTestSingle(m_rayFromTrans,m_rayToTrans,
00760 collisionObject,
00761 collisionObject->getCollisionShape(),
00762 collisionObject->getWorldTransform(),
00763 m_resultCallback);
00764 }
00765 }
00766 return true;
00767 }
00768 };
00769
00770 void btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const
00771 {
00772
00775 btSingleRayCallback rayCB(rayFromWorld,rayToWorld,this,resultCallback);
00776
00777 #ifndef USE_BRUTEFORCE_RAYBROADPHASE
00778 m_broadphasePairCache->rayTest(rayFromWorld,rayToWorld,rayCB);
00779 #else
00780 for (int i=0;i<this->getNumCollisionObjects();i++)
00781 {
00782 rayCB.process(m_collisionObjects[i]->getBroadphaseHandle());
00783 }
00784 #endif //USE_BRUTEFORCE_RAYBROADPHASE
00785
00786 }
00787
00788
00789 struct btSingleSweepCallback : public btBroadphaseRayCallback
00790 {
00791
00792 btTransform m_convexFromTrans;
00793 btTransform m_convexToTrans;
00794 btVector3 m_hitNormal;
00795 const btCollisionWorld* m_world;
00796 btCollisionWorld::ConvexResultCallback& m_resultCallback;
00797 btScalar m_allowedCcdPenetration;
00798 const btConvexShape* m_castShape;
00799
00800
00801 btSingleSweepCallback(const btConvexShape* castShape, const btTransform& convexFromTrans,const btTransform& convexToTrans,const btCollisionWorld* world,btCollisionWorld::ConvexResultCallback& resultCallback,btScalar allowedPenetration)
00802 :m_convexFromTrans(convexFromTrans),
00803 m_convexToTrans(convexToTrans),
00804 m_world(world),
00805 m_resultCallback(resultCallback),
00806 m_allowedCcdPenetration(allowedPenetration),
00807 m_castShape(castShape)
00808 {
00809 btVector3 unnormalizedRayDir = (m_convexToTrans.getOrigin()-m_convexFromTrans.getOrigin());
00810 btVector3 rayDir = unnormalizedRayDir.normalized();
00812 m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0];
00813 m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1];
00814 m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[2];
00815 m_signs[0] = m_rayDirectionInverse[0] < 0.0;
00816 m_signs[1] = m_rayDirectionInverse[1] < 0.0;
00817 m_signs[2] = m_rayDirectionInverse[2] < 0.0;
00818
00819 m_lambda_max = rayDir.dot(unnormalizedRayDir);
00820
00821 }
00822
00823 virtual bool process(const btBroadphaseProxy* proxy)
00824 {
00826 if (m_resultCallback.m_closestHitFraction == btScalar(0.f))
00827 return false;
00828
00829 btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject;
00830
00831
00832 if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) {
00833
00834 m_world->objectQuerySingle(m_castShape, m_convexFromTrans,m_convexToTrans,
00835 collisionObject,
00836 collisionObject->getCollisionShape(),
00837 collisionObject->getWorldTransform(),
00838 m_resultCallback,
00839 m_allowedCcdPenetration);
00840 }
00841
00842 return true;
00843 }
00844 };
00845
00846
00847
00848 void btCollisionWorld::convexSweepTest(const btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration) const
00849 {
00850
00851 BT_PROFILE("convexSweepTest");
00855
00856
00857
00858 btTransform convexFromTrans,convexToTrans;
00859 convexFromTrans = convexFromWorld;
00860 convexToTrans = convexToWorld;
00861 btVector3 castShapeAabbMin, castShapeAabbMax;
00862
00863 {
00864 btVector3 linVel, angVel;
00865 btTransformUtil::calculateVelocity (convexFromTrans, convexToTrans, 1.0, linVel, angVel);
00866 btVector3 zeroLinVel;
00867 zeroLinVel.setValue(0,0,0);
00868 btTransform R;
00869 R.setIdentity ();
00870 R.setRotation (convexFromTrans.getRotation());
00871 castShape->calculateTemporalAabb (R, zeroLinVel, angVel, 1.0, castShapeAabbMin, castShapeAabbMax);
00872 }
00873
00874 #ifndef USE_BRUTEFORCE_RAYBROADPHASE
00875
00876 btSingleSweepCallback convexCB(castShape,convexFromWorld,convexToWorld,this,resultCallback,allowedCcdPenetration);
00877
00878 m_broadphasePairCache->rayTest(convexFromTrans.getOrigin(),convexToTrans.getOrigin(),convexCB,castShapeAabbMin,castShapeAabbMax);
00879
00880 #else
00882 // do a ray-shape query using convexCaster (CCD)
00883 int i;
00884 for (i=0;i<m_collisionObjects.size();i++)
00885 {
00886 btCollisionObject* collisionObject= m_collisionObjects[i];
00887
00888 if(resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) {
00889
00890 btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
00891 collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
00892 AabbExpand (collisionObjectAabbMin, collisionObjectAabbMax, castShapeAabbMin, castShapeAabbMax);
00893 btScalar hitLambda = btScalar(1.);
00894 btVector3 hitNormal;
00895 if (btRayAabb(convexFromWorld.getOrigin(),convexToWorld.getOrigin(),collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,hitNormal))
00896 {
00897 objectQuerySingle(castShape, convexFromTrans,convexToTrans,
00898 collisionObject,
00899 collisionObject->getCollisionShape(),
00900 collisionObject->getWorldTransform(),
00901 resultCallback,
00902 allowedCcdPenetration);
00903 }
00904 }
00905 }
00906 #endif //USE_BRUTEFORCE_RAYBROADPHASE
00907 }
00908
00909
00910
00911 struct btBridgedManifoldResult : public btManifoldResult
00912 {
00913
00914 btCollisionWorld::ContactResultCallback& m_resultCallback;
00915
00916 btBridgedManifoldResult( btCollisionObject* obj0,btCollisionObject* obj1,btCollisionWorld::ContactResultCallback& resultCallback )
00917 :btManifoldResult(obj0,obj1),
00918 m_resultCallback(resultCallback)
00919 {
00920 }
00921
00922 virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)
00923 {
00924 bool isSwapped = m_manifoldPtr->getBody0() != m_body0;
00925 btVector3 pointA = pointInWorld + normalOnBInWorld * depth;
00926 btVector3 localA;
00927 btVector3 localB;
00928 if (isSwapped)
00929 {
00930 localA = m_rootTransB.invXform(pointA );
00931 localB = m_rootTransA.invXform(pointInWorld);
00932 } else
00933 {
00934 localA = m_rootTransA.invXform(pointA );
00935 localB = m_rootTransB.invXform(pointInWorld);
00936 }
00937
00938 btManifoldPoint newPt(localA,localB,normalOnBInWorld,depth);
00939 newPt.m_positionWorldOnA = pointA;
00940 newPt.m_positionWorldOnB = pointInWorld;
00941
00942
00943 if (isSwapped)
00944 {
00945 newPt.m_partId0 = m_partId1;
00946 newPt.m_partId1 = m_partId0;
00947 newPt.m_index0 = m_index1;
00948 newPt.m_index1 = m_index0;
00949 } else
00950 {
00951 newPt.m_partId0 = m_partId0;
00952 newPt.m_partId1 = m_partId1;
00953 newPt.m_index0 = m_index0;
00954 newPt.m_index1 = m_index1;
00955 }
00956
00957
00958 btCollisionObject* obj0 = isSwapped? m_body1 : m_body0;
00959 btCollisionObject* obj1 = isSwapped? m_body0 : m_body1;
00960 m_resultCallback.addSingleResult(newPt,obj0,newPt.m_partId0,newPt.m_index0,obj1,newPt.m_partId1,newPt.m_index1);
00961
00962 }
00963
00964 };
00965
00966
00967
00968 struct btSingleContactCallback : public btBroadphaseAabbCallback
00969 {
00970
00971 btCollisionObject* m_collisionObject;
00972 btCollisionWorld* m_world;
00973 btCollisionWorld::ContactResultCallback& m_resultCallback;
00974
00975
00976 btSingleContactCallback(btCollisionObject* collisionObject, btCollisionWorld* world,btCollisionWorld::ContactResultCallback& resultCallback)
00977 :m_collisionObject(collisionObject),
00978 m_world(world),
00979 m_resultCallback(resultCallback)
00980 {
00981 }
00982
00983 virtual bool process(const btBroadphaseProxy* proxy)
00984 {
00985 btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject;
00986 if (collisionObject == m_collisionObject)
00987 return true;
00988
00989
00990 if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
00991 {
00992 btCollisionAlgorithm* algorithm = m_world->getDispatcher()->findAlgorithm(m_collisionObject,collisionObject);
00993 if (algorithm)
00994 {
00995 btBridgedManifoldResult contactPointResult(m_collisionObject,collisionObject, m_resultCallback);
00996
00997 algorithm->processCollision(m_collisionObject,collisionObject, m_world->getDispatchInfo(),&contactPointResult);
00998
00999 algorithm->~btCollisionAlgorithm();
01000 m_world->getDispatcher()->freeCollisionAlgorithm(algorithm);
01001 }
01002 }
01003 return true;
01004 }
01005 };
01006
01007
01010 void btCollisionWorld::contactTest( btCollisionObject* colObj, ContactResultCallback& resultCallback)
01011 {
01012 btVector3 aabbMin,aabbMax;
01013 colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(),aabbMin,aabbMax);
01014 btSingleContactCallback contactCB(colObj,this,resultCallback);
01015
01016 m_broadphasePairCache->aabbTest(aabbMin,aabbMax,contactCB);
01017 }
01018
01019
01022 void btCollisionWorld::contactPairTest(btCollisionObject* colObjA, btCollisionObject* colObjB, ContactResultCallback& resultCallback)
01023 {
01024 btCollisionAlgorithm* algorithm = getDispatcher()->findAlgorithm(colObjA,colObjB);
01025 if (algorithm)
01026 {
01027 btBridgedManifoldResult contactPointResult(colObjA,colObjB, resultCallback);
01028
01029 algorithm->processCollision(colObjA,colObjB, getDispatchInfo(),&contactPointResult);
01030
01031 algorithm->~btCollisionAlgorithm();
01032 getDispatcher()->freeCollisionAlgorithm(algorithm);
01033 }
01034
01035 }
01036
01037
01038
01039
01040 class DebugDrawcallback : public btTriangleCallback, public btInternalTriangleIndexCallback
01041 {
01042 btIDebugDraw* m_debugDrawer;
01043 btVector3 m_color;
01044 btTransform m_worldTrans;
01045
01046 public:
01047
01048 DebugDrawcallback(btIDebugDraw* debugDrawer,const btTransform& worldTrans,const btVector3& color) :
01049 m_debugDrawer(debugDrawer),
01050 m_color(color),
01051 m_worldTrans(worldTrans)
01052 {
01053 }
01054
01055 virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex)
01056 {
01057 processTriangle(triangle,partId,triangleIndex);
01058 }
01059
01060 virtual void processTriangle(btVector3* triangle,int partId, int triangleIndex)
01061 {
01062 (void)partId;
01063 (void)triangleIndex;
01064
01065 btVector3 wv0,wv1,wv2;
01066 wv0 = m_worldTrans*triangle[0];
01067 wv1 = m_worldTrans*triangle[1];
01068 wv2 = m_worldTrans*triangle[2];
01069 btVector3 center = (wv0+wv1+wv2)*btScalar(1./3.);
01070
01071 btVector3 normal = (wv1-wv0).cross(wv2-wv0);
01072 normal.normalize();
01073 btVector3 normalColor(1,1,0);
01074 m_debugDrawer->drawLine(center,center+normal,normalColor);
01075
01076
01077
01078
01079 m_debugDrawer->drawLine(wv0,wv1,m_color);
01080 m_debugDrawer->drawLine(wv1,wv2,m_color);
01081 m_debugDrawer->drawLine(wv2,wv0,m_color);
01082 }
01083 };
01084
01085
01086 void btCollisionWorld::debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color)
01087 {
01088
01089 {
01090 btVector3 start = worldTransform.getOrigin();
01091 getDebugDrawer()->drawLine(start, start+worldTransform.getBasis() * btVector3(1,0,0), btVector3(1,0,0));
01092 getDebugDrawer()->drawLine(start, start+worldTransform.getBasis() * btVector3(0,1,0), btVector3(0,1,0));
01093 getDebugDrawer()->drawLine(start, start+worldTransform.getBasis() * btVector3(0,0,1), btVector3(0,0,1));
01094 }
01095
01096 if (shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE)
01097 {
01098 const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(shape);
01099 for (int i=compoundShape->getNumChildShapes()-1;i>=0;i--)
01100 {
01101 btTransform childTrans = compoundShape->getChildTransform(i);
01102 const btCollisionShape* colShape = compoundShape->getChildShape(i);
01103 debugDrawObject(worldTransform*childTrans,colShape,color);
01104 }
01105
01106 } else
01107 {
01108 switch (shape->getShapeType())
01109 {
01110
01111 case BOX_SHAPE_PROXYTYPE:
01112 {
01113 const btBoxShape* boxShape = static_cast<const btBoxShape*>(shape);
01114 btVector3 halfExtents = boxShape->getHalfExtentsWithMargin();
01115 getDebugDrawer()->drawBox(-halfExtents,halfExtents,worldTransform,color);
01116 break;
01117 }
01118
01119 case SPHERE_SHAPE_PROXYTYPE:
01120 {
01121 const btSphereShape* sphereShape = static_cast<const btSphereShape*>(shape);
01122 btScalar radius = sphereShape->getMargin();
01123
01124 getDebugDrawer()->drawSphere(radius, worldTransform, color);
01125 break;
01126 }
01127 case MULTI_SPHERE_SHAPE_PROXYTYPE:
01128 {
01129 const btMultiSphereShape* multiSphereShape = static_cast<const btMultiSphereShape*>(shape);
01130
01131 btTransform childTransform;
01132 childTransform.setIdentity();
01133
01134 for (int i = multiSphereShape->getSphereCount()-1; i>=0;i--)
01135 {
01136 childTransform.setOrigin(multiSphereShape->getSpherePosition(i));
01137 getDebugDrawer()->drawSphere(multiSphereShape->getSphereRadius(i), worldTransform*childTransform, color);
01138 }
01139
01140 break;
01141 }
01142 case CAPSULE_SHAPE_PROXYTYPE:
01143 {
01144 const btCapsuleShape* capsuleShape = static_cast<const btCapsuleShape*>(shape);
01145
01146 btScalar radius = capsuleShape->getRadius();
01147 btScalar halfHeight = capsuleShape->getHalfHeight();
01148
01149 int upAxis = capsuleShape->getUpAxis();
01150
01151
01152 btVector3 capStart(0.f,0.f,0.f);
01153 capStart[upAxis] = -halfHeight;
01154
01155 btVector3 capEnd(0.f,0.f,0.f);
01156 capEnd[upAxis] = halfHeight;
01157
01158
01159 {
01160
01161 btTransform childTransform = worldTransform;
01162 childTransform.getOrigin() = worldTransform * capStart;
01163 getDebugDrawer()->drawSphere(radius, childTransform, color);
01164 }
01165
01166 {
01167 btTransform childTransform = worldTransform;
01168 childTransform.getOrigin() = worldTransform * capEnd;
01169 getDebugDrawer()->drawSphere(radius, childTransform, color);
01170 }
01171
01172
01173 btVector3 start = worldTransform.getOrigin();
01174
01175
01176 capStart[(upAxis+1)%3] = radius;
01177 capEnd[(upAxis+1)%3] = radius;
01178 getDebugDrawer()->drawLine(start+worldTransform.getBasis() * capStart,start+worldTransform.getBasis() * capEnd, color);
01179 capStart[(upAxis+1)%3] = -radius;
01180 capEnd[(upAxis+1)%3] = -radius;
01181 getDebugDrawer()->drawLine(start+worldTransform.getBasis() * capStart,start+worldTransform.getBasis() * capEnd, color);
01182
01183 capStart[(upAxis+1)%3] = 0.f;
01184 capEnd[(upAxis+1)%3] = 0.f;
01185
01186 capStart[(upAxis+2)%3] = radius;
01187 capEnd[(upAxis+2)%3] = radius;
01188 getDebugDrawer()->drawLine(start+worldTransform.getBasis() * capStart,start+worldTransform.getBasis() * capEnd, color);
01189 capStart[(upAxis+2)%3] = -radius;
01190 capEnd[(upAxis+2)%3] = -radius;
01191 getDebugDrawer()->drawLine(start+worldTransform.getBasis() * capStart,start+worldTransform.getBasis() * capEnd, color);
01192
01193
01194 break;
01195 }
01196 case CONE_SHAPE_PROXYTYPE:
01197 {
01198 const btConeShape* coneShape = static_cast<const btConeShape*>(shape);
01199 btScalar radius = coneShape->getRadius();
01200 btScalar height = coneShape->getHeight();
01201 btVector3 start = worldTransform.getOrigin();
01202
01203 int upAxis= coneShape->getConeUpIndex();
01204
01205
01206 btVector3 offsetHeight(0,0,0);
01207 offsetHeight[upAxis] = height * btScalar(0.5);
01208 btVector3 offsetRadius(0,0,0);
01209 offsetRadius[(upAxis+1)%3] = radius;
01210 btVector3 offset2Radius(0,0,0);
01211 offset2Radius[(upAxis+2)%3] = radius;
01212
01213 getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight),start+worldTransform.getBasis() * (-offsetHeight+offsetRadius),color);
01214 getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight),start+worldTransform.getBasis() * (-offsetHeight-offsetRadius),color);
01215 getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight),start+worldTransform.getBasis() * (-offsetHeight+offset2Radius),color);
01216 getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight),start+worldTransform.getBasis() * (-offsetHeight-offset2Radius),color);
01217
01218
01219
01220 break;
01221
01222 }
01223 case CYLINDER_SHAPE_PROXYTYPE:
01224 {
01225 const btCylinderShape* cylinder = static_cast<const btCylinderShape*>(shape);
01226 int upAxis = cylinder->getUpAxis();
01227 btScalar radius = cylinder->getRadius();
01228 btScalar halfHeight = cylinder->getHalfExtentsWithMargin()[upAxis];
01229 btVector3 start = worldTransform.getOrigin();
01230 btVector3 offsetHeight(0,0,0);
01231 offsetHeight[upAxis] = halfHeight;
01232 btVector3 offsetRadius(0,0,0);
01233 offsetRadius[(upAxis+1)%3] = radius;
01234 getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight+offsetRadius),start+worldTransform.getBasis() * (-offsetHeight+offsetRadius),color);
01235 getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight-offsetRadius),start+worldTransform.getBasis() * (-offsetHeight-offsetRadius),color);
01236 break;
01237 }
01238
01239 case STATIC_PLANE_PROXYTYPE:
01240 {
01241 const btStaticPlaneShape* staticPlaneShape = static_cast<const btStaticPlaneShape*>(shape);
01242 btScalar planeConst = staticPlaneShape->getPlaneConstant();
01243 const btVector3& planeNormal = staticPlaneShape->getPlaneNormal();
01244 btVector3 planeOrigin = planeNormal * planeConst;
01245 btVector3 vec0,vec1;
01246 btPlaneSpace1(planeNormal,vec0,vec1);
01247 btScalar vecLen = 100.f;
01248 btVector3 pt0 = planeOrigin + vec0*vecLen;
01249 btVector3 pt1 = planeOrigin - vec0*vecLen;
01250 btVector3 pt2 = planeOrigin + vec1*vecLen;
01251 btVector3 pt3 = planeOrigin - vec1*vecLen;
01252 getDebugDrawer()->drawLine(worldTransform*pt0,worldTransform*pt1,color);
01253 getDebugDrawer()->drawLine(worldTransform*pt2,worldTransform*pt3,color);
01254 break;
01255
01256 }
01257 default:
01258 {
01259
01260 if (shape->isConcave())
01261 {
01262 btConcaveShape* concaveMesh = (btConcaveShape*) shape;
01263
01265 btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
01266 btVector3 aabbMin(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
01267
01268 DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color);
01269 concaveMesh->processAllTriangles(&drawCallback,aabbMin,aabbMax);
01270
01271 }
01272
01273 if (shape->getShapeType() == CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE)
01274 {
01275 btConvexTriangleMeshShape* convexMesh = (btConvexTriangleMeshShape*) shape;
01276
01277 btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
01278 btVector3 aabbMin(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
01279
01280 DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color);
01281 convexMesh->getMeshInterface()->InternalProcessAllTriangles(&drawCallback,aabbMin,aabbMax);
01282 }
01283
01284
01286 if (shape->isPolyhedral())
01287 {
01288 btPolyhedralConvexShape* polyshape = (btPolyhedralConvexShape*) shape;
01289
01290 int i;
01291 for (i=0;i<polyshape->getNumEdges();i++)
01292 {
01293 btVector3 a,b;
01294 polyshape->getEdge(i,a,b);
01295 btVector3 wa = worldTransform * a;
01296 btVector3 wb = worldTransform * b;
01297 getDebugDrawer()->drawLine(wa,wb,color);
01298
01299 }
01300
01301
01302 }
01303 }
01304 }
01305 }
01306 }
01307
01308
01309 void btCollisionWorld::debugDrawWorld()
01310 {
01311 if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints)
01312 {
01313 int numManifolds = getDispatcher()->getNumManifolds();
01314 btVector3 color(0,0,0);
01315 for (int i=0;i<numManifolds;i++)
01316 {
01317 btPersistentManifold* contactManifold = getDispatcher()->getManifoldByIndexInternal(i);
01318
01319
01320
01321 int numContacts = contactManifold->getNumContacts();
01322 for (int j=0;j<numContacts;j++)
01323 {
01324 btManifoldPoint& cp = contactManifold->getContactPoint(j);
01325 getDebugDrawer()->drawContactPoint(cp.m_positionWorldOnB,cp.m_normalWorldOnB,cp.getDistance(),cp.getLifeTime(),color);
01326 }
01327 }
01328 }
01329
01330 if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe | btIDebugDraw::DBG_DrawAabb))
01331 {
01332 int i;
01333
01334 for ( i=0;i<m_collisionObjects.size();i++)
01335 {
01336 btCollisionObject* colObj = m_collisionObjects[i];
01337 if ((colObj->getCollisionFlags() & btCollisionObject::CF_DISABLE_VISUALIZE_OBJECT)==0)
01338 {
01339 if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawWireframe)
01340 {
01341 btVector3 color(btScalar(1.),btScalar(1.),btScalar(1.));
01342 switch(colObj->getActivationState())
01343 {
01344 case ACTIVE_TAG:
01345 color = btVector3(btScalar(1.),btScalar(1.),btScalar(1.)); break;
01346 case ISLAND_SLEEPING:
01347 color = btVector3(btScalar(0.),btScalar(1.),btScalar(0.));break;
01348 case WANTS_DEACTIVATION:
01349 color = btVector3(btScalar(0.),btScalar(1.),btScalar(1.));break;
01350 case DISABLE_DEACTIVATION:
01351 color = btVector3(btScalar(1.),btScalar(0.),btScalar(0.));break;
01352 case DISABLE_SIMULATION:
01353 color = btVector3(btScalar(1.),btScalar(1.),btScalar(0.));break;
01354 default:
01355 {
01356 color = btVector3(btScalar(1),btScalar(0.),btScalar(0.));
01357 }
01358 };
01359
01360 debugDrawObject(colObj->getWorldTransform(),colObj->getCollisionShape(),color);
01361 }
01362 if (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawAabb))
01363 {
01364 btVector3 minAabb,maxAabb;
01365 btVector3 colorvec(1,0,0);
01366 colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);
01367 m_debugDrawer->drawAabb(minAabb,maxAabb,colorvec);
01368 }
01369 }
01370
01371 }
01372 }
01373 }
01374
01375
01376 void btCollisionWorld::serializeCollisionObjects(btSerializer* serializer)
01377 {
01378 int i;
01379
01380 for (i=0;i<m_collisionObjects.size();i++)
01381 {
01382 btCollisionObject* colObj = m_collisionObjects[i];
01383 if (colObj->getInternalType() == btCollisionObject::CO_COLLISION_OBJECT)
01384 {
01385 btChunk* chunk = serializer->allocate(colObj->calculateSerializeBufferSize(),1);
01386 const char* structType = colObj->serialize(chunk->m_oldPtr, serializer);
01387 serializer->finalizeChunk(chunk,structType,BT_COLLISIONOBJECT_CODE,colObj);
01388 }
01389 }
01390
01392 btHashMap<btHashPtr,btCollisionShape*> serializedShapes;
01393
01394 for (i=0;i<m_collisionObjects.size();i++)
01395 {
01396 btCollisionObject* colObj = m_collisionObjects[i];
01397 btCollisionShape* shape = colObj->getCollisionShape();
01398
01399 if (!serializedShapes.find(shape))
01400 {
01401 serializedShapes.insert(shape,shape);
01402
01403 int len = shape->calculateSerializeBufferSize();
01404 btChunk* chunk = serializer->allocate(len,1);
01405 const char* structType = shape->serialize(chunk->m_oldPtr, serializer);
01406 serializer->finalizeChunk(chunk,structType,BT_SHAPE_CODE,shape);
01407 }
01408 }
01409
01410 }
01411
01412
01413 void btCollisionWorld::serialize(btSerializer* serializer)
01414 {
01415
01416 serializeCollisionObjects(serializer);
01417
01418 serializer->finishSerialization();
01419 }
01420