2
0

b3ContactSphereSphere.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  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. } else
  70. {
  71. b3Vector3 tmp = spherePos-out;
  72. b3Scalar l2 = tmp.length2();
  73. if (l2<radius*radius)
  74. {
  75. dist = b3Sqrt(l2);
  76. if (dist>minDist)
  77. {
  78. minDist = dist;
  79. closestPnt = out;
  80. localHitNormal = tmp/dist;
  81. region=2;
  82. }
  83. } else
  84. {
  85. bCollide = false;
  86. break;
  87. }
  88. }
  89. }
  90. else
  91. {
  92. if ( dist > minDist )
  93. {
  94. minDist = dist;
  95. closestPnt = pntReturn;
  96. localHitNormal = planeEqn;
  97. region=3;
  98. }
  99. }
  100. }
  101. static int numChecks = 0;
  102. numChecks++;
  103. if (bCollide && minDist > -10000)
  104. {
  105. float4 normalOnSurfaceB1 = tr.getBasis()*localHitNormal;//-hitNormalWorld;
  106. float4 pOnB1 = tr(closestPnt);
  107. //printf("dist ,%f,",minDist);
  108. float actualDepth = minDist-radius;
  109. if (actualDepth<0)
  110. {
  111. //printf("actualDepth = ,%f,", actualDepth);
  112. //printf("normalOnSurfaceB1 = ,%f,%f,%f,", normalOnSurfaceB1.x,normalOnSurfaceB1.y,normalOnSurfaceB1.z);
  113. //printf("region=,%d,\n", region);
  114. pOnB1[3] = actualDepth;
  115. int dstIdx;
  116. // dstIdx = nGlobalContactsOut++;//AppendInc( nGlobalContactsOut, dstIdx );
  117. if (nGlobalContactsOut < maxContactCapacity)
  118. {
  119. dstIdx=nGlobalContactsOut;
  120. nGlobalContactsOut++;
  121. b3Contact4* c = &globalContactsOut[dstIdx];
  122. c->m_worldNormalOnB = normalOnSurfaceB1;
  123. c->setFrictionCoeff(0.7);
  124. c->setRestituitionCoeff(0.f);
  125. c->m_batchIdx = pairIndex;
  126. c->m_bodyAPtrAndSignBit = rigidBodies[bodyIndexA].m_invMass==0?-bodyIndexA:bodyIndexA;
  127. c->m_bodyBPtrAndSignBit = rigidBodies[bodyIndexB].m_invMass==0?-bodyIndexB:bodyIndexB;
  128. c->m_worldPosB[0] = pOnB1;
  129. int numPoints = 1;
  130. c->m_worldNormalOnB.w = (b3Scalar)numPoints;
  131. }//if (dstIdx < numPairs)
  132. }
  133. }//if (hasCollision)
  134. }
  135. #endif //B3_CONTACT_SPHERE_SPHERE_H