btConvexConvexAlgorithm.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 
00019 //define BT_DISABLE_CAPSULE_CAPSULE_COLLIDER 1
00020 
00021 #include "btConvexConvexAlgorithm.h"
00022 
00023 //#include <stdio.h>
00024 #include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
00025 #include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
00026 #include "BulletCollision/CollisionDispatch/btCollisionObject.h"
00027 #include "BulletCollision/CollisionShapes/btConvexShape.h"
00028 #include "BulletCollision/CollisionShapes/btCapsuleShape.h"
00029 
00030 
00031 #include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
00032 #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
00033 #include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
00034 #include "BulletCollision/CollisionShapes/btBoxShape.h"
00035 #include "BulletCollision/CollisionDispatch/btManifoldResult.h"
00036 
00037 #include "BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h"
00038 #include "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h"
00039 #include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
00040 #include "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h"
00041 
00042 
00043 
00044 #include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"
00045 #include "BulletCollision/CollisionShapes/btSphereShape.h"
00046 
00047 #include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h"
00048 
00049 #include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h"
00050 #include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
00051 
00052 
00053 
00055 
00056 
00057 
00058 static SIMD_FORCE_INLINE void segmentsClosestPoints(
00059         btVector3& ptsVector,
00060         btVector3& offsetA,
00061         btVector3& offsetB,
00062         btScalar& tA, btScalar& tB,
00063         const btVector3& translation,
00064         const btVector3& dirA, btScalar hlenA,
00065         const btVector3& dirB, btScalar hlenB )
00066 {
00067         // compute the parameters of the closest points on each line segment
00068 
00069         btScalar dirA_dot_dirB = btDot(dirA,dirB);
00070         btScalar dirA_dot_trans = btDot(dirA,translation);
00071         btScalar dirB_dot_trans = btDot(dirB,translation);
00072 
00073         btScalar denom = 1.0f - dirA_dot_dirB * dirA_dot_dirB;
00074 
00075         if ( denom == 0.0f ) {
00076                 tA = 0.0f;
00077         } else {
00078                 tA = ( dirA_dot_trans - dirB_dot_trans * dirA_dot_dirB ) / denom;
00079                 if ( tA < -hlenA )
00080                         tA = -hlenA;
00081                 else if ( tA > hlenA )
00082                         tA = hlenA;
00083         }
00084 
00085         tB = tA * dirA_dot_dirB - dirB_dot_trans;
00086 
00087         if ( tB < -hlenB ) {
00088                 tB = -hlenB;
00089                 tA = tB * dirA_dot_dirB + dirA_dot_trans;
00090 
00091                 if ( tA < -hlenA )
00092                         tA = -hlenA;
00093                 else if ( tA > hlenA )
00094                         tA = hlenA;
00095         } else if ( tB > hlenB ) {
00096                 tB = hlenB;
00097                 tA = tB * dirA_dot_dirB + dirA_dot_trans;
00098 
00099                 if ( tA < -hlenA )
00100                         tA = -hlenA;
00101                 else if ( tA > hlenA )
00102                         tA = hlenA;
00103         }
00104 
00105         // compute the closest points relative to segment centers.
00106 
00107         offsetA = dirA * tA;
00108         offsetB = dirB * tB;
00109 
00110         ptsVector = translation - offsetA + offsetB;
00111 }
00112 
00113 
00114 static SIMD_FORCE_INLINE btScalar capsuleCapsuleDistance(
00115         btVector3& normalOnB,
00116         btVector3& pointOnB,
00117         btScalar capsuleLengthA,
00118         btScalar        capsuleRadiusA,
00119         btScalar capsuleLengthB,
00120         btScalar        capsuleRadiusB,
00121         int capsuleAxisA,
00122         int capsuleAxisB,
00123         const btTransform& transformA,
00124         const btTransform& transformB,
00125         btScalar distanceThreshold )
00126 {
00127         btVector3 directionA = transformA.getBasis().getColumn(capsuleAxisA);
00128         btVector3 translationA = transformA.getOrigin();
00129         btVector3 directionB = transformB.getBasis().getColumn(capsuleAxisB);
00130         btVector3 translationB = transformB.getOrigin();
00131 
00132         // translation between centers
00133 
00134         btVector3 translation = translationB - translationA;
00135 
00136         // compute the closest points of the capsule line segments
00137 
00138         btVector3 ptsVector;           // the vector between the closest points
00139         
00140         btVector3 offsetA, offsetB;    // offsets from segment centers to their closest points
00141         btScalar tA, tB;              // parameters on line segment
00142 
00143         segmentsClosestPoints( ptsVector, offsetA, offsetB, tA, tB, translation,
00144                                                    directionA, capsuleLengthA, directionB, capsuleLengthB );
00145 
00146         btScalar distance = ptsVector.length() - capsuleRadiusA - capsuleRadiusB;
00147 
00148         if ( distance > distanceThreshold )
00149                 return distance;
00150 
00151         btScalar lenSqr = ptsVector.length2();
00152         if (lenSqr<= (SIMD_EPSILON*SIMD_EPSILON))
00153         {
00154                 //degenerate case where 2 capsules are likely at the same location: take a vector tangential to 'directionA'
00155                 btVector3 q;
00156                 btPlaneSpace1(directionA,normalOnB,q);
00157         } else
00158         {
00159                 // compute the contact normal
00160                 normalOnB = ptsVector*-btRecipSqrt(lenSqr);
00161         }
00162         pointOnB = transformB.getOrigin()+offsetB + normalOnB * capsuleRadiusB;
00163 
00164         return distance;
00165 }
00166 
00167 
00168 
00169 
00170 
00171 
00172 
00174 
00175 
00176 
00177 
00178 
00179 btConvexConvexAlgorithm::CreateFunc::CreateFunc(btSimplexSolverInterface*                       simplexSolver, btConvexPenetrationDepthSolver* pdSolver)
00180 {
00181         m_numPerturbationIterations = 0;
00182         m_minimumPointsPerturbationThreshold = 3;
00183         m_simplexSolver = simplexSolver;
00184         m_pdSolver = pdSolver;
00185 }
00186 
00187 btConvexConvexAlgorithm::CreateFunc::~CreateFunc() 
00188 { 
00189 }
00190 
00191 btConvexConvexAlgorithm::btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver,int numPerturbationIterations, int minimumPointsPerturbationThreshold)
00192 : btActivatingCollisionAlgorithm(ci,body0,body1),
00193 m_simplexSolver(simplexSolver),
00194 m_pdSolver(pdSolver),
00195 m_ownManifold (false),
00196 m_manifoldPtr(mf),
00197 m_lowLevelOfDetail(false),
00198 #ifdef USE_SEPDISTANCE_UTIL2
00199 m_sepDistance((static_cast<btConvexShape*>(body0->getCollisionShape()))->getAngularMotionDisc(),
00200                           (static_cast<btConvexShape*>(body1->getCollisionShape()))->getAngularMotionDisc()),
00201 #endif
00202 m_numPerturbationIterations(numPerturbationIterations),
00203 m_minimumPointsPerturbationThreshold(minimumPointsPerturbationThreshold)
00204 {
00205         (void)body0;
00206         (void)body1;
00207 }
00208 
00209 
00210 
00211 
00212 btConvexConvexAlgorithm::~btConvexConvexAlgorithm()
00213 {
00214         if (m_ownManifold)
00215         {
00216                 if (m_manifoldPtr)
00217                         m_dispatcher->releaseManifold(m_manifoldPtr);
00218         }
00219 }
00220 
00221 void    btConvexConvexAlgorithm ::setLowLevelOfDetail(bool useLowLevel)
00222 {
00223         m_lowLevelOfDetail = useLowLevel;
00224 }
00225 
00226 
00227 struct btPerturbedContactResult : public btManifoldResult
00228 {
00229         btManifoldResult* m_originalManifoldResult;
00230         btTransform m_transformA;
00231         btTransform m_transformB;
00232         btTransform     m_unPerturbedTransform;
00233         bool    m_perturbA;
00234         btIDebugDraw*   m_debugDrawer;
00235 
00236 
00237         btPerturbedContactResult(btManifoldResult* originalResult,const btTransform& transformA,const btTransform& transformB,const btTransform& unPerturbedTransform,bool perturbA,btIDebugDraw* debugDrawer)
00238                 :m_originalManifoldResult(originalResult),
00239                 m_transformA(transformA),
00240                 m_transformB(transformB),
00241                 m_unPerturbedTransform(unPerturbedTransform),
00242                 m_perturbA(perturbA),
00243                 m_debugDrawer(debugDrawer)
00244         {
00245         }
00246         virtual ~ btPerturbedContactResult()
00247         {
00248         }
00249 
00250         virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar orgDepth)
00251         {
00252                 btVector3 endPt,startPt;
00253                 btScalar newDepth;
00254                 btVector3 newNormal;
00255 
00256                 if (m_perturbA)
00257                 {
00258                         btVector3 endPtOrg = pointInWorld + normalOnBInWorld*orgDepth;
00259                         endPt = (m_unPerturbedTransform*m_transformA.inverse())(endPtOrg);
00260                         newDepth = (endPt -  pointInWorld).dot(normalOnBInWorld);
00261                         startPt = endPt+normalOnBInWorld*newDepth;
00262                 } else
00263                 {
00264                         endPt = pointInWorld + normalOnBInWorld*orgDepth;
00265                         startPt = (m_unPerturbedTransform*m_transformB.inverse())(pointInWorld);
00266                         newDepth = (endPt -  startPt).dot(normalOnBInWorld);
00267                         
00268                 }
00269 
00270 //#define DEBUG_CONTACTS 1
00271 #ifdef DEBUG_CONTACTS
00272                 m_debugDrawer->drawLine(startPt,endPt,btVector3(1,0,0));
00273                 m_debugDrawer->drawSphere(startPt,0.05,btVector3(0,1,0));
00274                 m_debugDrawer->drawSphere(endPt,0.05,btVector3(0,0,1));
00275 #endif //DEBUG_CONTACTS
00276 
00277                 
00278                 m_originalManifoldResult->addContactPoint(normalOnBInWorld,startPt,newDepth);
00279         }
00280 
00281 };
00282 
00283 extern btScalar gContactBreakingThreshold;
00284 
00285 
00286 //
00287 // Convex-Convex collision algorithm
00288 //
00289 void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
00290 {
00291 
00292         if (!m_manifoldPtr)
00293         {
00294                 //swapped?
00295                 m_manifoldPtr = m_dispatcher->getNewManifold(body0,body1);
00296                 m_ownManifold = true;
00297         }
00298         resultOut->setPersistentManifold(m_manifoldPtr);
00299 
00300         //comment-out next line to test multi-contact generation
00301         //resultOut->getPersistentManifold()->clearManifold();
00302         
00303 
00304         btConvexShape* min0 = static_cast<btConvexShape*>(body0->getCollisionShape());
00305         btConvexShape* min1 = static_cast<btConvexShape*>(body1->getCollisionShape());
00306 
00307         btVector3  normalOnB;
00308                 btVector3  pointOnBWorld;
00309 #ifndef BT_DISABLE_CAPSULE_CAPSULE_COLLIDER
00310         if ((min0->getShapeType() == CAPSULE_SHAPE_PROXYTYPE) && (min1->getShapeType() == CAPSULE_SHAPE_PROXYTYPE))
00311         {
00312                 btCapsuleShape* capsuleA = (btCapsuleShape*) min0;
00313                 btCapsuleShape* capsuleB = (btCapsuleShape*) min1;
00314                 btVector3 localScalingA = capsuleA->getLocalScaling();
00315                 btVector3 localScalingB = capsuleB->getLocalScaling();
00316                 
00317                 btScalar threshold = m_manifoldPtr->getContactBreakingThreshold();
00318 
00319                 btScalar dist = capsuleCapsuleDistance(normalOnB,       pointOnBWorld,capsuleA->getHalfHeight(),capsuleA->getRadius(),
00320                         capsuleB->getHalfHeight(),capsuleB->getRadius(),capsuleA->getUpAxis(),capsuleB->getUpAxis(),
00321                         body0->getWorldTransform(),body1->getWorldTransform(),threshold);
00322 
00323                 if (dist<threshold)
00324                 {
00325                         btAssert(normalOnB.length2()>=(SIMD_EPSILON*SIMD_EPSILON));
00326                         resultOut->addContactPoint(normalOnB,pointOnBWorld,dist);       
00327                 }
00328                 resultOut->refreshContactPoints();
00329                 return;
00330         }
00331 #endif //BT_DISABLE_CAPSULE_CAPSULE_COLLIDER
00332 
00333 
00334 #ifdef USE_SEPDISTANCE_UTIL2
00335         if (dispatchInfo.m_useConvexConservativeDistanceUtil)
00336         {
00337                 m_sepDistance.updateSeparatingDistance(body0->getWorldTransform(),body1->getWorldTransform());
00338         }
00339 
00340         if (!dispatchInfo.m_useConvexConservativeDistanceUtil || m_sepDistance.getConservativeSeparatingDistance()<=0.f)
00341 #endif //USE_SEPDISTANCE_UTIL2
00342 
00343         {
00344 
00345         
00346         btGjkPairDetector::ClosestPointInput input;
00347 
00348         btGjkPairDetector       gjkPairDetector(min0,min1,m_simplexSolver,m_pdSolver);
00349         //TODO: if (dispatchInfo.m_useContinuous)
00350         gjkPairDetector.setMinkowskiA(min0);
00351         gjkPairDetector.setMinkowskiB(min1);
00352 
00353 #ifdef USE_SEPDISTANCE_UTIL2
00354         if (dispatchInfo.m_useConvexConservativeDistanceUtil)
00355         {
00356                 input.m_maximumDistanceSquared = BT_LARGE_FLOAT;
00357         } else
00358 #endif //USE_SEPDISTANCE_UTIL2
00359         {
00360                 input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold();
00361                 input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared;
00362         }
00363 
00364         input.m_stackAlloc = dispatchInfo.m_stackAllocator;
00365         input.m_transformA = body0->getWorldTransform();
00366         input.m_transformB = body1->getWorldTransform();
00367 
00368         gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
00369 
00370         
00371 
00372 #ifdef USE_SEPDISTANCE_UTIL2
00373         btScalar sepDist = 0.f;
00374         if (dispatchInfo.m_useConvexConservativeDistanceUtil)
00375         {
00376                 sepDist = gjkPairDetector.getCachedSeparatingDistance();
00377                 if (sepDist>SIMD_EPSILON)
00378                 {
00379                         sepDist += dispatchInfo.m_convexConservativeDistanceThreshold;
00380                         //now perturbe directions to get multiple contact points
00381                         
00382                 }
00383         }
00384 #endif //USE_SEPDISTANCE_UTIL2
00385 
00386         //now perform 'm_numPerturbationIterations' collision queries with the perturbated collision objects
00387         
00388         //perform perturbation when more then 'm_minimumPointsPerturbationThreshold' points
00389         if (m_numPerturbationIterations && resultOut->getPersistentManifold()->getNumContacts() < m_minimumPointsPerturbationThreshold)
00390         {
00391                 
00392                 int i;
00393                 btVector3 v0,v1;
00394                 btVector3 sepNormalWorldSpace;
00395         
00396                 sepNormalWorldSpace = gjkPairDetector.getCachedSeparatingAxis().normalized();
00397                 btPlaneSpace1(sepNormalWorldSpace,v0,v1);
00398 
00399 
00400                 bool perturbeA = true;
00401                 const btScalar angleLimit = 0.125f * SIMD_PI;
00402                 btScalar perturbeAngle;
00403                 btScalar radiusA = min0->getAngularMotionDisc();
00404                 btScalar radiusB = min1->getAngularMotionDisc();
00405                 if (radiusA < radiusB)
00406                 {
00407                         perturbeAngle = gContactBreakingThreshold /radiusA;
00408                         perturbeA = true;
00409                 } else
00410                 {
00411                         perturbeAngle = gContactBreakingThreshold / radiusB;
00412                         perturbeA = false;
00413                 }
00414                 if ( perturbeAngle > angleLimit ) 
00415                                 perturbeAngle = angleLimit;
00416 
00417                 btTransform unPerturbedTransform;
00418                 if (perturbeA)
00419                 {
00420                         unPerturbedTransform = input.m_transformA;
00421                 } else
00422                 {
00423                         unPerturbedTransform = input.m_transformB;
00424                 }
00425                 
00426                 for ( i=0;i<m_numPerturbationIterations;i++)
00427                 {
00428                         if (v0.length2()>SIMD_EPSILON)
00429                         {
00430                         btQuaternion perturbeRot(v0,perturbeAngle);
00431                         btScalar iterationAngle = i*(SIMD_2_PI/btScalar(m_numPerturbationIterations));
00432                         btQuaternion rotq(sepNormalWorldSpace,iterationAngle);
00433                         
00434                         
00435                         if (perturbeA)
00436                         {
00437                                 input.m_transformA.setBasis(  btMatrix3x3(rotq.inverse()*perturbeRot*rotq)*body0->getWorldTransform().getBasis());
00438                                 input.m_transformB = body1->getWorldTransform();
00439 #ifdef DEBUG_CONTACTS
00440                                 dispatchInfo.m_debugDraw->drawTransform(input.m_transformA,10.0);
00441 #endif //DEBUG_CONTACTS
00442                         } else
00443                         {
00444                                 input.m_transformA = body0->getWorldTransform();
00445                                 input.m_transformB.setBasis( btMatrix3x3(rotq.inverse()*perturbeRot*rotq)*body1->getWorldTransform().getBasis());
00446 #ifdef DEBUG_CONTACTS
00447                                 dispatchInfo.m_debugDraw->drawTransform(input.m_transformB,10.0);
00448 #endif
00449                         }
00450                         
00451                         btPerturbedContactResult perturbedResultOut(resultOut,input.m_transformA,input.m_transformB,unPerturbedTransform,perturbeA,dispatchInfo.m_debugDraw);
00452                         gjkPairDetector.getClosestPoints(input,perturbedResultOut,dispatchInfo.m_debugDraw);
00453                         }
00454                         
00455                 }
00456         }
00457 
00458         
00459 
00460 #ifdef USE_SEPDISTANCE_UTIL2
00461         if (dispatchInfo.m_useConvexConservativeDistanceUtil && (sepDist>SIMD_EPSILON))
00462         {
00463                 m_sepDistance.initSeparatingDistance(gjkPairDetector.getCachedSeparatingAxis(),sepDist,body0->getWorldTransform(),body1->getWorldTransform());
00464         }
00465 #endif //USE_SEPDISTANCE_UTIL2
00466 
00467 
00468         }
00469 
00470         if (m_ownManifold)
00471         {
00472                 resultOut->refreshContactPoints();
00473         }
00474 
00475 }
00476 
00477 
00478 
00479 bool disableCcd = false;
00480 btScalar        btConvexConvexAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
00481 {
00482         (void)resultOut;
00483         (void)dispatchInfo;
00485     
00488         btScalar resultFraction = btScalar(1.);
00489 
00490 
00491         btScalar squareMot0 = (col0->getInterpolationWorldTransform().getOrigin() - col0->getWorldTransform().getOrigin()).length2();
00492         btScalar squareMot1 = (col1->getInterpolationWorldTransform().getOrigin() - col1->getWorldTransform().getOrigin()).length2();
00493     
00494         if (squareMot0 < col0->getCcdSquareMotionThreshold() &&
00495                 squareMot1 < col1->getCcdSquareMotionThreshold())
00496                 return resultFraction;
00497 
00498         if (disableCcd)
00499                 return btScalar(1.);
00500 
00501 
00502         //An adhoc way of testing the Continuous Collision Detection algorithms
00503         //One object is approximated as a sphere, to simplify things
00504         //Starting in penetration should report no time of impact
00505         //For proper CCD, better accuracy and handling of 'allowed' penetration should be added
00506         //also the mainloop of the physics should have a kind of toi queue (something like Brian Mirtich's application of Timewarp for Rigidbodies)
00507 
00508                 
00510         {
00511                 btConvexShape* convex0 = static_cast<btConvexShape*>(col0->getCollisionShape());
00512 
00513                 btSphereShape   sphere1(col1->getCcdSweptSphereRadius()); //todo: allow non-zero sphere sizes, for better approximation
00514                 btConvexCast::CastResult result;
00515                 btVoronoiSimplexSolver voronoiSimplex;
00516                 //SubsimplexConvexCast ccd0(&sphere,min0,&voronoiSimplex);
00518                 btGjkConvexCast ccd1( convex0 ,&sphere1,&voronoiSimplex);
00519                 //ContinuousConvexCollision ccd(min0,min1,&voronoiSimplex,0);
00520                 if (ccd1.calcTimeOfImpact(col0->getWorldTransform(),col0->getInterpolationWorldTransform(),
00521                         col1->getWorldTransform(),col1->getInterpolationWorldTransform(),result))
00522                 {
00523                 
00524                         //store result.m_fraction in both bodies
00525                 
00526                         if (col0->getHitFraction()> result.m_fraction)
00527                                 col0->setHitFraction( result.m_fraction );
00528 
00529                         if (col1->getHitFraction() > result.m_fraction)
00530                                 col1->setHitFraction( result.m_fraction);
00531 
00532                         if (resultFraction > result.m_fraction)
00533                                 resultFraction = result.m_fraction;
00534 
00535                 }
00536                 
00537                 
00538 
00539 
00540         }
00541 
00543         {
00544                 btConvexShape* convex1 = static_cast<btConvexShape*>(col1->getCollisionShape());
00545 
00546                 btSphereShape   sphere0(col0->getCcdSweptSphereRadius()); //todo: allow non-zero sphere sizes, for better approximation
00547                 btConvexCast::CastResult result;
00548                 btVoronoiSimplexSolver voronoiSimplex;
00549                 //SubsimplexConvexCast ccd0(&sphere,min0,&voronoiSimplex);
00551                 btGjkConvexCast ccd1(&sphere0,convex1,&voronoiSimplex);
00552                 //ContinuousConvexCollision ccd(min0,min1,&voronoiSimplex,0);
00553                 if (ccd1.calcTimeOfImpact(col0->getWorldTransform(),col0->getInterpolationWorldTransform(),
00554                         col1->getWorldTransform(),col1->getInterpolationWorldTransform(),result))
00555                 {
00556                 
00557                         //store result.m_fraction in both bodies
00558                 
00559                         if (col0->getHitFraction()      > result.m_fraction)
00560                                 col0->setHitFraction( result.m_fraction);
00561 
00562                         if (col1->getHitFraction() > result.m_fraction)
00563                                 col1->setHitFraction( result.m_fraction);
00564 
00565                         if (resultFraction > result.m_fraction)
00566                                 resultFraction = result.m_fraction;
00567 
00568                 }
00569         }
00570         
00571         return resultFraction;
00572 
00573 }
00574 

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