Bullet Collision Detection & Physics Library
btInternalEdgeUtility.cpp
Go to the documentation of this file.
2 
5 
12 
13 //#define DEBUG_INTERNAL_EDGE
14 
15 #ifdef DEBUG_INTERNAL_EDGE
16 #include <stdio.h>
17 #endif //DEBUG_INTERNAL_EDGE
18 
19 #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
20 static btIDebugDraw* gDebugDrawer = 0;
21 
22 void btSetDebugDrawer(btIDebugDraw* debugDrawer)
23 {
24  gDebugDrawer = debugDrawer;
25 }
26 
27 static void btDebugDrawLine(const btVector3& from, const btVector3& to, const btVector3& color)
28 {
29  if (gDebugDrawer)
30  gDebugDrawer->drawLine(from, to, color);
31 }
32 #endif //BT_INTERNAL_EDGE_DEBUG_DRAW
33 
34 static int btGetHash(int partId, int triangleIndex)
35 {
36  int hash = (partId << (31 - MAX_NUM_PARTS_IN_BITS)) | triangleIndex;
37  return hash;
38 }
39 
40 static btScalar btGetAngle(const btVector3& edgeA, const btVector3& normalA, const btVector3& normalB)
41 {
42  const btVector3 refAxis0 = edgeA;
43  const btVector3 refAxis1 = normalA;
44  const btVector3 swingAxis = normalB;
45  btScalar angle = btAtan2(swingAxis.dot(refAxis0), swingAxis.dot(refAxis1));
46  return angle;
47 }
48 
50 {
51  int m_partIdA;
55 
56  virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex)
57  {
58  //skip self-collisions
59  if ((m_partIdA == partId) && (m_triangleIndexA == triangleIndex))
60  return;
61 
62  //skip duplicates (disabled for now)
63  //if ((m_partIdA <= partId) && (m_triangleIndexA <= triangleIndex))
64  // return;
65 
66  //search for shared vertices and edges
67  int numshared = 0;
68  int sharedVertsA[3] = {-1, -1, -1};
69  int sharedVertsB[3] = {-1, -1, -1};
70 
72  btScalar crossBSqr = ((triangle[1] - triangle[0]).cross(triangle[2] - triangle[0])).length2();
73  if (crossBSqr < m_triangleInfoMap->m_equalVertexThreshold)
74  return;
75 
76  btScalar crossASqr = ((m_triangleVerticesA[1] - m_triangleVerticesA[0]).cross(m_triangleVerticesA[2] - m_triangleVerticesA[0])).length2();
78  if (crossASqr < m_triangleInfoMap->m_equalVertexThreshold)
79  return;
80 
81 #if 0
82  printf("triangle A[0] = (%f,%f,%f)\ntriangle A[1] = (%f,%f,%f)\ntriangle A[2] = (%f,%f,%f)\n",
83  m_triangleVerticesA[0].getX(),m_triangleVerticesA[0].getY(),m_triangleVerticesA[0].getZ(),
84  m_triangleVerticesA[1].getX(),m_triangleVerticesA[1].getY(),m_triangleVerticesA[1].getZ(),
85  m_triangleVerticesA[2].getX(),m_triangleVerticesA[2].getY(),m_triangleVerticesA[2].getZ());
86 
87  printf("partId=%d, triangleIndex=%d\n",partId,triangleIndex);
88  printf("triangle B[0] = (%f,%f,%f)\ntriangle B[1] = (%f,%f,%f)\ntriangle B[2] = (%f,%f,%f)\n",
89  triangle[0].getX(),triangle[0].getY(),triangle[0].getZ(),
90  triangle[1].getX(),triangle[1].getY(),triangle[1].getZ(),
91  triangle[2].getX(),triangle[2].getY(),triangle[2].getZ());
92 #endif
93 
94  for (int i = 0; i < 3; i++)
95  {
96  for (int j = 0; j < 3; j++)
97  {
98  if ((m_triangleVerticesA[i] - triangle[j]).length2() < m_triangleInfoMap->m_equalVertexThreshold)
99  {
100  sharedVertsA[numshared] = i;
101  sharedVertsB[numshared] = j;
102  numshared++;
104  if (numshared >= 3)
105  return;
106  }
107  }
109  if (numshared >= 3)
110  return;
111  }
112  switch (numshared)
113  {
114  case 0:
115  {
116  break;
117  }
118  case 1:
119  {
120  //shared vertex
121  break;
122  }
123  case 2:
124  {
125  //shared edge
126  //we need to make sure the edge is in the order V2V0 and not V0V2 so that the signs are correct
127  if (sharedVertsA[0] == 0 && sharedVertsA[1] == 2)
128  {
129  sharedVertsA[0] = 2;
130  sharedVertsA[1] = 0;
131  int tmp = sharedVertsB[1];
132  sharedVertsB[1] = sharedVertsB[0];
133  sharedVertsB[0] = tmp;
134  }
135 
136  int hash = btGetHash(m_partIdA, m_triangleIndexA);
137 
138  btTriangleInfo* info = m_triangleInfoMap->find(hash);
139  if (!info)
140  {
141  btTriangleInfo tmp;
142  m_triangleInfoMap->insert(hash, tmp);
143  info = m_triangleInfoMap->find(hash);
144  }
145 
146  int sumvertsA = sharedVertsA[0] + sharedVertsA[1];
147  int otherIndexA = 3 - sumvertsA;
148 
149  btVector3 edge(m_triangleVerticesA[sharedVertsA[1]] - m_triangleVerticesA[sharedVertsA[0]]);
150 
152  int otherIndexB = 3 - (sharedVertsB[0] + sharedVertsB[1]);
153 
154  btTriangleShape tB(triangle[sharedVertsB[1]], triangle[sharedVertsB[0]], triangle[otherIndexB]);
155  //btTriangleShape tB(triangle[0],triangle[1],triangle[2]);
156 
157  btVector3 normalA;
158  btVector3 normalB;
159  tA.calcNormal(normalA);
160  tB.calcNormal(normalB);
161  edge.normalize();
162  btVector3 edgeCrossA = edge.cross(normalA).normalize();
163 
164  {
165  btVector3 tmp = m_triangleVerticesA[otherIndexA] - m_triangleVerticesA[sharedVertsA[0]];
166  if (edgeCrossA.dot(tmp) < 0)
167  {
168  edgeCrossA *= -1;
169  }
170  }
171 
172  btVector3 edgeCrossB = edge.cross(normalB).normalize();
173 
174  {
175  btVector3 tmp = triangle[otherIndexB] - triangle[sharedVertsB[0]];
176  if (edgeCrossB.dot(tmp) < 0)
177  {
178  edgeCrossB *= -1;
179  }
180  }
181 
182  btScalar angle2 = 0;
183  btScalar ang4 = 0.f;
184 
185  btVector3 calculatedEdge = edgeCrossA.cross(edgeCrossB);
186  btScalar len2 = calculatedEdge.length2();
187 
188  btScalar correctedAngle(0);
189  //btVector3 calculatedNormalB = normalA;
190  bool isConvex = false;
191 
192  if (len2 < m_triangleInfoMap->m_planarEpsilon)
193  {
194  angle2 = 0.f;
195  ang4 = 0.f;
196  }
197  else
198  {
199  calculatedEdge.normalize();
200  btVector3 calculatedNormalA = calculatedEdge.cross(edgeCrossA);
201  calculatedNormalA.normalize();
202  angle2 = btGetAngle(calculatedNormalA, edgeCrossA, edgeCrossB);
203  ang4 = SIMD_PI - angle2;
204  btScalar dotA = normalA.dot(edgeCrossB);
206  isConvex = (dotA < 0.);
207 
208  correctedAngle = isConvex ? ang4 : -ang4;
209  }
210 
211  //alternatively use
212  //btVector3 calculatedNormalB2 = quatRotate(orn,normalA);
213 
214  switch (sumvertsA)
215  {
216  case 1:
217  {
219  btQuaternion orn(edge, -correctedAngle);
220  btVector3 computedNormalB = quatRotate(orn, normalA);
221  btScalar bla = computedNormalB.dot(normalB);
222  if (bla < 0)
223  {
224  computedNormalB *= -1;
226  }
227 #ifdef DEBUG_INTERNAL_EDGE
228  if ((computedNormalB - normalB).length() > 0.0001)
229  {
230  printf("warning: normals not identical\n");
231  }
232 #endif //DEBUG_INTERNAL_EDGE
233 
234  info->m_edgeV0V1Angle = -correctedAngle;
235 
236  if (isConvex)
237  info->m_flags |= TRI_INFO_V0V1_CONVEX;
238  break;
239  }
240  case 2:
241  {
243  btQuaternion orn(edge, -correctedAngle);
244  btVector3 computedNormalB = quatRotate(orn, normalA);
245  if (computedNormalB.dot(normalB) < 0)
246  {
247  computedNormalB *= -1;
249  }
250 
251 #ifdef DEBUG_INTERNAL_EDGE
252  if ((computedNormalB - normalB).length() > 0.0001)
253  {
254  printf("warning: normals not identical\n");
255  }
256 #endif //DEBUG_INTERNAL_EDGE
257  info->m_edgeV2V0Angle = -correctedAngle;
258  if (isConvex)
259  info->m_flags |= TRI_INFO_V2V0_CONVEX;
260  break;
261  }
262  case 3:
263  {
265  btQuaternion orn(edge, -correctedAngle);
266  btVector3 computedNormalB = quatRotate(orn, normalA);
267  if (computedNormalB.dot(normalB) < 0)
268  {
270  computedNormalB *= -1;
271  }
272 #ifdef DEBUG_INTERNAL_EDGE
273  if ((computedNormalB - normalB).length() > 0.0001)
274  {
275  printf("warning: normals not identical\n");
276  }
277 #endif //DEBUG_INTERNAL_EDGE
278  info->m_edgeV1V2Angle = -correctedAngle;
279 
280  if (isConvex)
281  info->m_flags |= TRI_INFO_V1V2_CONVEX;
282  break;
283  }
284  }
285 
286  break;
287  }
288  default:
289  {
290  // printf("warning: duplicate triangle\n");
291  }
292  }
293  }
294 };
295 
296 
298 {
301 
302 
304  :m_heightfieldShape(heightFieldShape),
305  m_triangleInfoMap(triangleInfoMap)
306  {
307  }
308  virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex)
309  {
310  btConnectivityProcessor connectivityProcessor;
311  connectivityProcessor.m_partIdA = partId;
312  connectivityProcessor.m_triangleIndexA = triangleIndex;
313  connectivityProcessor.m_triangleVerticesA = triangle;
314  connectivityProcessor.m_triangleInfoMap = m_triangleInfoMap;
315  btVector3 aabbMin, aabbMax;
318  aabbMin.setMin(triangle[0]);
319  aabbMax.setMax(triangle[0]);
320  aabbMin.setMin(triangle[1]);
321  aabbMax.setMax(triangle[1]);
322  aabbMin.setMin(triangle[2]);
323  aabbMax.setMax(triangle[2]);
324 
325  m_heightfieldShape->processAllTriangles(&connectivityProcessor, aabbMin, aabbMax);
326  }
327 };
330 
332 {
333  //the user pointer shouldn't already be used for other purposes, we intend to store connectivity info there!
334  if (trimeshShape->getTriangleInfoMap())
335  return;
336 
337  trimeshShape->setTriangleInfoMap(triangleInfoMap);
338 
339  btStridingMeshInterface* meshInterface = trimeshShape->getMeshInterface();
340  const btVector3& meshScaling = meshInterface->getScaling();
341 
342  for (int partId = 0; partId < meshInterface->getNumSubParts(); partId++)
343  {
344  const unsigned char* vertexbase = 0;
345  int numverts = 0;
347  int stride = 0;
348  const unsigned char* indexbase = 0;
349  int indexstride = 0;
350  int numfaces = 0;
351  PHY_ScalarType indicestype = PHY_INTEGER;
352  //PHY_ScalarType indexType=0;
353 
354  btVector3 triangleVerts[3];
355  meshInterface->getLockedReadOnlyVertexIndexBase(&vertexbase, numverts, type, stride, &indexbase, indexstride, numfaces, indicestype, partId);
356  btVector3 aabbMin, aabbMax;
357 
358  for (int triangleIndex = 0; triangleIndex < numfaces; triangleIndex++)
359  {
360  unsigned int* gfxbase = (unsigned int*)(indexbase + triangleIndex * indexstride);
361 
362  for (int j = 2; j >= 0; j--)
363  {
364  int graphicsindex = indicestype == PHY_SHORT ? ((unsigned short*)gfxbase)[j] : gfxbase[j];
365  if (type == PHY_FLOAT)
366  {
367  float* graphicsbase = (float*)(vertexbase + graphicsindex * stride);
368  triangleVerts[j] = btVector3(
369  graphicsbase[0] * meshScaling.getX(),
370  graphicsbase[1] * meshScaling.getY(),
371  graphicsbase[2] * meshScaling.getZ());
372  }
373  else
374  {
375  double* graphicsbase = (double*)(vertexbase + graphicsindex * stride);
376  triangleVerts[j] = btVector3(btScalar(graphicsbase[0] * meshScaling.getX()), btScalar(graphicsbase[1] * meshScaling.getY()), btScalar(graphicsbase[2] * meshScaling.getZ()));
377  }
378  }
381  aabbMin.setMin(triangleVerts[0]);
382  aabbMax.setMax(triangleVerts[0]);
383  aabbMin.setMin(triangleVerts[1]);
384  aabbMax.setMax(triangleVerts[1]);
385  aabbMin.setMin(triangleVerts[2]);
386  aabbMax.setMax(triangleVerts[2]);
387 
388  btConnectivityProcessor connectivityProcessor;
389  connectivityProcessor.m_partIdA = partId;
390  connectivityProcessor.m_triangleIndexA = triangleIndex;
391  connectivityProcessor.m_triangleVerticesA = &triangleVerts[0];
392  connectivityProcessor.m_triangleInfoMap = triangleInfoMap;
393 
394  trimeshShape->processAllTriangles(&connectivityProcessor, aabbMin, aabbMax);
395  }
396  }
397 }
398 
399 
401 {
402 
403  //the user pointer shouldn't already be used for other purposes, we intend to store connectivity info there!
404  if (heightfieldShape->getTriangleInfoMap())
405  return;
406 
407  heightfieldShape->setTriangleInfoMap(triangleInfoMap);
408 
409  //get all the triangles of the heightfield
410 
411  btVector3 aabbMin, aabbMax;
412 
415 
416  b3ProcessAllTrianglesHeightfield processHeightfield(heightfieldShape, triangleInfoMap);
417  heightfieldShape->processAllTriangles(&processHeightfield, aabbMin, aabbMax);
418 
419 }
420 
421 // Given a point and a line segment (defined by two points), compute the closest point
422 // in the line. Cap the point at the endpoints of the line segment.
423 void btNearestPointInLineSegment(const btVector3& point, const btVector3& line0, const btVector3& line1, btVector3& nearestPoint)
424 {
425  btVector3 lineDelta = line1 - line0;
426 
427  // Handle degenerate lines
428  if (lineDelta.fuzzyZero())
429  {
430  nearestPoint = line0;
431  }
432  else
433  {
434  btScalar delta = (point - line0).dot(lineDelta) / (lineDelta).dot(lineDelta);
435 
436  // Clamp the point to conform to the segment's endpoints
437  if (delta < 0)
438  delta = 0;
439  else if (delta > 1)
440  delta = 1;
441 
442  nearestPoint = line0 + lineDelta * delta;
443  }
444 }
445 
446 bool btClampNormal(const btVector3& edge, const btVector3& tri_normal_org, const btVector3& localContactNormalOnB, btScalar correctedEdgeAngle, btVector3& clampedLocalNormal)
447 {
448  btVector3 tri_normal = tri_normal_org;
449  //we only have a local triangle normal, not a local contact normal -> only normal in world space...
450  //either compute the current angle all in local space, or all in world space
451 
452  btVector3 edgeCross = edge.cross(tri_normal).normalize();
453  btScalar curAngle = btGetAngle(edgeCross, tri_normal, localContactNormalOnB);
454 
455  if (correctedEdgeAngle < 0)
456  {
457  if (curAngle < correctedEdgeAngle)
458  {
459  btScalar diffAngle = correctedEdgeAngle - curAngle;
460  btQuaternion rotation(edge, diffAngle);
461  clampedLocalNormal = btMatrix3x3(rotation) * localContactNormalOnB;
462  return true;
463  }
464  }
465 
466  if (correctedEdgeAngle >= 0)
467  {
468  if (curAngle > correctedEdgeAngle)
469  {
470  btScalar diffAngle = correctedEdgeAngle - curAngle;
471  btQuaternion rotation(edge, diffAngle);
472  clampedLocalNormal = btMatrix3x3(rotation) * localContactNormalOnB;
473  return true;
474  }
475  }
476  return false;
477 }
478 
480 void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap, const btCollisionObjectWrapper* colObj1Wrap, int partId0, int index0, int normalAdjustFlags)
481 {
482  //btAssert(colObj0->getCollisionShape()->getShapeType() == TRIANGLE_SHAPE_PROXYTYPE);
484  return;
485 
486 
487  btTriangleInfoMap* triangleInfoMapPtr = 0;
488 
490  {
492  triangleInfoMapPtr = heightfield->getTriangleInfoMap();
493 
494 //#define USE_HEIGHTFIELD_TRIANGLES
495 #ifdef USE_HEIGHTFIELD_TRIANGLES
496  btVector3 newNormal = btVector3(0, 0, 1);
497 
498  const btTriangleShape* tri_shape = static_cast<const btTriangleShape*>(colObj0Wrap->getCollisionShape());
499  btVector3 tri_normal;
500  tri_shape->calcNormal(tri_normal);
501  newNormal = tri_normal;
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?)
507  return;
508 #endif
509  }
510 
511 
512  btBvhTriangleMeshShape* trimesh = 0;
513 
515  {
516  trimesh = ((btScaledBvhTriangleMeshShape*)colObj0Wrap->getCollisionObject()->getCollisionShape())->getChildShape();
517  }
518  else
519  {
521  {
522  trimesh = (btBvhTriangleMeshShape*)colObj0Wrap->getCollisionObject()->getCollisionShape();
523  }
524  }
525  if (trimesh)
526  {
527  triangleInfoMapPtr = (btTriangleInfoMap*)trimesh->getTriangleInfoMap();
528  }
529 
530 
531  if (!triangleInfoMapPtr)
532  return;
533 
534  int hash = btGetHash(partId0, index0);
535 
536  btTriangleInfo* info = triangleInfoMapPtr->find(hash);
537  if (!info)
538  return;
539 
540  btScalar frontFacing = (normalAdjustFlags & BT_TRIANGLE_CONVEX_BACKFACE_MODE) == 0 ? 1.f : -1.f;
541 
542  const btTriangleShape* tri_shape = static_cast<const btTriangleShape*>(colObj0Wrap->getCollisionShape());
543  btVector3 v0, v1, v2;
544  tri_shape->getVertex(0, v0);
545  tri_shape->getVertex(1, v1);
546  tri_shape->getVertex(2, v2);
547 
548  //btVector3 center = (v0+v1+v2)*btScalar(1./3.);
549 
550  btVector3 red(1, 0, 0), green(0, 1, 0), blue(0, 0, 1), white(1, 1, 1), black(0, 0, 0);
551  btVector3 tri_normal;
552  tri_shape->calcNormal(tri_normal);
553 
554  //btScalar dot = tri_normal.dot(cp.m_normalWorldOnB);
555  btVector3 nearest;
556  btNearestPointInLineSegment(cp.m_localPointB, v0, v1, nearest);
557 
558  btVector3 contact = cp.m_localPointB;
559 #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
560  const btTransform& tr = colObj0->getWorldTransform();
561  btDebugDrawLine(tr * nearest, tr * cp.m_localPointB, red);
562 #endif //BT_INTERNAL_EDGE_DEBUG_DRAW
563 
564  bool isNearEdge = false;
565 
566  int numConcaveEdgeHits = 0;
567  int numConvexEdgeHits = 0;
568 
569  btVector3 localContactNormalOnB = colObj0Wrap->getWorldTransform().getBasis().transpose() * cp.m_normalWorldOnB;
570  localContactNormalOnB.normalize(); //is this necessary?
571 
572  // Get closest edge
573  int bestedge = -1;
574  btScalar disttobestedge = BT_LARGE_FLOAT;
575  //
576  // Edge 0 -> 1
577  if (btFabs(info->m_edgeV0V1Angle) < triangleInfoMapPtr->m_maxEdgeAngleThreshold)
578  {
579  btVector3 nearest;
580  btNearestPointInLineSegment(cp.m_localPointB, v0, v1, nearest);
581  btScalar len = (contact - nearest).length();
582  //
583  if (len < disttobestedge)
584  {
585  bestedge = 0;
586  disttobestedge = len;
587  }
588  }
589  // Edge 1 -> 2
590  if (btFabs(info->m_edgeV1V2Angle) < triangleInfoMapPtr->m_maxEdgeAngleThreshold)
591  {
592  btVector3 nearest;
593  btNearestPointInLineSegment(cp.m_localPointB, v1, v2, nearest);
594  btScalar len = (contact - nearest).length();
595  //
596  if (len < disttobestedge)
597  {
598  bestedge = 1;
599  disttobestedge = len;
600  }
601  }
602  // Edge 2 -> 0
603  if (btFabs(info->m_edgeV2V0Angle) < triangleInfoMapPtr->m_maxEdgeAngleThreshold)
604  {
605  btVector3 nearest;
606  btNearestPointInLineSegment(cp.m_localPointB, v2, v0, nearest);
607  btScalar len = (contact - nearest).length();
608  //
609  if (len < disttobestedge)
610  {
611  bestedge = 2;
612  disttobestedge = len;
613  }
614  }
615 
616 #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
617  btVector3 upfix = tri_normal * btVector3(0.1f, 0.1f, 0.1f);
618  btDebugDrawLine(tr * v0 + upfix, tr * v1 + upfix, red);
619 #endif
620  if (btFabs(info->m_edgeV0V1Angle) < triangleInfoMapPtr->m_maxEdgeAngleThreshold)
621  {
622 #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
623  btDebugDrawLine(tr * contact, tr * (contact + cp.m_normalWorldOnB * 10), black);
624 #endif
625  btScalar len = (contact - nearest).length();
626  if (len < triangleInfoMapPtr->m_edgeDistanceThreshold)
627  if (bestedge == 0)
628  {
629  btVector3 edge(v0 - v1);
630  isNearEdge = true;
631 
632  if (info->m_edgeV0V1Angle == btScalar(0))
633  {
634  numConcaveEdgeHits++;
635  }
636  else
637  {
638  bool isEdgeConvex = (info->m_flags & TRI_INFO_V0V1_CONVEX);
639  btScalar swapFactor = isEdgeConvex ? btScalar(1) : btScalar(-1);
640 #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
641  btDebugDrawLine(tr * nearest, tr * (nearest + swapFactor * tri_normal * 10), white);
642 #endif //BT_INTERNAL_EDGE_DEBUG_DRAW
643 
644  btVector3 nA = swapFactor * tri_normal;
645 
646  btQuaternion orn(edge, info->m_edgeV0V1Angle);
647  btVector3 computedNormalB = quatRotate(orn, tri_normal);
649  computedNormalB *= -1;
650  btVector3 nB = swapFactor * computedNormalB;
651 
652  btScalar NdotA = localContactNormalOnB.dot(nA);
653  btScalar NdotB = localContactNormalOnB.dot(nB);
654  bool backFacingNormal = (NdotA < triangleInfoMapPtr->m_convexEpsilon) && (NdotB < triangleInfoMapPtr->m_convexEpsilon);
655 
656 #ifdef DEBUG_INTERNAL_EDGE
657  {
658  btDebugDrawLine(cp.getPositionWorldOnB(), cp.getPositionWorldOnB() + tr.getBasis() * (nB * 20), red);
659  }
660 #endif //DEBUG_INTERNAL_EDGE
661 
662  if (backFacingNormal)
663  {
664  numConcaveEdgeHits++;
665  }
666  else
667  {
668  numConvexEdgeHits++;
669  btVector3 clampedLocalNormal;
670  bool isClamped = btClampNormal(edge, swapFactor * tri_normal, localContactNormalOnB, info->m_edgeV0V1Angle, clampedLocalNormal);
671  if (isClamped)
672  {
673  if (((normalAdjustFlags & BT_TRIANGLE_CONVEX_DOUBLE_SIDED) != 0) || (clampedLocalNormal.dot(frontFacing * tri_normal) > 0))
674  {
675  btVector3 newNormal = colObj0Wrap->getWorldTransform().getBasis() * clampedLocalNormal;
676  // cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB);
677  cp.m_normalWorldOnB = newNormal;
678  // Reproject collision point along normal. (what about cp.m_distance1?)
681  }
682  }
683  }
684  }
685  }
686  }
687 
688  btNearestPointInLineSegment(contact, v1, v2, nearest);
689 #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
690  btDebugDrawLine(tr * nearest, tr * cp.m_localPointB, green);
691 #endif //BT_INTERNAL_EDGE_DEBUG_DRAW
692 
693 #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
694  btDebugDrawLine(tr * v1 + upfix, tr * v2 + upfix, green);
695 #endif
696 
697  if (btFabs(info->m_edgeV1V2Angle) < triangleInfoMapPtr->m_maxEdgeAngleThreshold)
698  {
699 #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
700  btDebugDrawLine(tr * contact, tr * (contact + cp.m_normalWorldOnB * 10), black);
701 #endif //BT_INTERNAL_EDGE_DEBUG_DRAW
702 
703  btScalar len = (contact - nearest).length();
704  if (len < triangleInfoMapPtr->m_edgeDistanceThreshold)
705  if (bestedge == 1)
706  {
707  isNearEdge = true;
708 #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
709  btDebugDrawLine(tr * nearest, tr * (nearest + tri_normal * 10), white);
710 #endif //BT_INTERNAL_EDGE_DEBUG_DRAW
711 
712  btVector3 edge(v1 - v2);
713 
714  isNearEdge = true;
715 
716  if (info->m_edgeV1V2Angle == btScalar(0))
717  {
718  numConcaveEdgeHits++;
719  }
720  else
721  {
722  bool isEdgeConvex = (info->m_flags & TRI_INFO_V1V2_CONVEX) != 0;
723  btScalar swapFactor = isEdgeConvex ? btScalar(1) : btScalar(-1);
724 #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
725  btDebugDrawLine(tr * nearest, tr * (nearest + swapFactor * tri_normal * 10), white);
726 #endif //BT_INTERNAL_EDGE_DEBUG_DRAW
727 
728  btVector3 nA = swapFactor * tri_normal;
729 
730  btQuaternion orn(edge, info->m_edgeV1V2Angle);
731  btVector3 computedNormalB = quatRotate(orn, tri_normal);
733  computedNormalB *= -1;
734  btVector3 nB = swapFactor * computedNormalB;
735 
736 #ifdef DEBUG_INTERNAL_EDGE
737  {
738  btDebugDrawLine(cp.getPositionWorldOnB(), cp.getPositionWorldOnB() + tr.getBasis() * (nB * 20), red);
739  }
740 #endif //DEBUG_INTERNAL_EDGE
741 
742  btScalar NdotA = localContactNormalOnB.dot(nA);
743  btScalar NdotB = localContactNormalOnB.dot(nB);
744  bool backFacingNormal = (NdotA < triangleInfoMapPtr->m_convexEpsilon) && (NdotB < triangleInfoMapPtr->m_convexEpsilon);
745 
746  if (backFacingNormal)
747  {
748  numConcaveEdgeHits++;
749  }
750  else
751  {
752  numConvexEdgeHits++;
753  btVector3 localContactNormalOnB = colObj0Wrap->getWorldTransform().getBasis().transpose() * cp.m_normalWorldOnB;
754  btVector3 clampedLocalNormal;
755  bool isClamped = btClampNormal(edge, swapFactor * tri_normal, localContactNormalOnB, info->m_edgeV1V2Angle, clampedLocalNormal);
756  if (isClamped)
757  {
758  if (((normalAdjustFlags & BT_TRIANGLE_CONVEX_DOUBLE_SIDED) != 0) || (clampedLocalNormal.dot(frontFacing * tri_normal) > 0))
759  {
760  btVector3 newNormal = colObj0Wrap->getWorldTransform().getBasis() * clampedLocalNormal;
761  // cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB);
762  cp.m_normalWorldOnB = newNormal;
763  // Reproject collision point along normal.
766  }
767  }
768  }
769  }
770  }
771  }
772 
773  btNearestPointInLineSegment(contact, v2, v0, nearest);
774 #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
775  btDebugDrawLine(tr * nearest, tr * cp.m_localPointB, blue);
776 #endif //BT_INTERNAL_EDGE_DEBUG_DRAW
777 #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
778  btDebugDrawLine(tr * v2 + upfix, tr * v0 + upfix, blue);
779 #endif
780 
781  if (btFabs(info->m_edgeV2V0Angle) < triangleInfoMapPtr->m_maxEdgeAngleThreshold)
782  {
783 #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
784  btDebugDrawLine(tr * contact, tr * (contact + cp.m_normalWorldOnB * 10), black);
785 #endif //BT_INTERNAL_EDGE_DEBUG_DRAW
786 
787  btScalar len = (contact - nearest).length();
788  if (len < triangleInfoMapPtr->m_edgeDistanceThreshold)
789  if (bestedge == 2)
790  {
791  isNearEdge = true;
792 #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
793  btDebugDrawLine(tr * nearest, tr * (nearest + tri_normal * 10), white);
794 #endif //BT_INTERNAL_EDGE_DEBUG_DRAW
795 
796  btVector3 edge(v2 - v0);
797 
798  if (info->m_edgeV2V0Angle == btScalar(0))
799  {
800  numConcaveEdgeHits++;
801  }
802  else
803  {
804  bool isEdgeConvex = (info->m_flags & TRI_INFO_V2V0_CONVEX) != 0;
805  btScalar swapFactor = isEdgeConvex ? btScalar(1) : btScalar(-1);
806 #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
807  btDebugDrawLine(tr * nearest, tr * (nearest + swapFactor * tri_normal * 10), white);
808 #endif //BT_INTERNAL_EDGE_DEBUG_DRAW
809 
810  btVector3 nA = swapFactor * tri_normal;
811  btQuaternion orn(edge, info->m_edgeV2V0Angle);
812  btVector3 computedNormalB = quatRotate(orn, tri_normal);
814  computedNormalB *= -1;
815  btVector3 nB = swapFactor * computedNormalB;
816 
817 #ifdef DEBUG_INTERNAL_EDGE
818  {
819  btDebugDrawLine(cp.getPositionWorldOnB(), cp.getPositionWorldOnB() + tr.getBasis() * (nB * 20), red);
820  }
821 #endif //DEBUG_INTERNAL_EDGE
822 
823  btScalar NdotA = localContactNormalOnB.dot(nA);
824  btScalar NdotB = localContactNormalOnB.dot(nB);
825  bool backFacingNormal = (NdotA < triangleInfoMapPtr->m_convexEpsilon) && (NdotB < triangleInfoMapPtr->m_convexEpsilon);
826 
827  if (backFacingNormal)
828  {
829  numConcaveEdgeHits++;
830  }
831  else
832  {
833  numConvexEdgeHits++;
834  // printf("hitting convex edge\n");
835 
836  btVector3 localContactNormalOnB = colObj0Wrap->getWorldTransform().getBasis().transpose() * cp.m_normalWorldOnB;
837  btVector3 clampedLocalNormal;
838  bool isClamped = btClampNormal(edge, swapFactor * tri_normal, localContactNormalOnB, info->m_edgeV2V0Angle, clampedLocalNormal);
839  if (isClamped)
840  {
841  if (((normalAdjustFlags & BT_TRIANGLE_CONVEX_DOUBLE_SIDED) != 0) || (clampedLocalNormal.dot(frontFacing * tri_normal) > 0))
842  {
843  btVector3 newNormal = colObj0Wrap->getWorldTransform().getBasis() * clampedLocalNormal;
844  // cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB);
845  cp.m_normalWorldOnB = newNormal;
846  // Reproject collision point along normal.
849  }
850  }
851  }
852  }
853  }
854  }
855 
856 #ifdef DEBUG_INTERNAL_EDGE
857  {
858  btVector3 color(0, 1, 1);
859  btDebugDrawLine(cp.getPositionWorldOnB(), cp.getPositionWorldOnB() + cp.m_normalWorldOnB * 10, color);
860  }
861 #endif //DEBUG_INTERNAL_EDGE
862 
863  if (isNearEdge)
864  {
865  if (numConcaveEdgeHits > 0)
866  {
867  if ((normalAdjustFlags & BT_TRIANGLE_CONCAVE_DOUBLE_SIDED) != 0)
868  {
869  //fix tri_normal so it pointing the same direction as the current local contact normal
870  if (tri_normal.dot(localContactNormalOnB) < 0)
871  {
872  tri_normal *= -1;
873  }
874  cp.m_normalWorldOnB = colObj0Wrap->getWorldTransform().getBasis() * tri_normal;
875  }
876  else
877  {
878  btVector3 newNormal = tri_normal * frontFacing;
879  //if the tri_normal is pointing opposite direction as the current local contact normal, skip it
880  btScalar d = newNormal.dot(localContactNormalOnB);
881  if (d < 0)
882  {
883  return;
884  }
885  //modify the normal to be the triangle normal (or backfacing normal)
886  cp.m_normalWorldOnB = colObj0Wrap->getWorldTransform().getBasis() * newNormal;
887  }
888 
889  // Reproject collision point along normal.
892  }
893  }
894 }
btManifoldPoint.h
BT_TRIANGLE_CONVEX_DOUBLE_SIDED
Definition: btInternalEdgeUtility.h:24
btConnectivityProcessor::m_triangleVerticesA
btVector3 * m_triangleVerticesA
Definition: btInternalEdgeUtility.cpp:53
btNearestPointInLineSegment
void btNearestPointInLineSegment(const btVector3 &point, const btVector3 &line0, const btVector3 &line1, btVector3 &nearestPoint)
Definition: btInternalEdgeUtility.cpp:423
TERRAIN_SHAPE_PROXYTYPE
Definition: btBroadphaseProxy.h:59
btTriangleShape::calcNormal
void calcNormal(btVector3 &normal) const
Definition: btTriangleShape.h:105
b3ProcessAllTrianglesHeightfield::m_heightfieldShape
btHeightfieldTerrainShape * m_heightfieldShape
Definition: btInternalEdgeUtility.cpp:299
dot
btScalar dot(const btQuaternion &q1, const btQuaternion &q2)
Calculate the dot product between two quaternions.
Definition: btQuaternion.h:888
btCollisionShape::getShapeType
int getShapeType() const
Definition: btCollisionShape.h:106
btQuaternion
The btQuaternion implements quaternion to perform linear algebra rotations in combination with btMatr...
Definition: btQuaternion.h:49
TRI_INFO_V0V1_CONVEX
#define TRI_INFO_V0V1_CONVEX
for btTriangleInfo m_flags
Definition: btTriangleInfoMap.h:23
btVector3::setValue
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
Definition: btVector3.h:640
btTriangleInfo::m_edgeV1V2Angle
btScalar m_edgeV1V2Angle
Definition: btTriangleInfoMap.h:46
btScalar
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:314
btCollisionObjectWrapper.h
btCollisionObjectWrapper
Definition: btCollisionObjectWrapper.h:17
btAdjustInternalEdgeContacts
void btAdjustInternalEdgeContacts(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, const btCollisionObjectWrapper *colObj1Wrap, int partId0, int index0, int normalAdjustFlags)
Changes a btManifoldPoint collision normal to the normal from the mesh.
Definition: btInternalEdgeUtility.cpp:480
btTriangleMeshShape::getMeshInterface
btStridingMeshInterface * getMeshInterface()
Definition: btTriangleMeshShape.h:59
btBvhTriangleMeshShape
The btBvhTriangleMeshShape is a static-triangle mesh shape, it can only be used for fixed/non-moving ...
Definition: btBvhTriangleMeshShape.h:34
btManifoldPoint::m_normalWorldOnB
btVector3 m_normalWorldOnB
Definition: btManifoldPoint.h:100
btVector3::cross
btVector3 cross(const btVector3 &v) const
Return the cross product between this and another vector.
Definition: btVector3.h:380
btHeightfieldTerrainShape::setTriangleInfoMap
void setTriangleInfoMap(btTriangleInfoMap *map)
Definition: btHeightfieldTerrainShape.h:219
TRI_INFO_V1V2_SWAP_NORMALB
#define TRI_INFO_V1V2_SWAP_NORMALB
Definition: btTriangleInfoMap.h:28
btConnectivityProcessor::m_partIdA
int m_partIdA
Definition: btInternalEdgeUtility.cpp:51
b3ProcessAllTrianglesHeightfield::m_triangleInfoMap
btTriangleInfoMap * m_triangleInfoMap
Definition: btInternalEdgeUtility.cpp:300
btVector3::dot
btScalar dot(const btVector3 &v) const
Return the dot product.
Definition: btVector3.h:229
SIMD_PI
#define SIMD_PI
Definition: btScalar.h:526
MAX_NUM_PARTS_IN_BITS
#define MAX_NUM_PARTS_IN_BITS
Definition: btQuantizedBvh.h:51
btTriangleInfoMap::m_convexEpsilon
btScalar m_convexEpsilon
Definition: btTriangleInfoMap.h:55
btHeightfieldTerrainShape
btHeightfieldTerrainShape simulates a 2D heightfield terrain
Definition: btHeightfieldTerrainShape.h:72
btCollisionObjectWrapper::getWorldTransform
const btTransform & getWorldTransform() const
Definition: btCollisionObjectWrapper.h:44
btConnectivityProcessor::m_triangleIndexA
int m_triangleIndexA
Definition: btInternalEdgeUtility.cpp:52
PHY_FLOAT
Definition: btConcaveShape.h:27
btConnectivityProcessor
Definition: btInternalEdgeUtility.cpp:49
btTriangleShape
Definition: btTriangleShape.h:22
btTriangleShape.h
btStridingMeshInterface
The btStridingMeshInterface is the interface class for high performance generic access to triangle me...
Definition: btStridingMeshInterface.h:26
BT_TRIANGLE_CONCAVE_DOUBLE_SIDED
Definition: btInternalEdgeUtility.h:23
btVector3::getX
const btScalar & getX() const
Return the x value.
Definition: btVector3.h:561
btTriangleInfo::m_edgeV2V0Angle
btScalar m_edgeV2V0Angle
Definition: btTriangleInfoMap.h:47
TRIANGLE_SHAPE_PROXYTYPE
Definition: btBroadphaseProxy.h:31
btHeightfieldTerrainShape::processAllTriangles
virtual void processAllTriangles(btTriangleCallback *callback, const btVector3 &aabbMin, const btVector3 &aabbMax) const
process all triangles within the provided axis-aligned bounding box
Definition: btHeightfieldTerrainShape.cpp:264
btFabs
btScalar btFabs(btScalar x)
Definition: btScalar.h:497
BT_LARGE_FLOAT
#define BT_LARGE_FLOAT
Definition: btScalar.h:316
btManifoldPoint::m_positionWorldOnB
btVector3 m_positionWorldOnB
Definition: btManifoldPoint.h:97
btIDebugDraw
The btIDebugDraw interface class allows hooking up a debug renderer to visually debug simulations.
Definition: btIDebugDraw.h:26
btManifoldPoint
ManifoldContactPoint collects and maintains persistent contactpoints.
Definition: btManifoldPoint.h:51
btGetHash
static int btGetHash(int partId, int triangleIndex)
Definition: btInternalEdgeUtility.cpp:34
btManifoldPoint::m_distance1
btScalar m_distance1
Definition: btManifoldPoint.h:102
btCollisionObjectWrapper::getCollisionShape
const btCollisionShape * getCollisionShape() const
Definition: btCollisionObjectWrapper.h:46
btTransform::getBasis
btMatrix3x3 & getBasis()
Return the basis matrix for the rotation.
Definition: btTransform.h:108
btVector3::setMax
void setMax(const btVector3 &other)
Set each element to the max of the current values and the values of another btVector3.
Definition: btVector3.h:609
btInternalEdgeUtility.h
btTriangleInfoMap
The btTriangleInfoMap stores edge angle information for some triangles. You can compute this informat...
Definition: btTriangleInfoMap.h:53
PHY_ScalarType
PHY_ScalarType
PHY_ScalarType enumerates possible scalar types.
Definition: btConcaveShape.h:25
SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE
Definition: btBroadphaseProxy.h:55
btTriangleInfo::m_edgeV0V1Angle
btScalar m_edgeV0V1Angle
Definition: btTriangleInfoMap.h:45
btMatrix3x3
The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with...
Definition: btMatrix3x3.h:46
btMatrix3x3::transpose
btMatrix3x3 transpose() const
Return the transpose of the matrix.
Definition: btMatrix3x3.h:1033
btTriangleCallback
The btTriangleCallback provides a callback for each overlapping triangle when calling processAllTrian...
Definition: btTriangleCallback.h:23
btVector3::fuzzyZero
bool fuzzyZero() const
Definition: btVector3.h:688
btTransform
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:28
btCollisionObjectWrapper::getCollisionObject
const btCollisionObject * getCollisionObject() const
Definition: btCollisionObjectWrapper.h:45
btVector3
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:80
btManifoldPoint::getPositionWorldOnB
const btVector3 & getPositionWorldOnB() const
Definition: btManifoldPoint.h:157
btTriangleShape::getVertex
virtual void getVertex(int index, btVector3 &vert) const
Definition: btTriangleShape.h:44
btGetAngle
static btScalar btGetAngle(const btVector3 &edgeA, const btVector3 &normalA, const btVector3 &normalB)
Definition: btInternalEdgeUtility.cpp:40
btTriangleInfo::m_flags
int m_flags
Definition: btTriangleInfoMap.h:43
btStridingMeshInterface::getLockedReadOnlyVertexIndexBase
virtual void getLockedReadOnlyVertexIndexBase(const unsigned char **vertexbase, int &numverts, PHY_ScalarType &type, int &stride, const unsigned char **indexbase, int &indexstride, int &numfaces, PHY_ScalarType &indicestype, int subpart=0) const =0
btTransform::invXform
btVector3 invXform(const btVector3 &inVec) const
Definition: btTransform.h:215
btBvhTriangleMeshShape::processAllTriangles
virtual void processAllTriangles(btTriangleCallback *callback, const btVector3 &aabbMin, const btVector3 &aabbMax) const
Definition: btBvhTriangleMeshShape.cpp:229
btBvhTriangleMeshShape::setTriangleInfoMap
void setTriangleInfoMap(btTriangleInfoMap *triangleInfoMap)
Definition: btBvhTriangleMeshShape.h:92
btVector3::getZ
const btScalar & getZ() const
Return the z value.
Definition: btVector3.h:565
btHeightfieldTerrainShape.h
btStridingMeshInterface::getScaling
const btVector3 & getScaling() const
Definition: btStridingMeshInterface.h:80
btIDebugDraw::drawLine
virtual void drawLine(const btVector3 &from, const btVector3 &to, const btVector3 &color)=0
btVector3::getY
const btScalar & getY() const
Return the y value.
Definition: btVector3.h:563
btTriangleInfo
The btTriangleInfo structure stores information to adjust collision normals to avoid collisions again...
Definition: btTriangleInfoMap.h:33
btManifoldPoint::m_localPointB
btVector3 m_localPointB
Definition: btManifoldPoint.h:96
btTriangleInfoMap::m_maxEdgeAngleThreshold
btScalar m_maxEdgeAngleThreshold
used to determine edge contacts: if the closest distance between a contact point and an edge is small...
Definition: btTriangleInfoMap.h:59
btHashMap::find
const Value * find(const Key &key) const
Definition: btHashMap.h:424
btVector3::setMin
void setMin(const btVector3 &other)
Set each element to the min of the current values and the values of another btVector3.
Definition: btVector3.h:626
TRI_INFO_V2V0_CONVEX
#define TRI_INFO_V2V0_CONVEX
Definition: btTriangleInfoMap.h:25
TRIANGLE_MESH_SHAPE_PROXYTYPE
Definition: btBroadphaseProxy.h:54
b3ProcessAllTrianglesHeightfield
Definition: btInternalEdgeUtility.cpp:297
btManifoldPoint::m_positionWorldOnA
btVector3 m_positionWorldOnA
m_positionWorldOnA is redundant information, see getPositionWorldOnA(), but for clarity
Definition: btManifoldPoint.h:99
btIDebugDraw.h
btHashMap::insert
void insert(const Key &key, const Value &value)
Definition: btHashMap.h:264
btStridingMeshInterface::getNumSubParts
virtual int getNumSubParts() const =0
getNumSubParts returns the number of separate subparts each subpart has a continuous array of vertice...
PHY_INTEGER
Definition: btConcaveShape.h:29
btBvhTriangleMeshShape.h
TRI_INFO_V0V1_SWAP_NORMALB
#define TRI_INFO_V0V1_SWAP_NORMALB
Definition: btTriangleInfoMap.h:27
btCollisionObject.h
btAtan2
btScalar btAtan2(btScalar x, btScalar y)
Definition: btScalar.h:518
btBvhTriangleMeshShape::getTriangleInfoMap
const btTriangleInfoMap * getTriangleInfoMap() const
Definition: btBvhTriangleMeshShape.h:97
btHeightfieldTerrainShape::getTriangleInfoMap
const struct btTriangleInfoMap * getTriangleInfoMap() const
Definition: btHeightfieldTerrainShape.h:211
btScaledBvhTriangleMeshShape.h
length
btScalar length(const btQuaternion &q)
Return the length of a quaternion.
Definition: btQuaternion.h:895
b3ProcessAllTrianglesHeightfield::processTriangle
virtual void processTriangle(btVector3 *triangle, int partId, int triangleIndex)
Definition: btInternalEdgeUtility.cpp:308
TRI_INFO_V1V2_CONVEX
#define TRI_INFO_V1V2_CONVEX
Definition: btTriangleInfoMap.h:24
btTriangleInfoMap::m_equalVertexThreshold
btScalar m_equalVertexThreshold
used to determine if a triangle edge is planar with zero angle
Definition: btTriangleInfoMap.h:57
btVector3::normalize
btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
Definition: btVector3.h:303
btScaledBvhTriangleMeshShape
The btScaledBvhTriangleMeshShape allows to instance a scaled version of an existing btBvhTriangleMesh...
Definition: btScaledBvhTriangleMeshShape.h:23
TRI_INFO_V2V0_SWAP_NORMALB
#define TRI_INFO_V2V0_SWAP_NORMALB
Definition: btTriangleInfoMap.h:29
b3ProcessAllTrianglesHeightfield::b3ProcessAllTrianglesHeightfield
b3ProcessAllTrianglesHeightfield(btHeightfieldTerrainShape *heightFieldShape, btTriangleInfoMap *triangleInfoMap)
Definition: btInternalEdgeUtility.cpp:303
btConnectivityProcessor::processTriangle
virtual void processTriangle(btVector3 *triangle, int partId, int triangleIndex)
Definition: btInternalEdgeUtility.cpp:56
btClampNormal
bool btClampNormal(const btVector3 &edge, const btVector3 &tri_normal_org, const btVector3 &localContactNormalOnB, btScalar correctedEdgeAngle, btVector3 &clampedLocalNormal)
Definition: btInternalEdgeUtility.cpp:446
btGenerateInternalEdgeInfo
void btGenerateInternalEdgeInfo(btBvhTriangleMeshShape *trimeshShape, btTriangleInfoMap *triangleInfoMap)
Call btGenerateInternalEdgeInfo to create triangle info, store in the shape 'userInfo'.
Definition: btInternalEdgeUtility.cpp:331
BT_TRIANGLE_CONVEX_BACKFACE_MODE
Definition: btInternalEdgeUtility.h:22
btConnectivityProcessor::m_triangleInfoMap
btTriangleInfoMap * m_triangleInfoMap
Definition: btInternalEdgeUtility.cpp:54
PHY_SHORT
Definition: btConcaveShape.h:30
btVector3::length2
btScalar length2() const
Return the length of the vector squared.
Definition: btVector3.h:251
btCollisionObject::getCollisionShape
const btCollisionShape * getCollisionShape() const
Definition: btCollisionObject.h:226
quatRotate
btVector3 quatRotate(const btQuaternion &rotation, const btVector3 &v)
Definition: btQuaternion.h:926