b3ReduceContacts.h 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  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