btInternalEdgeUtility.cpp 26 KB

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