Back to index

supertuxkart  0.5+dfsg1
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 
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 
00030 #include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
00031 #include "LinearMath/btAabbUtil2.h"
00032 #include "LinearMath/btQuickprof.h"
00033 #include "LinearMath/btStackAlloc.h"
00034 
00035 
00036 //When the user doesn't provide dispatcher or broadphase, create basic versions (and delete them in destructor)
00037 #include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
00038 #include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h"
00039 #include "BulletCollision/CollisionDispatch/btCollisionConfiguration.h"
00040 
00041 
00042 btCollisionWorld::btCollisionWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache, btCollisionConfiguration* collisionConfiguration)
00043 :m_dispatcher1(dispatcher),
00044 m_broadphasePairCache(pairCache),
00045 m_debugDrawer(0)
00046 {
00047        m_stackAlloc = collisionConfiguration->getStackAllocator();
00048        m_dispatchInfo.m_stackAllocator = m_stackAlloc;
00049 }
00050 
00051 
00052 btCollisionWorld::~btCollisionWorld()
00053 {
00054 
00055        //clean up remaining objects
00056        int i;
00057        for (i=0;i<m_collisionObjects.size();i++)
00058        {
00059               btCollisionObject* collisionObject= m_collisionObjects[i];
00060               
00061               btBroadphaseProxy* bp = collisionObject->getBroadphaseHandle();
00062               if (bp)
00063               {
00064                      //
00065                      // only clear the cached algorithms
00066                      //
00067                      getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(bp,m_dispatcher1);
00068                      getBroadphase()->destroyProxy(bp,m_dispatcher1);
00069               }
00070        }
00071 
00072 
00073 }
00074 
00075 
00076 
00077 
00078 
00079 
00080 
00081 
00082 
00083 
00084 void   btCollisionWorld::addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup,short int collisionFilterMask)
00085 {
00086 
00087        //check that the object isn't already added
00088               btAssert( m_collisionObjects.findLinearSearch(collisionObject)  == m_collisionObjects.size());
00089 
00090               m_collisionObjects.push_back(collisionObject);
00091 
00092               //calculate new AABB
00093               btTransform trans = collisionObject->getWorldTransform();
00094 
00095               btVector3     minAabb;
00096               btVector3     maxAabb;
00097               collisionObject->getCollisionShape()->getAabb(trans,minAabb,maxAabb);
00098 
00099               int type = collisionObject->getCollisionShape()->getShapeType();
00100               collisionObject->setBroadphaseHandle( getBroadphase()->createProxy(
00101                      minAabb,
00102                      maxAabb,
00103                      type,
00104                      collisionObject,
00105                      collisionFilterGroup,
00106                      collisionFilterMask,
00107                      m_dispatcher1,0
00108                      ))     ;
00109 
00110               
00111 
00112 
00113 
00114 }
00115 
00116 void   btCollisionWorld::updateAabbs()
00117 {
00118        BT_PROFILE("updateAabbs");
00119        
00120        btTransform predictedTrans;
00121        for ( int i=0;i<m_collisionObjects.size();i++)
00122        {
00123               btCollisionObject* colObj = m_collisionObjects[i];
00124               
00125               //only update aabb of active objects
00126               if (colObj->isActive())
00127               {
00128                      btPoint3 minAabb,maxAabb;
00129                      colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);
00130                      btBroadphaseInterface* bp = (btBroadphaseInterface*)m_broadphasePairCache;
00131 
00132                      //moving objects should be moderately sized, probably something wrong if not
00133                      if ( colObj->isStaticObject() || ((maxAabb-minAabb).length2() < btScalar(1e12)))
00134                      {
00135                             bp->setAabb(colObj->getBroadphaseHandle(),minAabb,maxAabb, m_dispatcher1);
00136                      } else
00137                      {
00138                             //something went wrong, investigate
00139                             //this assert is unwanted in 3D modelers (danger of loosing work)
00140                             colObj->setActivationState(DISABLE_SIMULATION);
00141                             
00142                             static bool reportMe = true;
00143                             if (reportMe && m_debugDrawer)
00144                             {
00145                                    reportMe = false;
00146                                    m_debugDrawer->reportErrorWarning("Overflow in AABB, object removed from simulation");
00147                                    m_debugDrawer->reportErrorWarning("If you can reproduce this, please email bugs@continuousphysics.com\n");
00148                                    m_debugDrawer->reportErrorWarning("Please include above information, your Platform, version of OS.\n");
00149                                    m_debugDrawer->reportErrorWarning("Thanks.\n");
00150                             }
00151                      }
00152               }
00153        }
00154        
00155 }
00156 
00157 
00158 
00159 void   btCollisionWorld::performDiscreteCollisionDetection()
00160 {
00161        BT_PROFILE("performDiscreteCollisionDetection");
00162 
00163        btDispatcherInfo& dispatchInfo = getDispatchInfo();
00164 
00165        updateAabbs();
00166 
00167        {
00168               m_broadphasePairCache->calculateOverlappingPairs(m_dispatcher1);
00169        }
00170 
00171 
00172        btDispatcher* dispatcher = getDispatcher();
00173        {
00174               BT_PROFILE("dispatchAllCollisionPairs");
00175               if (dispatcher)
00176                      dispatcher->dispatchAllCollisionPairs(m_broadphasePairCache->getOverlappingPairCache(),dispatchInfo,m_dispatcher1);
00177        }
00178 
00179 }
00180 
00181 
00182 
00183 void   btCollisionWorld::removeCollisionObject(btCollisionObject* collisionObject)
00184 {
00185        
00186        
00187        //bool removeFromBroadphase = false;
00188        
00189        {
00190               
00191               btBroadphaseProxy* bp = collisionObject->getBroadphaseHandle();
00192               if (bp)
00193               {
00194                      //
00195                      // only clear the cached algorithms
00196                      //
00197                      getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(bp,m_dispatcher1);
00198                      getBroadphase()->destroyProxy(bp,m_dispatcher1);
00199                      collisionObject->setBroadphaseHandle(0);
00200               }
00201        }
00202 
00203 
00204        //swapremove
00205        m_collisionObjects.remove(collisionObject);
00206 
00207 }
00208 
00209 
00210 
00211 void   btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans,
00212                                      btCollisionObject* collisionObject,
00213                                      const btCollisionShape* collisionShape,
00214                                      const btTransform& colObjWorldTransform,
00215                                      RayResultCallback& resultCallback,short int collisionFilterMask)
00216 {
00217        btSphereShape pointShape(btScalar(0.0));
00218        pointShape.setMargin(0.f);
00219        const btConvexShape* castShape = &pointShape;
00220 
00221        if (collisionShape->isConvex())
00222        {
00223               btConvexCast::CastResult castResult;
00224               castResult.m_fraction = resultCallback.m_closestHitFraction;
00225 
00226               btConvexShape* convexShape = (btConvexShape*) collisionShape;
00227               btVoronoiSimplexSolver      simplexSolver;
00228 #define USE_SUBSIMPLEX_CONVEX_CAST 1
00229 #ifdef USE_SUBSIMPLEX_CONVEX_CAST
00230               btSubsimplexConvexCast convexCaster(castShape,convexShape,&simplexSolver);
00231 #else
00232               //btGjkConvexCast    convexCaster(castShape,convexShape,&simplexSolver);
00233               //btContinuousConvexCollision convexCaster(castShape,convexShape,&simplexSolver,0);
00234 #endif //#USE_SUBSIMPLEX_CONVEX_CAST
00235                      
00236               if (convexCaster.calcTimeOfImpact(rayFromTrans,rayToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
00237               {
00238                      //add hit
00239                      if (castResult.m_normal.length2() > btScalar(0.0001))
00240                      {                           
00241                             if (castResult.m_fraction < resultCallback.m_closestHitFraction)
00242                             {
00243 #ifdef USE_SUBSIMPLEX_CONVEX_CAST
00244                                    //rotate normal into worldspace
00245                                    castResult.m_normal = rayFromTrans.getBasis() * castResult.m_normal;
00246 #endif //USE_SUBSIMPLEX_CONVEX_CAST
00247 
00248                                    castResult.m_normal.normalize();
00249                                    btCollisionWorld::LocalRayResult localRayResult
00250                                           (
00251                                                  collisionObject, 
00252                                                  0,
00253                                                  castResult.m_normal,
00254                                                  castResult.m_fraction
00255                                           );
00256 
00257                                    bool normalInWorldSpace = true;
00258                                    resultCallback.AddSingleResult(localRayResult, normalInWorldSpace);
00259 
00260                             }
00261                      }
00262               }
00263        } else {
00264               if (collisionShape->isConcave())
00265               {
00266                      if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE)
00267                      {
00269                             btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape;
00270                             btTransform worldTocollisionObject = colObjWorldTransform.inverse();
00271                             btVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin();
00272                             btVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin();
00273 
00274                             //ConvexCast::CastResult
00275                             struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback 
00276                             {
00277                                    btCollisionWorld::RayResultCallback* m_resultCallback;
00278                                    btCollisionObject*   m_collisionObject;
00279                                    btTriangleMeshShape* m_triangleMesh;
00280 
00281                                    BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,
00282                                           btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape*    triangleMesh):
00283                                           btTriangleRaycastCallback(from,to),
00284                                                  m_resultCallback(resultCallback),
00285                                                  m_collisionObject(collisionObject),
00286                                                  m_triangleMesh(triangleMesh)
00287                                           {
00288                                           }
00289 
00290 
00291                                    virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex )
00292                                    {
00293                                           btCollisionWorld::LocalShapeInfo   shapeInfo;
00294                                           shapeInfo.m_shapePart = partId;
00295                                           shapeInfo.m_triangleIndex = triangleIndex;
00296                                           
00297                                           btCollisionWorld::LocalRayResult rayResult
00298                                           (m_collisionObject, 
00299                                                  &shapeInfo,
00300                                                  hitNormalLocal,
00301                                                  hitFraction);
00302                                           
00303                                           bool   normalInWorldSpace = false;
00304                                           return m_resultCallback->AddSingleResult(rayResult,normalInWorldSpace);
00305                                    }
00306 
00307                             };
00308 
00309                             BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,triangleMesh);
00310                             rcb.m_hitFraction = resultCallback.m_closestHitFraction;
00311                             triangleMesh->performRaycast(&rcb,rayFromLocal,rayToLocal);
00312                      } else
00313                      {
00314                             btTriangleMeshShape* triangleMesh = (btTriangleMeshShape*)collisionShape;
00315                             
00316                             btTransform worldTocollisionObject = colObjWorldTransform.inverse();
00317 
00318                             btVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin();
00319                             btVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin();
00320 
00321                             //ConvexCast::CastResult
00322 
00323                             struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback 
00324                             {
00325                                    btCollisionWorld::RayResultCallback* m_resultCallback;
00326                                    btCollisionObject*   m_collisionObject;
00327                                    btTriangleMeshShape* m_triangleMesh;
00328 
00329                                    BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,
00330                                           btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape*    triangleMesh):
00331                                           btTriangleRaycastCallback(from,to),
00332                                                  m_resultCallback(resultCallback),
00333                                                  m_collisionObject(collisionObject),
00334                                                  m_triangleMesh(triangleMesh)
00335                                           {
00336                                           }
00337 
00338 
00339                                    virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex )
00340                                    {
00341                                           btCollisionWorld::LocalShapeInfo   shapeInfo;
00342                                           shapeInfo.m_shapePart = partId;
00343                                           shapeInfo.m_triangleIndex = triangleIndex;
00344                                           
00345                                           btCollisionWorld::LocalRayResult rayResult
00346                                           (m_collisionObject, 
00347                                                  &shapeInfo,
00348                                                  hitNormalLocal,
00349                                                  hitFraction);
00350                                           
00351                                           bool   normalInWorldSpace = false;
00352                                           return m_resultCallback->AddSingleResult(rayResult,normalInWorldSpace);
00353                                           
00354                                           
00355                                    }
00356 
00357                             };
00358 
00359 
00360                             BridgeTriangleRaycastCallback      rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,triangleMesh);
00361                             rcb.m_hitFraction = resultCallback.m_closestHitFraction;
00362 
00363                             btVector3 rayAabbMinLocal = rayFromLocal;
00364                             rayAabbMinLocal.setMin(rayToLocal);
00365                             btVector3 rayAabbMaxLocal = rayFromLocal;
00366                             rayAabbMaxLocal.setMax(rayToLocal);
00367 
00368                             triangleMesh->processAllTriangles(&rcb,rayAabbMinLocal,rayAabbMaxLocal);
00369                      }
00370               } else {
00371                      //todo: use AABB tree or other BVH acceleration structure!
00372                      if (collisionShape->isCompound())
00373                      {
00374                             const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(collisionShape);
00375                             int i=0;
00376                             for (i=0;i<compoundShape->getNumChildShapes();i++)
00377                             {
00378                                    btTransform childTrans = compoundShape->getChildTransform(i);
00379                                    const btCollisionShape* childCollisionShape = compoundShape->getChildShape(i);
00380                                    btTransform childWorldTrans = colObjWorldTransform * childTrans;
00381                                    rayTestSingle(rayFromTrans,rayToTrans,
00382                                           collisionObject,
00383                                           childCollisionShape,
00384                                           childWorldTrans,
00385                                           resultCallback, collisionFilterMask);
00386 
00387                             }
00388                      }
00389               }
00390        }
00391 }
00392 
00393 void   btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const btTransform& convexFromTrans,const btTransform& convexToTrans,
00394                                      btCollisionObject* collisionObject,
00395                                      const btCollisionShape* collisionShape,
00396                                      const btTransform& colObjWorldTransform,
00397                                      ConvexResultCallback& resultCallback,short int collisionFilterMask)
00398 {
00399        if (collisionShape->isConvex())
00400        {
00401               btConvexCast::CastResult castResult;
00402               castResult.m_fraction = btScalar(1.);//??
00403 
00404               btConvexShape* convexShape = (btConvexShape*) collisionShape;
00405               btVoronoiSimplexSolver      simplexSolver;
00406               btContinuousConvexCollision convexCaster(castShape,convexShape,&simplexSolver,0);
00407 
00408               if (convexCaster.calcTimeOfImpact(convexFromTrans,convexToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
00409               {
00410                      //add hit
00411                      if (castResult.m_normal.length2() > btScalar(0.0001))
00412                      {                                  
00413                             if (castResult.m_fraction < resultCallback.m_closestHitFraction)
00414                             {
00415                                    castResult.m_normal.normalize();
00416                                    btCollisionWorld::LocalConvexResult localConvexResult
00417                                                         (
00418                                                                collisionObject, 
00419                                                                0,
00420                                                                castResult.m_normal,
00421                                                                castResult.m_hitPoint,
00422                                                                castResult.m_fraction
00423                                                         );
00424 
00425                                    bool normalInWorldSpace = true;
00426                                    resultCallback.AddSingleResult(localConvexResult, normalInWorldSpace);
00427 
00428                             }
00429                      }
00430               }
00431        } else {
00432               if (collisionShape->isConcave())
00433               {
00434                      if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE)
00435                      {
00436                             btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape;
00437                             btTransform worldTocollisionObject = colObjWorldTransform.inverse();
00438                             btVector3 convexFromLocal = worldTocollisionObject * convexFromTrans.getOrigin();
00439                             btVector3 convexToLocal = worldTocollisionObject * convexToTrans.getOrigin();
00440                             // rotation of box in local mesh space = MeshRotation^-1 * ConvexToRotation
00441                             btTransform rotationXform = btTransform(worldTocollisionObject.getBasis() * convexToTrans.getBasis());
00442 
00443                             //ConvexCast::CastResult
00444                             struct BridgeTriangleConvexcastCallback : public btTriangleConvexcastCallback 
00445                             {
00446                                    btCollisionWorld::ConvexResultCallback* m_resultCallback;
00447                                    btCollisionObject*   m_collisionObject;
00448                                    btTriangleMeshShape* m_triangleMesh;
00449 
00450                                    BridgeTriangleConvexcastCallback(const btConvexShape* castShape, const btTransform& from,const btTransform& to,
00451                                           btCollisionWorld::ConvexResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh, const btTransform& triangleToWorld):
00452                                           btTriangleConvexcastCallback(castShape, from,to, triangleToWorld),
00453                                                  m_resultCallback(resultCallback),
00454                                                  m_collisionObject(collisionObject),
00455                                                  m_triangleMesh(triangleMesh)
00456                                           {
00457                                           }
00458 
00459 
00460                                    virtual btScalar reportHit(const btVector3& hitNormalLocal, const btVector3& hitPointLocal, btScalar hitFraction, int partId, int triangleIndex )
00461                                    {
00462                                           btCollisionWorld::LocalShapeInfo   shapeInfo;
00463                                           shapeInfo.m_shapePart = partId;
00464                                           shapeInfo.m_triangleIndex = triangleIndex;
00465                                           if (hitFraction <= m_resultCallback->m_closestHitFraction)
00466                                           {
00467 
00468                                                  btCollisionWorld::LocalConvexResult convexResult
00469                                                  (m_collisionObject, 
00470                                                         &shapeInfo,
00471                                                         hitNormalLocal,
00472                                                         hitPointLocal,
00473                                                         hitFraction);
00474                                                  
00475                                                  bool   normalInWorldSpace = true;
00476 
00477                                    
00478                                                  return m_resultCallback->AddSingleResult(convexResult,normalInWorldSpace);
00479                                           }
00480                                           return hitFraction;
00481                                    }
00482 
00483                             };
00484 
00485                             BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,collisionObject,triangleMesh, colObjWorldTransform);
00486                             tccb.m_hitFraction = resultCallback.m_closestHitFraction;
00487                             btVector3 boxMinLocal, boxMaxLocal;
00488                             castShape->getAabb(rotationXform, boxMinLocal, boxMaxLocal);
00489                             triangleMesh->performConvexcast(&tccb,convexFromLocal,convexToLocal,boxMinLocal, boxMaxLocal);
00490                      } else
00491                      {
00492                             btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape;
00493                             btTransform worldTocollisionObject = colObjWorldTransform.inverse();
00494                             btVector3 convexFromLocal = worldTocollisionObject * convexFromTrans.getOrigin();
00495                             btVector3 convexToLocal = worldTocollisionObject * convexToTrans.getOrigin();
00496                             // rotation of box in local mesh space = MeshRotation^-1 * ConvexToRotation
00497                             btTransform rotationXform = btTransform(worldTocollisionObject.getBasis() * convexToTrans.getBasis());
00498 
00499                             //ConvexCast::CastResult
00500                             struct BridgeTriangleConvexcastCallback : public btTriangleConvexcastCallback 
00501                             {
00502                                    btCollisionWorld::ConvexResultCallback* m_resultCallback;
00503                                    btCollisionObject*   m_collisionObject;
00504                                    btTriangleMeshShape* m_triangleMesh;
00505 
00506                                    BridgeTriangleConvexcastCallback(const btConvexShape* castShape, const btTransform& from,const btTransform& to,
00507                                           btCollisionWorld::ConvexResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh, const btTransform& triangleToWorld):
00508                                           btTriangleConvexcastCallback(castShape, from,to, triangleToWorld),
00509                                                  m_resultCallback(resultCallback),
00510                                                  m_collisionObject(collisionObject),
00511                                                  m_triangleMesh(triangleMesh)
00512                                           {
00513                                           }
00514 
00515 
00516                                    virtual btScalar reportHit(const btVector3& hitNormalLocal, const btVector3& hitPointLocal, btScalar hitFraction, int partId, int triangleIndex )
00517                                    {
00518                                           btCollisionWorld::LocalShapeInfo   shapeInfo;
00519                                           shapeInfo.m_shapePart = partId;
00520                                           shapeInfo.m_triangleIndex = triangleIndex;
00521                                           if (hitFraction <= m_resultCallback->m_closestHitFraction)
00522                                           {
00523 
00524                                                  btCollisionWorld::LocalConvexResult convexResult
00525                                                  (m_collisionObject, 
00526                                                         &shapeInfo,
00527                                                         hitNormalLocal,
00528                                                         hitPointLocal,
00529                                                         hitFraction);
00530                                                  
00531                                                  bool   normalInWorldSpace = false;
00532 
00533                                                  return m_resultCallback->AddSingleResult(convexResult,normalInWorldSpace);
00534                                           }
00535                                           return hitFraction;
00536                                    }
00537 
00538                             };
00539 
00540                             BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,collisionObject,triangleMesh, colObjWorldTransform);
00541                             tccb.m_hitFraction = resultCallback.m_closestHitFraction;
00542                             btVector3 boxMinLocal, boxMaxLocal;
00543                             castShape->getAabb(rotationXform, boxMinLocal, boxMaxLocal);
00544                             
00545                             btVector3 rayAabbMinLocal = convexFromLocal;
00546                             rayAabbMinLocal.setMin(convexToLocal);
00547                             btVector3 rayAabbMaxLocal = convexFromLocal;
00548                             rayAabbMaxLocal.setMax(convexToLocal);
00549                             rayAabbMinLocal += boxMinLocal;
00550                             rayAabbMaxLocal += boxMaxLocal;
00551                             triangleMesh->processAllTriangles(&tccb,rayAabbMinLocal,rayAabbMaxLocal);
00552                      }
00553               } else {
00554                      //todo: use AABB tree or other BVH acceleration structure!
00555                      if (collisionShape->isCompound())
00556                      {
00557                             const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(collisionShape);
00558                             int i=0;
00559                             for (i=0;i<compoundShape->getNumChildShapes();i++)
00560                             {
00561                                    btTransform childTrans = compoundShape->getChildTransform(i);
00562                                    const btCollisionShape* childCollisionShape = compoundShape->getChildShape(i);
00563                                    btTransform childWorldTrans = colObjWorldTransform * childTrans;
00564                                    objectQuerySingle(castShape, convexFromTrans,convexToTrans,
00565                                           collisionObject,
00566                                           childCollisionShape,
00567                                           childWorldTrans,
00568                                           resultCallback, collisionFilterMask);
00569                             }
00570                      }
00571               }
00572        }
00573 }
00574 
00575 void   btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback,short int collisionFilterMask)
00576 {
00577 
00578        
00579        btTransform   rayFromTrans,rayToTrans;
00580        rayFromTrans.setIdentity();
00581        rayFromTrans.setOrigin(rayFromWorld);
00582        rayToTrans.setIdentity();
00583        
00584        rayToTrans.setOrigin(rayToWorld);
00585 
00587        
00588        int i;
00589        for (i=0;i<m_collisionObjects.size();i++)
00590        {
00592               if (resultCallback.m_closestHitFraction == btScalar(0.f))
00593                      break;
00594 
00595               btCollisionObject*   collisionObject= m_collisionObjects[i];
00596               //only perform raycast if filterMask matches
00597               if(collisionObject->getBroadphaseHandle()->m_collisionFilterGroup & collisionFilterMask) { 
00598                      //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
00599                      btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
00600                      collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
00601 
00602                      btScalar hitLambda = resultCallback.m_closestHitFraction;
00603                      btVector3 hitNormal;
00604                      if (btRayAabb(rayFromWorld,rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,hitNormal))
00605                      {
00606                             rayTestSingle(rayFromTrans,rayToTrans,
00607                                    collisionObject,
00608                                           collisionObject->getCollisionShape(),
00609                                           collisionObject->getWorldTransform(),
00610                                           resultCallback);
00611                      }      
00612               }
00613               
00614        }
00615 
00616 }
00617 
00618 void   btCollisionWorld::convexSweepTest(const btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, ConvexResultCallback& resultCallback,short int collisionFilterMask)
00619 {
00620        btTransform   convexFromTrans,convexToTrans;
00621        convexFromTrans = convexFromWorld;
00622        convexToTrans = convexToWorld;
00623        btVector3 castShapeAabbMin, castShapeAabbMax;
00624        /* Compute AABB that encompasses angular movement */
00625        {
00626               btVector3 linVel, angVel;
00627               btTransformUtil::calculateVelocity (convexFromTrans, convexToTrans, 1.0, linVel, angVel);
00628               btTransform R;
00629               R.setIdentity ();
00630               R.setRotation (convexFromTrans.getRotation());
00631               castShape->calculateTemporalAabb (R, linVel, angVel, 1.0, castShapeAabbMin, castShapeAabbMax);
00632        }
00633 
00635        // do a ray-shape query using convexCaster (CCD)
00636        int i;
00637        for (i=0;i<m_collisionObjects.size();i++)
00638        {
00639               btCollisionObject*   collisionObject= m_collisionObjects[i];
00640               //only perform raycast if filterMask matches
00641               if(collisionObject->getBroadphaseHandle()->m_collisionFilterGroup & collisionFilterMask) { 
00642                      //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
00643                      btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
00644                      collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
00645                      AabbExpand (collisionObjectAabbMin, collisionObjectAabbMax, castShapeAabbMin, castShapeAabbMax);
00646                      btScalar hitLambda = btScalar(1.); //could use resultCallback.m_closestHitFraction, but needs testing
00647                      btVector3 hitNormal;
00648                      if (btRayAabb(convexFromWorld.getOrigin(),convexToWorld.getOrigin(),collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,hitNormal))
00649                      {
00650                             objectQuerySingle(castShape, convexFromTrans,convexToTrans,
00651                                    collisionObject,
00652                                           collisionObject->getCollisionShape(),
00653                                           collisionObject->getWorldTransform(),
00654                                           resultCallback);
00655                      }      
00656               }
00657        }
00658 
00659 }