b3ReduceContacts.h 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. #ifndef B3_REDUCE_CONTACTS_H
  2. #define B3_REDUCE_CONTACTS_H
  3. inline int b3ReduceContacts(const b3Float4* p, int nPoints, const b3Float4& nearNormal, b3Int4* contactIdx)
  4. {
  5. if( nPoints == 0 )
  6. return 0;
  7. if (nPoints <=4)
  8. return nPoints;
  9. if (nPoints >64)
  10. nPoints = 64;
  11. b3Float4 center = b3MakeFloat4(0,0,0,0);
  12. {
  13. for (int i=0;i<nPoints;i++)
  14. center += p[i];
  15. center /= (float)nPoints;
  16. }
  17. // sample 4 directions
  18. b3Float4 aVector = p[0] - center;
  19. b3Float4 u = b3Cross3( nearNormal, aVector );
  20. b3Float4 v = b3Cross3( nearNormal, u );
  21. u = b3FastNormalized3( u );
  22. v = b3FastNormalized3( v );
  23. //keep point with deepest penetration
  24. float minW= FLT_MAX;
  25. int minIndex=-1;
  26. b3Float4 maxDots;
  27. maxDots.x = FLT_MIN;
  28. maxDots.y = FLT_MIN;
  29. maxDots.z = FLT_MIN;
  30. maxDots.w = FLT_MIN;
  31. // idx, distance
  32. for(int ie = 0; ie<nPoints; ie++ )
  33. {
  34. if (p[ie].w<minW)
  35. {
  36. minW = p[ie].w;
  37. minIndex=ie;
  38. }
  39. float f;
  40. b3Float4 r = p[ie]-center;
  41. f = b3Dot3F4( u, r );
  42. if (f<maxDots.x)
  43. {
  44. maxDots.x = f;
  45. contactIdx[0].x = ie;
  46. }
  47. f = b3Dot3F4( -u, r );
  48. if (f<maxDots.y)
  49. {
  50. maxDots.y = f;
  51. contactIdx[0].y = ie;
  52. }
  53. f = b3Dot3F4( v, r );
  54. if (f<maxDots.z)
  55. {
  56. maxDots.z = f;
  57. contactIdx[0].z = ie;
  58. }
  59. f = b3Dot3F4( -v, r );
  60. if (f<maxDots.w)
  61. {
  62. maxDots.w = f;
  63. contactIdx[0].w = ie;
  64. }
  65. }
  66. if (contactIdx[0].x != minIndex && contactIdx[0].y != minIndex && contactIdx[0].z != minIndex && contactIdx[0].w != minIndex)
  67. {
  68. //replace the first contact with minimum (todo: replace contact with least penetration)
  69. contactIdx[0].x = minIndex;
  70. }
  71. return 4;
  72. }
  73. #endif //B3_REDUCE_CONTACTS_H