Back to index

supertuxkart  0.5+dfsg1
Public Member Functions | Private Attributes
btContinuousConvexCollision Class Reference

btContinuousConvexCollision implements angular and linear time of impact for convex objects. Based on Brian Mirtich's Conservative Advancement idea (PhD thesis). Algorithm operates in worldspace, in order to keep inbetween motion globally consistent. It uses GJK at the moment. Future improvement would use minkowski sum / supporting vertex, merging innerloops More...

#include <btContinuousConvexCollision.h>

Inheritance diagram for btContinuousConvexCollision:
Inheritance graph
[legend]
Collaboration diagram for btContinuousConvexCollision:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 btContinuousConvexCollision (const btConvexShape *shapeA, const btConvexShape *shapeB, btSimplexSolverInterface *simplexSolver, btConvexPenetrationDepthSolver *penetrationDepthSolver)
virtual bool calcTimeOfImpact (const btTransform &fromA, const btTransform &toA, const btTransform &fromB, const btTransform &toB, CastResult &result)
 cast a convex against another convex object

Private Attributes

btSimplexSolverInterfacem_simplexSolver
btConvexPenetrationDepthSolverm_penetrationDepthSolver
const btConvexShape * m_convexA
const btConvexShape * m_convexB

Detailed Description

btContinuousConvexCollision implements angular and linear time of impact for convex objects. Based on Brian Mirtich's Conservative Advancement idea (PhD thesis). Algorithm operates in worldspace, in order to keep inbetween motion globally consistent. It uses GJK at the moment. Future improvement would use minkowski sum / supporting vertex, merging innerloops

Definition at line 29 of file btContinuousConvexCollision.h.


Constructor & Destructor Documentation

btContinuousConvexCollision::btContinuousConvexCollision ( const btConvexShape *  shapeA,
const btConvexShape *  shapeB,
btSimplexSolverInterface simplexSolver,
btConvexPenetrationDepthSolver penetrationDepthSolver 
)

Definition at line 28 of file btContinuousConvexCollision.cpp.

:m_simplexSolver(simplexSolver),
m_penetrationDepthSolver(penetrationDepthSolver),
m_convexA(convexA),m_convexB(convexB)
{
}

Member Function Documentation

bool btContinuousConvexCollision::calcTimeOfImpact ( const btTransform fromA,
const btTransform toA,
const btTransform fromB,
const btTransform toB,
CastResult result 
) [virtual]

cast a convex against another convex object

compute linear and angular velocity for this interval, to interpolate

Implements btConvexCast.

Definition at line 39 of file btContinuousConvexCollision.cpp.

