Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

843 rader
25 KiB

  1. #include "btInternalEdgeUtility.h"
  2. #include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h"
  3. #include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h"
  4. #include "BulletCollision/CollisionShapes/btTriangleShape.h"
  5. #include "BulletCollision/CollisionDispatch/btCollisionObject.h"
  6. #include "BulletCollision/NarrowPhaseCollision/btManifoldPoint.h"
  7. #include "LinearMath/btIDebugDraw.h"
  8. //#define DEBUG_INTERNAL_EDGE
  9. #ifdef DEBUG_INTERNAL_EDGE
  10. #include <stdio.h>
  11. #endif //DEBUG_INTERNAL_EDGE
  12. #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
  13. static btIDebugDraw* gDebugDrawer = 0;
  14. void btSetDebugDrawer(btIDebugDraw* debugDrawer)
  15. {
  16. gDebugDrawer = debugDrawer;
  17. }
  18. static void btDebugDrawLine(const btVector3& from,const btVector3& to, const btVector3& color)
  19. {
  20. if (gDebugDrawer)
  21. gDebugDrawer->drawLine(from,to,color);
  22. }
  23. #endif //BT_INTERNAL_EDGE_DEBUG_DRAW
  24. static int btGetHash(int partId, int triangleIndex)
  25. {
  26. int hash = (partId<<(31-MAX_NUM_PARTS_IN_BITS)) | triangleIndex;
  27. return hash;
  28. }
  29. static btScalar btGetAngle(const btVector3& edgeA, const btVector3& normalA,const btVector3& normalB)
  30. {
  31. const btVector3 refAxis0 = edgeA;
  32. const btVector3 refAxis1 = normalA;
  33. const btVector3 swingAxis = normalB;
  34. btScalar angle = btAtan2(swingAxis.dot(refAxis0), swingAxis.dot(refAxis1));
  35. return angle;
  36. }
  37. struct btConnectivityProcessor : public btTriangleCallback
  38. {
  39. int m_partIdA;
  40. int m_triangleIndexA;
  41. btVector3* m_triangleVerticesA;
  42. btTriangleInfoMap* m_triangleInfoMap;
  43. virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex)
  44. {
  45. //skip self-collisions
  46. if ((m_partIdA == partId) && (m_triangleIndexA == triangleIndex))
  47. return;
  48. //skip duplicates (disabled for now)
  49. //if ((m_partIdA <= partId) && (m_triangleIndexA <= triangleIndex))
  50. // return;
  51. //search for shared vertices and edges
  52. int numshared = 0;
  53. int sharedVertsA[3]={-1,-1,-1};
  54. int sharedVertsB[3]={-1,-1,-1};
  55. ///skip degenerate triangles
  56. btScalar crossBSqr = ((triangle[1]-triangle[0]).cross(triangle[2]-triangle[0])).length2();
  57. if (crossBSqr < m_triangleInfoMap->m_equalVertexThreshold)
  58. return;
  59. btScalar crossASqr = ((m_triangleVerticesA[1]-m_triangleVerticesA[0]).cross(m_triangleVerticesA[2]-m_triangleVerticesA[0])).length2();
  60. ///skip degenerate triangles
  61. if (crossASqr< m_triangleInfoMap->m_equalVertexThreshold)
  62. return;
  63. #if 0
  64. printf("triangle A[0] = (%f,%f,%f)\ntriangle A[1] = (%f,%f,%f)\ntriangle A[2] = (%f,%f,%f)\n",
  65. m_triangleVerticesA[0].getX(),m_triangleVerticesA[0].getY(),m_triangleVerticesA[0].getZ(),
  66. m_triangleVerticesA[1].getX(),m_triangleVerticesA[1].getY(),m_triangleVerticesA[1].getZ(),
  67. m_triangleVerticesA[2].getX(),m_triangleVerticesA[2].getY(),m_triangleVerticesA[2].getZ());
  68. printf("partId=%d, triangleIndex=%d\n",partId,triangleIndex);
  69. printf("triangle B[0] = (%f,%f,%f)\ntriangle B[1] = (%f,%f,%f)\ntriangle B[2] = (%f,%f,%f)\n",
  70. triangle[0].getX(),triangle[0].getY(),triangle[0].getZ(),
  71. triangle[1].getX(),triangle[1].getY(),triangle[1].getZ(),
  72. triangle[2].getX(),triangle[2].getY(),triangle[2].getZ());
  73. #endif
  74. for (int i=0;i<3;i++)
  75. {
  76. for (int j=0;j<3;j++)
  77. {
  78. if ( (m_triangleVerticesA[i]-triangle[j]).length2() < m_triangleInfoMap->m_equalVertexThreshold)
  79. {
  80. sharedVertsA[numshared] = i;
  81. sharedVertsB[numshared] = j;
  82. numshared++;
  83. ///degenerate case
  84. if(numshared >= 3)
  85. return;
  86. }
  87. }
  88. ///degenerate case
  89. if(numshared >= 3)
  90. return;
  91. }
  92. switch (numshared)
  93. {
  94. case 0:
  95. {
  96. break;
  97. }
  98. case 1:
  99. {
  100. //shared vertex
  101. break;
  102. }
  103. case 2:
  104. {
  105. //shared edge
  106. //we need to make sure the edge is in the order V2V0 and not V0V2 so that the signs are correct
  107. if (sharedVertsA[0] == 0 && sharedVertsA[1] == 2)
  108. {
  109. sharedVertsA[0] = 2;
  110. sharedVertsA[1] = 0;
  111. int tmp = sharedVertsB[1];
  112. sharedVertsB[1] = sharedVertsB[0];
  113. sharedVertsB[0] = tmp;
  114. }
  115. int hash = btGetHash(m_partIdA,m_triangleIndexA);
  116. btTriangleInfo* info = m_triangleInfoMap->find(hash);
  117. if (!info)
  118. {
  119. btTriangleInfo tmp;
  120. m_triangleInfoMap->insert(hash,tmp);
  121. info = m_triangleInfoMap->find(hash);
  122. }
  123. int sumvertsA = sharedVertsA[0]+sharedVertsA[1];
  124. int otherIndexA = 3-sumvertsA;
  125. btVector3 edge(m_triangleVerticesA[sharedVertsA[1]]-m_triangleVerticesA[sharedVertsA[0]]);
  126. btTriangleShape tA(m_triangleVerticesA[0],m_triangleVerticesA[1],m_triangleVerticesA[2]);
  127. int otherIndexB = 3-(sharedVertsB[0]+sharedVertsB[1]);
  128. btTriangleShape tB(triangle[sharedVertsB[1]],triangle[sharedVertsB[0]],triangle[otherIndexB]);
  129. //btTriangleShape tB(triangle[0],triangle[1],triangle[2]);
  130. btVector3 normalA;
  131. btVector3 normalB;
  132. tA.calcNormal(normalA);
  133. tB.calcNormal(normalB);
  134. edge.normalize();
  135. btVector3 edgeCrossA = edge.cross(normalA).normalize();
  136. {
  137. btVector3 tmp = m_triangleVerticesA[otherIndexA]-m_triangleVerticesA[sharedVertsA[0]];
  138. if (edgeCrossA.dot(tmp) < 0)
  139. {
  140. edgeCrossA*=-1;
  141. }
  142. }
  143. btVector3 edgeCrossB = edge.cross(normalB).normalize();
  144. {
  145. btVector3 tmp = triangle[otherIndexB]-triangle[sharedVertsB[0]];
  146. if (edgeCrossB.dot(tmp) < 0)
  147. {
  148. edgeCrossB*=-1;
  149. }
  150. }
  151. btScalar angle2 = 0;
  152. btScalar ang4 = 0.f;
  153. btVector3 calculatedEdge = edgeCrossA.cross(edgeCrossB);
  154. btScalar len2 = calculatedEdge.length2();
  155. btScalar correctedAngle(0);
  156. btVector3 calculatedNormalB = normalA;
  157. bool isConvex = false;
  158. if (len2<m_triangleInfoMap->m_planarEpsilon)
  159. {
  160. angle2 = 0.f;
  161. ang4 = 0.f;
  162. } else
  163. {
  164. calculatedEdge.normalize();
  165. btVector3 calculatedNormalA = calculatedEdge.cross(edgeCrossA);
  166. calculatedNormalA.normalize();
  167. angle2 = btGetAngle(calculatedNormalA,edgeCrossA,edgeCrossB);
  168. ang4 = SIMD_PI-angle2;
  169. btScalar dotA = normalA.dot(edgeCrossB);
  170. ///@todo: check if we need some epsilon, due to floating point imprecision
  171. isConvex = (dotA<0.);
  172. correctedAngle = isConvex ? ang4 : -ang4;
  173. btQuaternion orn2(calculatedEdge,-correctedAngle);
  174. calculatedNormalB = btMatrix3x3(orn2)*normalA;
  175. }
  176. //alternatively use
  177. //btVector3 calculatedNormalB2 = quatRotate(orn,normalA);
  178. switch (sumvertsA)
  179. {
  180. case 1:
  181. {
  182. btVector3 edge = m_triangleVerticesA[0]-m_triangleVerticesA[1];
  183. btQuaternion orn(edge,-correctedAngle);
  184. btVector3 computedNormalB = quatRotate(orn,normalA);
  185. btScalar bla = computedNormalB.dot(normalB);
  186. if (bla<0)
  187. {
  188. computedNormalB*=-1;
  189. info->m_flags |= TRI_INFO_V0V1_SWAP_NORMALB;
  190. }
  191. #ifdef DEBUG_INTERNAL_EDGE
  192. if ((computedNormalB-normalB).length()>0.0001)
  193. {
  194. printf("warning: normals not identical\n");
  195. }
  196. #endif//DEBUG_INTERNAL_EDGE
  197. info->m_edgeV0V1Angle = -correctedAngle;
  198. if (isConvex)
  199. info->m_flags |= TRI_INFO_V0V1_CONVEX;
  200. break;
  201. }
  202. case 2:
  203. {
  204. btVector3 edge = m_triangleVerticesA[2]-m_triangleVerticesA[0];
  205. btQuaternion orn(edge,-correctedAngle);
  206. btVector3 computedNormalB = quatRotate(orn,normalA);
  207. if (computedNormalB.dot(normalB)<0)
  208. {
  209. computedNormalB*=-1;
  210. info->m_flags |= TRI_INFO_V2V0_SWAP_NORMALB;
  211. }
  212. #ifdef DEBUG_INTERNAL_EDGE
  213. if ((computedNormalB-normalB).length()>0.0001)
  214. {
  215. printf("warning: normals not identical\n");
  216. }
  217. #endif //DEBUG_INTERNAL_EDGE
  218. info->m_edgeV2V0Angle = -correctedAngle;
  219. if (isConvex)
  220. info->m_flags |= TRI_INFO_V2V0_CONVEX;
  221. break;
  222. }
  223. case 3:
  224. {
  225. btVector3 edge = m_triangleVerticesA[1]-m_triangleVerticesA[2];
  226. btQuaternion orn(edge,-correctedAngle);
  227. btVector3 computedNormalB = quatRotate(orn,normalA);
  228. if (computedNormalB.dot(normalB)<0)
  229. {
  230. info->m_flags |= TRI_INFO_V1V2_SWAP_NORMALB;
  231. computedNormalB*=-1;
  232. }
  233. #ifdef DEBUG_INTERNAL_EDGE
  234. if ((computedNormalB-normalB).length()>0.0001)
  235. {
  236. printf("warning: normals not identical\n");
  237. }
  238. #endif //DEBUG_INTERNAL_EDGE
  239. info->m_edgeV1V2Angle = -correctedAngle;
  240. if (isConvex)
  241. info->m_flags |= TRI_INFO_V1V2_CONVEX;
  242. break;
  243. }
  244. }
  245. break;
  246. }
  247. default:
  248. {
  249. // printf("warning: duplicate triangle\n");
  250. }
  251. }
  252. }
  253. };
  254. /////////////////////////////////////////////////////////
  255. /////////////////////////////////////////////////////////
  256. void btGenerateInternalEdgeInfo (btBvhTriangleMeshShape*trimeshShape, btTriangleInfoMap* triangleInfoMap)
  257. {
  258. //the user pointer shouldn't already be used for other purposes, we intend to store connectivity info there!
  259. if (trimeshShape->getTriangleInfoMap())
  260. return;
  261. trimeshShape->setTriangleInfoMap(triangleInfoMap);
  262. btStridingMeshInterface* meshInterface = trimeshShape->getMeshInterface();
  263. const btVector3& meshScaling = meshInterface->getScaling();
  264. for (int partId = 0; partId< meshInterface->getNumSubParts();partId++)
  265. {
  266. const unsigned char *vertexbase = 0;
  267. int numverts = 0;
  268. PHY_ScalarType type = PHY_INTEGER;
  269. int stride = 0;
  270. const unsigned char *indexbase = 0;
  271. int indexstride = 0;
  272. int numfaces = 0;
  273. PHY_ScalarType indicestype = PHY_INTEGER;
  274. //PHY_ScalarType indexType=0;
  275. btVector3 triangleVerts[3];
  276. meshInterface->getLockedReadOnlyVertexIndexBase(&vertexbase,numverts, type,stride,&indexbase,indexstride,numfaces,indicestype,partId);
  277. btVector3 aabbMin,aabbMax;
  278. for (int triangleIndex = 0 ; triangleIndex < numfaces;triangleIndex++)
  279. {
  280. unsigned int* gfxbase = (unsigned int*)(indexbase+triangleIndex*indexstride);
  281. for (int j=2;j>=0;j--)
  282. {
  283. int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
  284. if (type == PHY_FLOAT)
  285. {
  286. float* graphicsbase = (float*)(vertexbase+graphicsindex*stride);
  287. triangleVerts[j] = btVector3(
  288. graphicsbase[0]*meshScaling.getX(),
  289. graphicsbase[1]*meshScaling.getY(),
  290. graphicsbase[2]*meshScaling.getZ());
  291. }
  292. else
  293. {
  294. double* graphicsbase = (double*)(vertexbase+graphicsindex*stride);
  295. triangleVerts[j] = btVector3( btScalar(graphicsbase[0]*meshScaling.getX()), btScalar(graphicsbase[1]*meshScaling.getY()), btScalar(graphicsbase[2]*meshScaling.getZ()));
  296. }
  297. }
  298. aabbMin.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
  299. aabbMax.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
  300. aabbMin.setMin(triangleVerts[0]);
  301. aabbMax.setMax(triangleVerts[0]);
  302. aabbMin.setMin(triangleVerts[1]);
  303. aabbMax.setMax(triangleVerts[1]);
  304. aabbMin.setMin(triangleVerts[2]);
  305. aabbMax.setMax(triangleVerts[2]);
  306. btConnectivityProcessor connectivityProcessor;
  307. connectivityProcessor.m_partIdA = partId;
  308. connectivityProcessor.m_triangleIndexA = triangleIndex;
  309. connectivityProcessor.m_triangleVerticesA = &triangleVerts[0];
  310. connectivityProcessor.m_triangleInfoMap = triangleInfoMap;
  311. trimeshShape->processAllTriangles(&connectivityProcessor,aabbMin,aabbMax);
  312. }
  313. }
  314. }
  315. // Given a point and a line segment (defined by two points), compute the closest point
  316. // in the line. Cap the point at the endpoints of the line segment.
  317. void btNearestPointInLineSegment(const btVector3 &point, const btVector3& line0, const btVector3& line1, btVector3& nearestPoint)
  318. {
  319. btVector3 lineDelta = line1 - line0;
  320. // Handle degenerate lines
  321. if ( lineDelta.fuzzyZero())
  322. {
  323. nearestPoint = line0;
  324. }
  325. else
  326. {
  327. btScalar delta = (point-line0).dot(lineDelta) / (lineDelta).dot(lineDelta);
  328. // Clamp the point to conform to the segment's endpoints
  329. if ( delta < 0 )
  330. delta = 0;
  331. else if ( delta > 1 )
  332. delta = 1;
  333. nearestPoint = line0 + lineDelta*delta;
  334. }
  335. }
  336. bool btClampNormal(const btVector3& edge,const btVector3& tri_normal_org,const btVector3& localContactNormalOnB, btScalar correctedEdgeAngle, btVector3 & clampedLocalNormal)
  337. {
  338. btVector3 tri_normal = tri_normal_org;
  339. //we only have a local triangle normal, not a local contact normal -> only normal in world space...
  340. //either compute the current angle all in local space, or all in world space
  341. btVector3 edgeCross = edge.cross(tri_normal).normalize();
  342. btScalar curAngle = btGetAngle(edgeCross,tri_normal,localContactNormalOnB);
  343. if (correctedEdgeAngle<0)
  344. {
  345. if (curAngle < correctedEdgeAngle)
  346. {
  347. btScalar diffAngle = correctedEdgeAngle-curAngle;
  348. btQuaternion rotation(edge,diffAngle );
  349. clampedLocalNormal = btMatrix3x3(rotation)*localContactNormalOnB;
  350. return true;
  351. }
  352. }
  353. if (correctedEdgeAngle>=0)
  354. {
  355. if (curAngle > correctedEdgeAngle)
  356. {
  357. btScalar diffAngle = correctedEdgeAngle-curAngle;
  358. btQuaternion rotation(edge,diffAngle );
  359. clampedLocalNormal = btMatrix3x3(rotation)*localContactNormalOnB;
  360. return true;
  361. }
  362. }
  363. return false;
  364. }
  365. /// Changes a btManifoldPoint collision normal to the normal from the mesh.
  366. void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject* colObj0,const btCollisionObject* colObj1, int partId0, int index0, int normalAdjustFlags)
  367. {
  368. //btAssert(colObj0->getCollisionShape()->getShapeType() == TRIANGLE_SHAPE_PROXYTYPE);
  369. if (colObj0->getCollisionShape()->getShapeType() != TRIANGLE_SHAPE_PROXYTYPE)
  370. return;
  371. btBvhTriangleMeshShape* trimesh = 0;
  372. if( colObj0->getRootCollisionShape()->getShapeType() == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE )
  373. trimesh = ((btScaledBvhTriangleMeshShape*)colObj0->getRootCollisionShape())->getChildShape();
  374. else
  375. trimesh = (btBvhTriangleMeshShape*)colObj0->getRootCollisionShape();
  376. btTriangleInfoMap* triangleInfoMapPtr = (btTriangleInfoMap*) trimesh->getTriangleInfoMap();
  377. if (!triangleInfoMapPtr)
  378. return;
  379. int hash = btGetHash(partId0,index0);
  380. btTriangleInfo* info = triangleInfoMapPtr->find(hash);
  381. if (!info)
  382. return;
  383. btScalar frontFacing = (normalAdjustFlags & BT_TRIANGLE_CONVEX_BACKFACE_MODE)==0? 1.f : -1.f;
  384. const btTriangleShape* tri_shape = static_cast<const btTriangleShape*>(colObj0->getCollisionShape());
  385. btVector3 v0,v1,v2;
  386. tri_shape->getVertex(0,v0);
  387. tri_shape->getVertex(1,v1);
  388. tri_shape->getVertex(2,v2);
  389. btVector3 center = (v0+v1+v2)*btScalar(1./3.);
  390. btVector3 red(1,0,0), green(0,1,0),blue(0,0,1),white(1,1,1),black(0,0,0);
  391. btVector3 tri_normal;
  392. tri_shape->calcNormal(tri_normal);
  393. //btScalar dot = tri_normal.dot(cp.m_normalWorldOnB);
  394. btVector3 nearest;
  395. btNearestPointInLineSegment(cp.m_localPointB,v0,v1,nearest);
  396. btVector3 contact = cp.m_localPointB;
  397. #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
  398. const btTransform& tr = colObj0->getWorldTransform();
  399. btDebugDrawLine(tr*nearest,tr*cp.m_localPointB,red);
  400. #endif //BT_INTERNAL_EDGE_DEBUG_DRAW
  401. bool isNearEdge = false;
  402. int numConcaveEdgeHits = 0;
  403. int numConvexEdgeHits = 0;
  404. btVector3 localContactNormalOnB = colObj0->getWorldTransform().getBasis().transpose() * cp.m_normalWorldOnB;
  405. localContactNormalOnB.normalize();//is this necessary?
  406. // Get closest edge
  407. int bestedge=-1;
  408. btScalar disttobestedge=BT_LARGE_FLOAT;
  409. //
  410. // Edge 0 -> 1
  411. if (btFabs(info->m_edgeV0V1Angle)< triangleInfoMapPtr->m_maxEdgeAngleThreshold)
  412. {
  413. btVector3 nearest;
  414. btNearestPointInLineSegment( cp.m_localPointB, v0, v1, nearest );
  415. btScalar len=(contact-nearest).length();
  416. //
  417. if( len < disttobestedge )
  418. {
  419. bestedge=0;
  420. disttobestedge=len;
  421. }
  422. }
  423. // Edge 1 -> 2
  424. if (btFabs(info->m_edgeV1V2Angle)< triangleInfoMapPtr->m_maxEdgeAngleThreshold)
  425. {
  426. btVector3 nearest;
  427. btNearestPointInLineSegment( cp.m_localPointB, v1, v2, nearest );
  428. btScalar len=(contact-nearest).length();
  429. //
  430. if( len < disttobestedge )
  431. {
  432. bestedge=1;
  433. disttobestedge=len;
  434. }
  435. }
  436. // Edge 2 -> 0
  437. if (btFabs(info->m_edgeV2V0Angle)< triangleInfoMapPtr->m_maxEdgeAngleThreshold)
  438. {
  439. btVector3 nearest;
  440. btNearestPointInLineSegment( cp.m_localPointB, v2, v0, nearest );
  441. btScalar len=(contact-nearest).length();
  442. //
  443. if( len < disttobestedge )
  444. {
  445. bestedge=2;
  446. disttobestedge=len;
  447. }
  448. }
  449. #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
  450. btVector3 upfix=tri_normal * btVector3(0.1f,0.1f,0.1f);
  451. btDebugDrawLine(tr * v0 + upfix, tr * v1 + upfix, red );
  452. #endif
  453. if (btFabs(info->m_edgeV0V1Angle)< triangleInfoMapPtr->m_maxEdgeAngleThreshold)
  454. {
  455. #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
  456. btDebugDrawLine(tr*contact,tr*(contact+cp.m_normalWorldOnB*10),black);
  457. #endif
  458. btScalar len = (contact-nearest).length();
  459. if(len<triangleInfoMapPtr->m_edgeDistanceThreshold)
  460. if( bestedge==0 )
  461. {
  462. btVector3 edge(v0-v1);
  463. isNearEdge = true;
  464. if (info->m_edgeV0V1Angle==btScalar(0))
  465. {
  466. numConcaveEdgeHits++;
  467. } else
  468. {
  469. bool isEdgeConvex = (info->m_flags & TRI_INFO_V0V1_CONVEX);
  470. btScalar swapFactor = isEdgeConvex ? btScalar(1) : btScalar(-1);
  471. #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
  472. btDebugDrawLine(tr*nearest,tr*(nearest+swapFactor*tri_normal*10),white);
  473. #endif //BT_INTERNAL_EDGE_DEBUG_DRAW
  474. btVector3 nA = swapFactor * tri_normal;
  475. btQuaternion orn(edge,info->m_edgeV0V1Angle);
  476. btVector3 computedNormalB = quatRotate(orn,tri_normal);
  477. if (info->m_flags & TRI_INFO_V0V1_SWAP_NORMALB)
  478. computedNormalB*=-1;
  479. btVector3 nB = swapFactor*computedNormalB;
  480. btScalar NdotA = localContactNormalOnB.dot(nA);
  481. btScalar NdotB = localContactNormalOnB.dot(nB);
  482. bool backFacingNormal = (NdotA< triangleInfoMapPtr->m_convexEpsilon) && (NdotB<triangleInfoMapPtr->m_convexEpsilon);
  483. #ifdef DEBUG_INTERNAL_EDGE
  484. {
  485. btDebugDrawLine(cp.getPositionWorldOnB(),cp.getPositionWorldOnB()+tr.getBasis()*(nB*20),red);
  486. }
  487. #endif //DEBUG_INTERNAL_EDGE
  488. if (backFacingNormal)
  489. {
  490. numConcaveEdgeHits++;
  491. }
  492. else
  493. {
  494. numConvexEdgeHits++;
  495. btVector3 clampedLocalNormal;
  496. bool isClamped = btClampNormal(edge,swapFactor*tri_normal,localContactNormalOnB, info->m_edgeV0V1Angle,clampedLocalNormal);
  497. if (isClamped)
  498. {
  499. if (((normalAdjustFlags & BT_TRIANGLE_CONVEX_DOUBLE_SIDED)!=0) || (clampedLocalNormal.dot(frontFacing*tri_normal)>0))
  500. {
  501. btVector3 newNormal = colObj0->getWorldTransform().getBasis() * clampedLocalNormal;
  502. // cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB);
  503. cp.m_normalWorldOnB = newNormal;
  504. // Reproject collision point along normal. (what about cp.m_distance1?)
  505. cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1;
  506. cp.m_localPointB = colObj0->getWorldTransform().invXform(cp.m_positionWorldOnB);
  507. }
  508. }
  509. }
  510. }
  511. }
  512. }
  513. btNearestPointInLineSegment(contact,v1,v2,nearest);
  514. #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
  515. btDebugDrawLine(tr*nearest,tr*cp.m_localPointB,green);
  516. #endif //BT_INTERNAL_EDGE_DEBUG_DRAW
  517. #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
  518. btDebugDrawLine(tr * v1 + upfix, tr * v2 + upfix , green );
  519. #endif
  520. if (btFabs(info->m_edgeV1V2Angle)< triangleInfoMapPtr->m_maxEdgeAngleThreshold)
  521. {
  522. #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
  523. btDebugDrawLine(tr*contact,tr*(contact+cp.m_normalWorldOnB*10),black);
  524. #endif //BT_INTERNAL_EDGE_DEBUG_DRAW
  525. btScalar len = (contact-nearest).length();
  526. if(len<triangleInfoMapPtr->m_edgeDistanceThreshold)
  527. if( bestedge==1 )
  528. {
  529. isNearEdge = true;
  530. #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
  531. btDebugDrawLine(tr*nearest,tr*(nearest+tri_normal*10),white);
  532. #endif //BT_INTERNAL_EDGE_DEBUG_DRAW
  533. btVector3 edge(v1-v2);
  534. isNearEdge = true;
  535. if (info->m_edgeV1V2Angle == btScalar(0))
  536. {
  537. numConcaveEdgeHits++;
  538. } else
  539. {
  540. bool isEdgeConvex = (info->m_flags & TRI_INFO_V1V2_CONVEX)!=0;
  541. btScalar swapFactor = isEdgeConvex ? btScalar(1) : btScalar(-1);
  542. #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
  543. btDebugDrawLine(tr*nearest,tr*(nearest+swapFactor*tri_normal*10),white);
  544. #endif //BT_INTERNAL_EDGE_DEBUG_DRAW
  545. btVector3 nA = swapFactor * tri_normal;
  546. btQuaternion orn(edge,info->m_edgeV1V2Angle);
  547. btVector3 computedNormalB = quatRotate(orn,tri_normal);
  548. if (info->m_flags & TRI_INFO_V1V2_SWAP_NORMALB)
  549. computedNormalB*=-1;
  550. btVector3 nB = swapFactor*computedNormalB;
  551. #ifdef DEBUG_INTERNAL_EDGE
  552. {
  553. btDebugDrawLine(cp.getPositionWorldOnB(),cp.getPositionWorldOnB()+tr.getBasis()*(nB*20),red);
  554. }
  555. #endif //DEBUG_INTERNAL_EDGE
  556. btScalar NdotA = localContactNormalOnB.dot(nA);
  557. btScalar NdotB = localContactNormalOnB.dot(nB);
  558. bool backFacingNormal = (NdotA< triangleInfoMapPtr->m_convexEpsilon) && (NdotB<triangleInfoMapPtr->m_convexEpsilon);
  559. if (backFacingNormal)
  560. {
  561. numConcaveEdgeHits++;
  562. }
  563. else
  564. {
  565. numConvexEdgeHits++;
  566. btVector3 localContactNormalOnB = colObj0->getWorldTransform().getBasis().transpose() * cp.m_normalWorldOnB;
  567. btVector3 clampedLocalNormal;
  568. bool isClamped = btClampNormal(edge,swapFactor*tri_normal,localContactNormalOnB, info->m_edgeV1V2Angle,clampedLocalNormal);
  569. if (isClamped)
  570. {
  571. if (((normalAdjustFlags & BT_TRIANGLE_CONVEX_DOUBLE_SIDED)!=0) || (clampedLocalNormal.dot(frontFacing*tri_normal)>0))
  572. {
  573. btVector3 newNormal = colObj0->getWorldTransform().getBasis() * clampedLocalNormal;
  574. // cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB);
  575. cp.m_normalWorldOnB = newNormal;
  576. // Reproject collision point along normal.
  577. cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1;
  578. cp.m_localPointB = colObj0->getWorldTransform().invXform(cp.m_positionWorldOnB);
  579. }
  580. }
  581. }
  582. }
  583. }
  584. }
  585. btNearestPointInLineSegment(contact,v2,v0,nearest);
  586. #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
  587. btDebugDrawLine(tr*nearest,tr*cp.m_localPointB,blue);
  588. #endif //BT_INTERNAL_EDGE_DEBUG_DRAW
  589. #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
  590. btDebugDrawLine(tr * v2 + upfix, tr * v0 + upfix , blue );
  591. #endif
  592. if (btFabs(info->m_edgeV2V0Angle)< triangleInfoMapPtr->m_maxEdgeAngleThreshold)
  593. {
  594. #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
  595. btDebugDrawLine(tr*contact,tr*(contact+cp.m_normalWorldOnB*10),black);
  596. #endif //BT_INTERNAL_EDGE_DEBUG_DRAW
  597. btScalar len = (contact-nearest).length();
  598. if(len<triangleInfoMapPtr->m_edgeDistanceThreshold)
  599. if( bestedge==2 )
  600. {
  601. isNearEdge = true;
  602. #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
  603. btDebugDrawLine(tr*nearest,tr*(nearest+tri_normal*10),white);
  604. #endif //BT_INTERNAL_EDGE_DEBUG_DRAW
  605. btVector3 edge(v2-v0);
  606. if (info->m_edgeV2V0Angle==btScalar(0))
  607. {
  608. numConcaveEdgeHits++;
  609. } else
  610. {
  611. bool isEdgeConvex = (info->m_flags & TRI_INFO_V2V0_CONVEX)!=0;
  612. btScalar swapFactor = isEdgeConvex ? btScalar(1) : btScalar(-1);
  613. #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
  614. btDebugDrawLine(tr*nearest,tr*(nearest+swapFactor*tri_normal*10),white);
  615. #endif //BT_INTERNAL_EDGE_DEBUG_DRAW
  616. btVector3 nA = swapFactor * tri_normal;
  617. btQuaternion orn(edge,info->m_edgeV2V0Angle);
  618. btVector3 computedNormalB = quatRotate(orn,tri_normal);
  619. if (info->m_flags & TRI_INFO_V2V0_SWAP_NORMALB)
  620. computedNormalB*=-1;
  621. btVector3 nB = swapFactor*computedNormalB;
  622. #ifdef DEBUG_INTERNAL_EDGE
  623. {
  624. btDebugDrawLine(cp.getPositionWorldOnB(),cp.getPositionWorldOnB()+tr.getBasis()*(nB*20),red);
  625. }
  626. #endif //DEBUG_INTERNAL_EDGE
  627. btScalar NdotA = localContactNormalOnB.dot(nA);
  628. btScalar NdotB = localContactNormalOnB.dot(nB);
  629. bool backFacingNormal = (NdotA< triangleInfoMapPtr->m_convexEpsilon) && (NdotB<triangleInfoMapPtr->m_convexEpsilon);
  630. if (backFacingNormal)
  631. {
  632. numConcaveEdgeHits++;
  633. }
  634. else
  635. {
  636. numConvexEdgeHits++;
  637. // printf("hitting convex edge\n");
  638. btVector3 localContactNormalOnB = colObj0->getWorldTransform().getBasis().transpose() * cp.m_normalWorldOnB;
  639. btVector3 clampedLocalNormal;
  640. bool isClamped = btClampNormal(edge,swapFactor*tri_normal,localContactNormalOnB,info->m_edgeV2V0Angle,clampedLocalNormal);
  641. if (isClamped)
  642. {
  643. if (((normalAdjustFlags & BT_TRIANGLE_CONVEX_DOUBLE_SIDED)!=0) || (clampedLocalNormal.dot(frontFacing*tri_normal)>0))
  644. {
  645. btVector3 newNormal = colObj0->getWorldTransform().getBasis() * clampedLocalNormal;
  646. // cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB);
  647. cp.m_normalWorldOnB = newNormal;
  648. // Reproject collision point along normal.
  649. cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1;
  650. cp.m_localPointB = colObj0->getWorldTransform().invXform(cp.m_positionWorldOnB);
  651. }
  652. }
  653. }
  654. }
  655. }
  656. }
  657. #ifdef DEBUG_INTERNAL_EDGE
  658. {
  659. btVector3 color(0,1,1);
  660. btDebugDrawLine(cp.getPositionWorldOnB(),cp.getPositionWorldOnB()+cp.m_normalWorldOnB*10,color);
  661. }
  662. #endif //DEBUG_INTERNAL_EDGE
  663. if (isNearEdge)
  664. {
  665. if (numConcaveEdgeHits>0)
  666. {
  667. if ((normalAdjustFlags & BT_TRIANGLE_CONCAVE_DOUBLE_SIDED)!=0)
  668. {
  669. //fix tri_normal so it pointing the same direction as the current local contact normal
  670. if (tri_normal.dot(localContactNormalOnB) < 0)
  671. {
  672. tri_normal *= -1;
  673. }
  674. cp.m_normalWorldOnB = colObj0->getWorldTransform().getBasis()*tri_normal;
  675. } else
  676. {
  677. btVector3 newNormal = tri_normal *frontFacing;
  678. //if the tri_normal is pointing opposite direction as the current local contact normal, skip it
  679. btScalar d = newNormal.dot(localContactNormalOnB) ;
  680. if (d< 0)
  681. {
  682. return;
  683. }
  684. //modify the normal to be the triangle normal (or backfacing normal)
  685. cp.m_normalWorldOnB = colObj0->getWorldTransform().getBasis() *newNormal;
  686. }
  687. // Reproject collision point along normal.
  688. cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1;
  689. cp.m_localPointB = colObj0->getWorldTransform().invXform(cp.m_positionWorldOnB);
  690. }
  691. }
  692. }