btCollisionWorld.cpp

Go to the documentation of this file.
00001 /*
00002 Bullet Continuous Collision Detection and Physics Library
00003 Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
00004 
00005 This software is provided 'as-is', without any express or implied warranty.
00006 In no event will the authors be held liable for any damages arising from the use of this software.
00007 Permission is granted to anyone to use this software for any purpose,
00008 including commercial applications, and to alter it and redistribute it freely,
00009 subject to the following restrictions:
00010 
00011 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.
00012 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
00013 3. This notice may not be removed or altered from any source distribution.
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" //for raycasting
00023 #include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h" //for raycasting
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 //#define USE_BRUTEFORCE_RAYBROADPHASE 1
00037 //RECALCULATE_AABB is slower, but benefit is that you don't need to call 'stepSimulation'  or 'updateAabbs' before using a rayTest
00038 //#define RECALCULATE_AABB_RAYCAST 1
00039 
00040 //When the user doesn't provide dispatcher or broadphase, create basic versions (and delete them in destructor)
00041 #include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
00042 #include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h"
00043 #include "BulletCollision/CollisionDispatch/btCollisionConfiguration.h"
00044 
00045 
00047 
00048 //for debug rendering
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         //clean up remaining objects
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                         // only clear the cached algorithms
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         //check that the object isn't already added
00114         btAssert( m_collisionObjects.findLinearSearch(collisionObject)  == m_collisionObjects.size());
00115 
00116         m_collisionObjects.push_back(collisionObject);
00117 
00118         //calculate new AABB
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         //need to increase the aabb for contact thresholds
00149         btVector3 contactThreshold(gContactBreakingThreshold,gContactBreakingThreshold,gContactBreakingThreshold);
00150         minAabb -= contactThreshold;
00151         maxAabb += contactThreshold;
00152 
00153         btBroadphaseInterface* bp = (btBroadphaseInterface*)m_broadphasePairCache;
00154 
00155         //moving objects should be moderately sized, probably something wrong if not
00156         if ( colObj->isStaticObject() || ((maxAabb-minAabb).length2() < btScalar(1e12)))
00157         {
00158                 bp->setAabb(colObj->getBroadphaseHandle(),minAabb,maxAabb, m_dispatcher1);
00159         } else
00160         {
00161                 //something went wrong, investigate
00162                 //this assert is unwanted in 3D modelers (danger of loosing work)
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                 //only update aabb of active objects
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         //bool removeFromBroadphase = false;
00226 
00227         {
00228 
00229                 btBroadphaseProxy* bp = collisionObject->getBroadphaseHandle();
00230                 if (bp)
00231                 {
00232                         //
00233                         // only clear the cached algorithms
00234                         //
00235                         getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(bp,m_dispatcher1);
00236                         getBroadphase()->destroyProxy(bp,m_dispatcher1);
00237                         collisionObject->setBroadphaseHandle(0);
00238                 }
00239         }
00240 
00241 
00242         //swapremove
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                 //              BT_PROFILE("rayTestConvex");
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                 //btGjkConvexCast       convexCaster(castShape,convexShape,&simplexSolver);
00272                 //btContinuousConvexCollision convexCaster(castShape,convexShape,&simplexSolver,0);
00273 #endif //#USE_SUBSIMPLEX_CONVEX_CAST
00274 
00275                 if (convexCaster.calcTimeOfImpact(rayFromTrans,rayToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
00276                 {
00277                         //add hit
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                                         //rotate normal into worldspace
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                         //                      BT_PROFILE("rayTestConcave");
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                                 //ConvexCast::CastResult
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                                         //@BP Mod
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                                 //generic (slower) case
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                                 //ConvexCast::CastResult
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                                         //@BP Mod
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                         //                      BT_PROFILE("rayTestCompound");
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                                         // replace collision shape so that callback can determine the triangle
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                                         // restore
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                 //BT_PROFILE("convexSweepConvex");
00480                 btConvexCast::CastResult castResult;
00481                 castResult.m_allowedPenetration = allowedPenetration;
00482                 castResult.m_fraction = resultCallback.m_closestHitFraction;//btScalar(1.);//??
00483 
00484                 btConvexShape* convexShape = (btConvexShape*) collisionShape;
00485                 btVoronoiSimplexSolver  simplexSolver;
00486                 btGjkEpaPenetrationDepthSolver  gjkEpaPenetrationSolver;
00487 
00488                 btContinuousConvexCollision convexCaster1(castShape,convexShape,&simplexSolver,&gjkEpaPenetrationSolver);
00489                 //btGjkConvexCast convexCaster2(castShape,convexShape,&simplexSolver);
00490                 //btSubsimplexConvexCast convexCaster3(castShape,convexShape,&simplexSolver);
00491 
00492                 btConvexCast* castPtr = &convexCaster1;
00493 
00494 
00495 
00496                 if (castPtr->calcTimeOfImpact(convexFromTrans,convexToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
00497                 {
00498                         //add hit
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                                 //BT_PROFILE("convexSweepbtBvhTriangleMesh");
00525                                 btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape;
00526                                 btTransform worldTocollisionObject = colObjWorldTransform.inverse();
00527                                 btVector3 convexFromLocal = worldTocollisionObject * convexFromTrans.getOrigin();
00528                                 btVector3 convexToLocal = worldTocollisionObject * convexToTrans.getOrigin();
00529                                 // rotation of box in local mesh space = MeshRotation^-1 * ConvexToRotation
00530                                 btTransform rotationXform = btTransform(worldTocollisionObject.getBasis() * convexToTrans.getBasis());
00531 
00532                                 //ConvexCast::CastResult
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                                 //BT_PROFILE("convexSweepConcave");
00582                                 btConcaveShape* concaveShape = (btConcaveShape*)collisionShape;
00583                                 btTransform worldTocollisionObject = colObjWorldTransform.inverse();
00584                                 btVector3 convexFromLocal = worldTocollisionObject * convexFromTrans.getOrigin();
00585                                 btVector3 convexToLocal = worldTocollisionObject * convexToTrans.getOrigin();
00586                                 // rotation of box in local mesh space = MeshRotation^-1 * ConvexToRotation
00587                                 btTransform rotationXform = btTransform(worldTocollisionObject.getBasis() * convexToTrans.getBasis());
00588 
00589                                 //ConvexCast::CastResult
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                                         // replace collision shape so that callback can determine the triangle
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                                         // restore
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                 //only perform raycast if filterMask matches
00741                 if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) 
00742                 {
00743                         //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
00744                         //btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
00745 #if 0
00746 #ifdef RECALCULATE_AABB
00747                         btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
00748                         collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
00749 #else
00750                         //getBroadphase()->getAabb(collisionObject->getBroadphaseHandle(),collisionObjectAabbMin,collisionObjectAabbMax);
00751                         const btVector3& collisionObjectAabbMin = collisionObject->getBroadphaseHandle()->m_aabbMin;
00752                         const btVector3& collisionObjectAabbMax = collisionObject->getBroadphaseHandle()->m_aabbMax;
00753 #endif
00754 #endif
00755                         //btScalar hitLambda = m_resultCallback.m_closestHitFraction;
00756                         //culling already done by broadphase
00757                         //if (btRayAabb(m_rayFromWorld,m_rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,m_hitNormal))
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         //BT_PROFILE("rayTest");
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                 //only perform raycast if filterMask matches
00832                 if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) {
00833                         //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
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         /* Compute AABB that encompasses angular movement */
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                 //only perform raycast if filterMask matches
00888                 if(resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) {
00889                         //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
00890                         btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
00891                         collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
00892                         AabbExpand (collisionObjectAabbMin, collisionObjectAabbMax, castShapeAabbMin, castShapeAabbMax);
00893                         btScalar hitLambda = btScalar(1.); //could use resultCallback.m_closestHitFraction, but needs testing
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            //BP mod, store contact triangles.
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                 //experimental feature info, for per-triangle material etc.
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                 //only perform raycast if filterMask matches
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                                 //discrete collision detection query
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                 //discrete collision detection query
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         // Draw a small simplex at the center of the object
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();//radius doesn't include the margin, so draw with margin
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                                 // Draw the ends
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                                 // Draw some additional lines
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();//+coneShape->getMargin();
01200                                 btScalar height = coneShape->getHeight();//+coneShape->getMargin();
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                                         //todo: pass camera for some culling                    
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                                         //DebugDrawcallback drawCallback;
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                         //btCollisionObject* obA = static_cast<btCollisionObject*>(contactManifold->getBody0());
01319                         //btCollisionObject* obB = static_cast<btCollisionObject*>(contactManifold->getBody1());
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         //serialize all collision objects
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                         //serialize all collision shapes
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 

Generated on Mon Feb 15 22:17:02 2010 for Bullet Collision Detection & Physics Library by  doxygen 1.6.1