{

       m_simplexSolver->reset();

       btVector3 linVelA,angVelA,linVelB,angVelB;
       btTransformUtil::calculateVelocity(fromA,toA,btScalar(1.),linVelA,angVelA);
       btTransformUtil::calculateVelocity(fromB,toB,btScalar(1.),linVelB,angVelB);

       btScalar boundingRadiusA = m_convexA->getAngularMotionDisc();
       btScalar boundingRadiusB = m_convexB->getAngularMotionDisc();

       btScalar maxAngularProjectedVelocity = angVelA.length() * boundingRadiusA + angVelB.length() * boundingRadiusB;

       btScalar radius = btScalar(0.001);

       btScalar lambda = btScalar(0.);
       btVector3 v(1,0,0);

       int maxIter = MAX_ITERATIONS;

       btVector3 n;
       n.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
       bool hasResult = false;
       btVector3 c;

       btScalar lastLambda = lambda;
       //btScalar epsilon = btScalar(0.001);

       int numIter = 0;
       //first solution, using GJK


       btTransform identityTrans;
       identityTrans.setIdentity();

       btSphereShape raySphere(btScalar(0.0));
       raySphere.setMargin(btScalar(0.));


//     result.drawCoordSystem(sphereTr);

       btPointCollector     pointCollector1;

       {
              
              btGjkPairDetector gjk(m_convexA,m_convexB,m_simplexSolver,m_penetrationDepthSolver);              
              btGjkPairDetector::ClosestPointInput input;
       
              //we don't use margins during CCD
       //     gjk.setIgnoreMargin(true);

              input.m_transformA = fromA;
              input.m_transformB = fromB;
              gjk.getClosestPoints(input,pointCollector1,0);

              hasResult = pointCollector1.m_hasResult;
              c = pointCollector1.m_pointInWorld;
       }

       if (hasResult)
       {
              btScalar dist;
              dist = pointCollector1.m_distance;
              n = pointCollector1.m_normalOnBInWorld;

       

              //not close enough
              while (dist > radius)
              {
                     numIter++;
                     if (numIter > maxIter)
                     {
                            return false; //todo: report a failure
                     }
                     btScalar dLambda = btScalar(0.);

                            btScalar projectedLinearVelocity = (linVelB-linVelA).dot(n);

                     //calculate safe moving fraction from distance / (linear+rotational velocity)
                     
                     //btScalar clippedDist  = GEN_min(angularConservativeRadius,dist);
                     //btScalar clippedDist  = dist;
                     
                     
                     dLambda = dist / (projectedLinearVelocity+ maxAngularProjectedVelocity);

                     lambda = lambda + dLambda;

                     if (lambda > btScalar(1.))
                            return false;

                     if (lambda < btScalar(0.))
                            return false;


                     //todo: next check with relative epsilon
                     if (lambda <= lastLambda)
                     {
                            return false;
                            //n.setValue(0,0,0);
                            break;
                     }
                     lastLambda = lambda;

                     

                     //interpolate to next lambda
                     btTransform interpolatedTransA,interpolatedTransB,relativeTrans;

                     btTransformUtil::integrateTransform(fromA,linVelA,angVelA,lambda,interpolatedTransA);
                     btTransformUtil::integrateTransform(fromB,linVelB,angVelB,lambda,interpolatedTransB);
                     relativeTrans = interpolatedTransB.inverseTimes(interpolatedTransA);

                     result.DebugDraw( lambda );

                     btPointCollector     pointCollector;
                     btGjkPairDetector gjk(m_convexA,m_convexB,m_simplexSolver,m_penetrationDepthSolver);
                     btGjkPairDetector::ClosestPointInput input;
                     input.m_transformA = interpolatedTransA;
                     input.m_transformB = interpolatedTransB;
                     gjk.getClosestPoints(input,pointCollector,0);
                     if (pointCollector.m_hasResult)
                     {
                            if (pointCollector.m_distance < btScalar(0.))
                            {
                                   //degenerate ?!
                                   result.m_fraction = lastLambda;
                                   n = pointCollector.m_normalOnBInWorld;
                                   result.m_normal=n;//.setValue(1,1,1);// = n;
                                   result.m_hitPoint = pointCollector.m_pointInWorld;
                                   return true;
                            }
                            c = pointCollector.m_pointInWorld;        
                            n = pointCollector.m_normalOnBInWorld;
                            dist = pointCollector.m_distance;
                     } else
                     {
                            //??
                            return false;
                     }

              }

              result.m_fraction = lambda;
              result.m_normal = n;
              result.m_hitPoint = c;
              return true;
       }

       return false;

/*
//todo:
       //if movement away from normal, discard result
       btVector3 move = transBLocalTo.getOrigin() - transBLocalFrom.getOrigin();
       if (result.m_fraction < btScalar(1.))
       {
              if (move.dot(result.m_normal) <= btScalar(0.))
              {
              }
       }
*/

}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

const btConvexShape* btContinuousConvexCollision::m_convexA [private]

Definition at line 33 of file btContinuousConvexCollision.h.

const btConvexShape* btContinuousConvexCollision::m_convexB [private]

Definition at line 34 of file btContinuousConvexCollision.h.

Definition at line 32 of file btContinuousConvexCollision.h.

Definition at line 31 of file btContinuousConvexCollision.h.


The documentation for this class was generated from the following files: