Back to index

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