Blender V2.61 - r43446

btRaycastCallback.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 <stdio.h>
00017 
00018 #include "BulletCollision/CollisionShapes/btConvexShape.h"
00019 #include "BulletCollision/CollisionShapes/btTriangleShape.h"
00020 #include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
00021 #include "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h"
00022 #include "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h"
00023 #include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
00024 #include "btRaycastCallback.h"
00025 
00026 btTriangleRaycastCallback::btTriangleRaycastCallback(const btVector3& from,const btVector3& to, unsigned int flags)
00027     :
00028     m_from(from),
00029     m_to(to),
00030    //@BP Mod
00031    m_flags(flags),
00032     m_hitFraction(btScalar(1.))
00033 {
00034 
00035 }
00036 
00037 
00038 
00039 void btTriangleRaycastCallback::processTriangle(btVector3* triangle,int partId, int triangleIndex)
00040 {
00041     const btVector3 &vert0=triangle[0];
00042     const btVector3 &vert1=triangle[1];
00043     const btVector3 &vert2=triangle[2];
00044 
00045     btVector3 v10; v10 = vert1 - vert0 ;
00046     btVector3 v20; v20 = vert2 - vert0 ;
00047 
00048     btVector3 triangleNormal; triangleNormal = v10.cross( v20 );
00049     
00050     const btScalar dist = vert0.dot(triangleNormal);
00051     btScalar dist_a = triangleNormal.dot(m_from) ;
00052     dist_a-= dist;
00053     btScalar dist_b = triangleNormal.dot(m_to);
00054     dist_b -= dist;
00055 
00056     if ( dist_a * dist_b >= btScalar(0.0) )
00057     {
00058         return ; // same sign
00059     }
00060    //@BP Mod - Backface filtering
00061    if (((m_flags & kF_FilterBackfaces) != 0) && (dist_a > btScalar(0.0)))
00062    {
00063       // Backface, skip check
00064       return;
00065    }
00066     
00067     const btScalar proj_length=dist_a-dist_b;
00068     const btScalar distance = (dist_a)/(proj_length);
00069     // Now we have the intersection point on the plane, we'll see if it's inside the triangle
00070     // Add an epsilon as a tolerance for the raycast,
00071     // in case the ray hits exacly on the edge of the triangle.
00072     // It must be scaled for the triangle size.
00073     
00074     if(distance < m_hitFraction)
00075     {
00076         
00077 
00078         btScalar edge_tolerance =triangleNormal.length2();      
00079         edge_tolerance *= btScalar(-0.0001);
00080         btVector3 point; point.setInterpolate3( m_from, m_to, distance);
00081         {
00082             btVector3 v0p; v0p = vert0 - point;
00083             btVector3 v1p; v1p = vert1 - point;
00084             btVector3 cp0; cp0 = v0p.cross( v1p );
00085 
00086             if ( (btScalar)(cp0.dot(triangleNormal)) >=edge_tolerance) 
00087             {
00088                         
00089 
00090                 btVector3 v2p; v2p = vert2 -  point;
00091                 btVector3 cp1;
00092                 cp1 = v1p.cross( v2p);
00093                 if ( (btScalar)(cp1.dot(triangleNormal)) >=edge_tolerance) 
00094                 {
00095                     btVector3 cp2;
00096                     cp2 = v2p.cross(v0p);
00097                     
00098                     if ( (btScalar)(cp2.dot(triangleNormal)) >=edge_tolerance) 
00099                     {
00100                   //@BP Mod
00101                   // Triangle normal isn't normalized
00102                       triangleNormal.normalize();
00103 
00104                   //@BP Mod - Allow for unflipped normal when raycasting against backfaces
00105                   if (((m_flags & kF_KeepUnflippedNormal) != 0) || (dist_a <= btScalar(0.0)))
00106                         {
00107                             m_hitFraction = reportHit(-triangleNormal,distance,partId,triangleIndex);
00108                         }
00109                         else
00110                         {
00111                      m_hitFraction = reportHit(triangleNormal,distance,partId,triangleIndex);
00112                         }
00113                     }
00114                 }
00115             }
00116         }
00117     }
00118 }
00119 
00120 
00121 btTriangleConvexcastCallback::btTriangleConvexcastCallback (const btConvexShape* convexShape, const btTransform& convexShapeFrom, const btTransform& convexShapeTo, const btTransform& triangleToWorld, const btScalar triangleCollisionMargin)
00122 {
00123     m_convexShape = convexShape;
00124     m_convexShapeFrom = convexShapeFrom;
00125     m_convexShapeTo = convexShapeTo;
00126     m_triangleToWorld = triangleToWorld;
00127     m_hitFraction = 1.0f;
00128     m_triangleCollisionMargin = triangleCollisionMargin;
00129     m_allowedPenetration = 0.f;
00130 }
00131 
00132 void
00133 btTriangleConvexcastCallback::processTriangle (btVector3* triangle, int partId, int triangleIndex)
00134 {
00135     btTriangleShape triangleShape (triangle[0], triangle[1], triangle[2]);
00136     triangleShape.setMargin(m_triangleCollisionMargin);
00137 
00138     btVoronoiSimplexSolver  simplexSolver;
00139     btGjkEpaPenetrationDepthSolver  gjkEpaPenetrationSolver;
00140 
00141 //#define  USE_SUBSIMPLEX_CONVEX_CAST 1
00142 //if you reenable USE_SUBSIMPLEX_CONVEX_CAST see commented out code below
00143 #ifdef USE_SUBSIMPLEX_CONVEX_CAST
00144     btSubsimplexConvexCast convexCaster(m_convexShape, &triangleShape, &simplexSolver);
00145 #else
00146     //btGjkConvexCast   convexCaster(m_convexShape,&triangleShape,&simplexSolver);
00147     btContinuousConvexCollision convexCaster(m_convexShape,&triangleShape,&simplexSolver,&gjkEpaPenetrationSolver);
00148 #endif //#USE_SUBSIMPLEX_CONVEX_CAST
00149     
00150     btConvexCast::CastResult castResult;
00151     castResult.m_fraction = btScalar(1.);
00152     castResult.m_allowedPenetration = m_allowedPenetration;
00153     if (convexCaster.calcTimeOfImpact(m_convexShapeFrom,m_convexShapeTo,m_triangleToWorld, m_triangleToWorld, castResult))
00154     {
00155         //add hit
00156         if (castResult.m_normal.length2() > btScalar(0.0001))
00157         {                   
00158             if (castResult.m_fraction < m_hitFraction)
00159             {
00160 /* btContinuousConvexCast's normal is already in world space */
00161 /*
00162 #ifdef USE_SUBSIMPLEX_CONVEX_CAST
00163                 //rotate normal into worldspace
00164                 castResult.m_normal = m_convexShapeFrom.getBasis() * castResult.m_normal;
00165 #endif //USE_SUBSIMPLEX_CONVEX_CAST
00166 */
00167                 castResult.m_normal.normalize();
00168 
00169                 reportHit (castResult.m_normal,
00170                             castResult.m_hitPoint,
00171                             castResult.m_fraction,
00172                             partId,
00173                             triangleIndex);
00174             }
00175         }
00176     }
00177 }