b3ContactSphereSphere.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. #ifndef B3_CONTACT_SPHERE_SPHERE_H
  2. #define B3_CONTACT_SPHERE_SPHERE_H
  3. void computeContactSphereConvex(int pairIndex,
  4. int bodyIndexA, int bodyIndexB,
  5. int collidableIndexA, int collidableIndexB,
  6. const b3RigidBodyData* rigidBodies,
  7. const b3Collidable* collidables,
  8. const b3ConvexPolyhedronData* convexShapes,
  9. const b3Vector3* convexVertices,
  10. const int* convexIndices,
  11. const b3GpuFace* faces,
  12. b3Contact4* globalContactsOut,
  13. int& nGlobalContactsOut,
  14. int maxContactCapacity)
  15. {
  16. float radius = collidables[collidableIndexA].m_radius;
  17. float4 spherePos1 = rigidBodies[bodyIndexA].m_pos;
  18. b3Quaternion sphereOrn = rigidBodies[bodyIndexA].m_quat;
  19. float4 pos = rigidBodies[bodyIndexB].m_pos;
  20. b3Quaternion quat = rigidBodies[bodyIndexB].m_quat;
  21. b3Transform tr;
  22. tr.setIdentity();
  23. tr.setOrigin(pos);
  24. tr.setRotation(quat);
  25. b3Transform trInv = tr.inverse();
  26. float4 spherePos = trInv(spherePos1);
  27. int collidableIndex = rigidBodies[bodyIndexB].m_collidableIdx;
  28. int shapeIndex = collidables[collidableIndex].m_shapeIndex;
  29. int numFaces = convexShapes[shapeIndex].m_numFaces;
  30. float4 closestPnt = b3MakeVector3(0, 0, 0, 0);
  31. float4 hitNormalWorld = b3MakeVector3(0, 0, 0, 0);
  32. float minDist = -1000000.f; // TODO: What is the largest/smallest float?
  33. bool bCollide = true;
  34. int region = -1;
  35. float4 localHitNormal;
  36. for (int f = 0; f < numFaces; f++)
  37. {
  38. b3GpuFace face = faces[convexShapes[shapeIndex].m_faceOffset + f];
  39. float4 planeEqn;
  40. float4 localPlaneNormal = b3MakeVector3(face.m_plane.x, face.m_plane.y, face.m_plane.z, 0.f);
  41. float4 n1 = localPlaneNormal; //quatRotate(quat,localPlaneNormal);
  42. planeEqn = n1;
  43. planeEqn[3] = face.m_plane.w;
  44. float4 pntReturn;
  45. float dist = signedDistanceFromPointToPlane(spherePos, planeEqn, &pntReturn);
  46. if (dist > radius)
  47. {
  48. bCollide = false;
  49. break;
  50. }
  51. if (dist > 0)
  52. {
  53. //might hit an edge or vertex
  54. b3Vector3 out;
  55. bool isInPoly = IsPointInPolygon(spherePos,
  56. &face,
  57. &convexVertices[convexShapes[shapeIndex].m_vertexOffset],
  58. convexIndices,
  59. &out);
  60. if (isInPoly)
  61. {
  62. if (dist > minDist)
  63. {
  64. minDist = dist;
  65. closestPnt = pntReturn;
  66. localHitNormal = planeEqn;
  67. region = 1;
  68. }
  69. }
  70. else
  71. {
  72. b3Vector3 tmp = spherePos - out;
  73. b3Scalar l2 = tmp.length2();
  74. if (l2 < radius * radius)
  75. {
  76. dist = b3Sqrt(l2);
  77. if (dist > minDist)
  78. {
  79. minDist = dist;
  80. closestPnt = out;
  81. localHitNormal = tmp / dist;
  82. region = 2;
  83. }
  84. }
  85. else
  86. {
  87. bCollide = false;
  88. break;
  89. }
  90. }
  91. }
  92. else
  93. {
  94. if (dist > minDist)
  95. {
  96. minDist = dist;
  97. closestPnt = pntReturn;
  98. localHitNormal = planeEqn;
  99. region = 3;
  100. }
  101. }
  102. }
  103. static int numChecks = 0;
  104. numChecks++;
  105. if (bCollide && minDist > -10000)
  106. {
  107. float4 normalOnSurfaceB1 = tr.getBasis() * localHitNormal; //-hitNormalWorld;
  108. float4 pOnB1 = tr(closestPnt);
  109. //printf("dist ,%f,",minDist);
  110. float actualDepth = minDist - radius;
  111. if (actualDepth < 0)
  112. {
  113. //printf("actualDepth = ,%f,", actualDepth);
  114. //printf("normalOnSurfaceB1 = ,%f,%f,%f,", normalOnSurfaceB1.x,normalOnSurfaceB1.y,normalOnSurfaceB1.z);
  115. //printf("region=,%d,\n", region);
  116. pOnB1[3] = actualDepth;
  117. int dstIdx;
  118. // dstIdx = nGlobalContactsOut++;//AppendInc( nGlobalContactsOut, dstIdx );
  119. if (nGlobalContactsOut < maxContactCapacity)
  120. {
  121. dstIdx = nGlobalContactsOut;
  122. nGlobalContactsOut++;
  123. b3Contact4* c = &globalContactsOut[dstIdx];
  124. c->m_worldNormalOnB = normalOnSurfaceB1;
  125. c->setFrictionCoeff(0.7);
  126. c->setRestituitionCoeff(0.f);
  127. c->m_batchIdx = pairIndex;
  128. c->m_bodyAPtrAndSignBit = rigidBodies[bodyIndexA].m_invMass == 0 ? -bodyIndexA : bodyIndexA;
  129. c->m_bodyBPtrAndSignBit = rigidBodies[bodyIndexB].m_invMass == 0 ? -bodyIndexB : bodyIndexB;
  130. c->m_worldPosB[0] = pOnB1;
  131. int numPoints = 1;
  132. c->m_worldNormalOnB.w = (b3Scalar)numPoints;
  133. } //if (dstIdx < numPairs)
  134. }
  135. } //if (hasCollision)
  136. }
  137. #endif //B3_CONTACT_SPHERE_SPHERE_H