Blender V2.61 - r43446
|
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 }