Logo Search packages:      
Sourcecode: blender version File versions  Download package

void btCollisionWorld::rayTestSingle ( const btTransform rayFromTrans,
const btTransform rayToTrans,
btCollisionObject *  collisionObject,
const btCollisionShape collisionShape,
const btTransform colObjWorldTransform,
RayResultCallback resultCallback 
) [static, inherited]

rayTestSingle performs a raycast call and calls the resultCallback. It is used internally by rayTest. In a future implementation, we consider moving the ray test as a virtual method in btCollisionShape. This allows more customization.

optimized version for btBvhTriangleMeshShape

Todo:
: use AABB tree or other BVH acceleration structure, see btDbvt

Definition at line 227 of file btCollisionWorld.cpp.

References btCollisionWorld::RayResultCallback::addSingleResult(), btSubsimplexConvexCast::calcTimeOfImpact(), btTransform::getBasis(), btTransform::getOrigin(), btCollisionShape::getShapeType(), btTransform::inverse(), btCollisionShape::isCompound(), btCollisionShape::isConcave(), btCollisionShape::isConvex(), btCollisionWorld::RayResultCallback::m_closestHitFraction, btCollisionWorld::RayResultCallback::m_flags, btConvexCast::CastResult::m_fraction, btConvexCast::CastResult::m_normal, btCollisionWorld::LocalShapeInfo::m_shapePart, btCollisionWorld::LocalShapeInfo::m_triangleIndex, and btConcaveShape::processAllTriangles().

