btInternalEdgeUtility.cpp 29 KB

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