{
      btSphereShape pointShape(btScalar(0.0));
      pointShape.setMargin(0.f);
      const btConvexShape* castShape = &pointShape;

      if (collisionShape->isConvex())
      {
//          BT_PROFILE("rayTestConvex");
            btConvexCast::CastResult castResult;
            castResult.m_fraction = resultCallback.m_closestHitFraction;

            btConvexShape* convexShape = (btConvexShape*) collisionShape;
            btVoronoiSimplexSolver  simplexSolver;
#define USE_SUBSIMPLEX_CONVEX_CAST 1
#ifdef USE_SUBSIMPLEX_CONVEX_CAST
            btSubsimplexConvexCast convexCaster(castShape,convexShape,&simplexSolver);
#else
            //btGjkConvexCast convexCaster(castShape,convexShape,&simplexSolver);
            //btContinuousConvexCollision convexCaster(castShape,convexShape,&simplexSolver,0);
#endif //#USE_SUBSIMPLEX_CONVEX_CAST

            if (convexCaster.calcTimeOfImpact(rayFromTrans,rayToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
            {
                  //add hit
                  if (castResult.m_normal.length2() > btScalar(0.0001))
                  {
                        if (castResult.m_fraction < resultCallback.m_closestHitFraction)
                        {
#ifdef USE_SUBSIMPLEX_CONVEX_CAST
                              //rotate normal into worldspace
                              castResult.m_normal = rayFromTrans.getBasis() * castResult.m_normal;
#endif //USE_SUBSIMPLEX_CONVEX_CAST

                              castResult.m_normal.normalize();
                              btCollisionWorld::LocalRayResult localRayResult
                                    (
                                          collisionObject,
                                          0,
                                          castResult.m_normal,
                                          castResult.m_fraction
                                    );

                              bool normalInWorldSpace = true;
                              resultCallback.addSingleResult(localRayResult, normalInWorldSpace);

                        }
                  }
            }
      } else {
            if (collisionShape->isConcave())
            {
//                BT_PROFILE("rayTestConcave");
                  if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE)
                  {
                        ///optimized version for btBvhTriangleMeshShape
                        btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape;
                        btTransform worldTocollisionObject = colObjWorldTransform.inverse();
                        btVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin();
                        btVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin();

                        //ConvexCast::CastResult
                        struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback
                        {
                              btCollisionWorld::RayResultCallback* m_resultCallback;
                              btCollisionObject*      m_collisionObject;
                              btTriangleMeshShape*    m_triangleMesh;

                              BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,
                                    btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape*      triangleMesh):
                  //@BP Mod
                                    btTriangleRaycastCallback(from,to, resultCallback->m_flags),
                                          m_resultCallback(resultCallback),
                                          m_collisionObject(collisionObject),
                                          m_triangleMesh(triangleMesh)
                                    {
                                    }


                              virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex )
                              {
                                    btCollisionWorld::LocalShapeInfo    shapeInfo;
                                    shapeInfo.m_shapePart = partId;
                                    shapeInfo.m_triangleIndex = triangleIndex;

                                    btCollisionWorld::LocalRayResult rayResult
                                    (m_collisionObject,
                                          &shapeInfo,
                                          hitNormalLocal,
                                          hitFraction);

                                    bool  normalInWorldSpace = false;
                                    return m_resultCallback->addSingleResult(rayResult,normalInWorldSpace);
                              }

                        };

                        BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,triangleMesh);
                        rcb.m_hitFraction = resultCallback.m_closestHitFraction;
                        triangleMesh->performRaycast(&rcb,rayFromLocal,rayToLocal);
                  } else
                  {
                        //generic (slower) case
                        btConcaveShape* concaveShape = (btConcaveShape*)collisionShape;

                        btTransform worldTocollisionObject = colObjWorldTransform.inverse();

                        btVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin();
                        btVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin();

                        //ConvexCast::CastResult

                        struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback
                        {
                              btCollisionWorld::RayResultCallback* m_resultCallback;
                              btCollisionObject*      m_collisionObject;
                              btConcaveShape*   m_triangleMesh;

                              BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,
                                    btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btConcaveShape*     triangleMesh):
                  //@BP Mod
                  btTriangleRaycastCallback(from,to, resultCallback->m_flags),
                                          m_resultCallback(resultCallback),
                                          m_collisionObject(collisionObject),
                                          m_triangleMesh(triangleMesh)
                                    {
                                    }


                              virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex )
                              {
                                    btCollisionWorld::LocalShapeInfo    shapeInfo;
                                    shapeInfo.m_shapePart = partId;
                                    shapeInfo.m_triangleIndex = triangleIndex;

                                    btCollisionWorld::LocalRayResult rayResult
                                    (m_collisionObject,
                                          &shapeInfo,
                                          hitNormalLocal,
                                          hitFraction);

                                    bool  normalInWorldSpace = false;
                                    return m_resultCallback->addSingleResult(rayResult,normalInWorldSpace);


                              }

                        };


                        BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,concaveShape);
                        rcb.m_hitFraction = resultCallback.m_closestHitFraction;

                        btVector3 rayAabbMinLocal = rayFromLocal;
                        rayAabbMinLocal.setMin(rayToLocal);
                        btVector3 rayAabbMaxLocal = rayFromLocal;
                        rayAabbMaxLocal.setMax(rayToLocal);

                        concaveShape->processAllTriangles(&rcb,rayAabbMinLocal,rayAabbMaxLocal);
                  }
            } else {
//                BT_PROFILE("rayTestCompound");
                  ///@todo: use AABB tree or other BVH acceleration structure, see btDbvt
                  if (collisionShape->isCompound())
                  {
                        const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(collisionShape);
                        int i=0;
                        for (i=0;i<compoundShape->getNumChildShapes();i++)
                        {
                              btTransform childTrans = compoundShape->getChildTransform(i);
                              const btCollisionShape* childCollisionShape = compoundShape->getChildShape(i);
                              btTransform childWorldTrans = colObjWorldTransform * childTrans;
                              // replace collision shape so that callback can determine the triangle
                              btCollisionShape* saveCollisionShape = collisionObject->getCollisionShape();
                              collisionObject->internalSetTemporaryCollisionShape((btCollisionShape*)childCollisionShape);
                              rayTestSingle(rayFromTrans,rayToTrans,
                                    collisionObject,
                                    childCollisionShape,
                                    childWorldTrans,
                                    resultCallback);
                              // restore
                              collisionObject->internalSetTemporaryCollisionShape(saveCollisionShape);
                        }
                  }
            }
      }
}


Generated by  Doxygen 1.6.0   Back to index