b3NewContactReduction.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. #ifndef B3_NEW_CONTACT_REDUCTION_H
  2. #define B3_NEW_CONTACT_REDUCTION_H
  3. #include "Bullet3Common/shared/b3Float4.h"
  4. #include "Bullet3Collision/NarrowPhaseCollision/shared/b3RigidBodyData.h"
  5. #include "Bullet3Collision/NarrowPhaseCollision/shared/b3Contact4Data.h"
  6. #define GET_NPOINTS(x) (x).m_worldNormalOnB.w
  7. int b3ExtractManifoldSequentialGlobal(__global const b3Float4* p, int nPoints, b3Float4ConstArg nearNormal, b3Int4* contactIdx)
  8. {
  9. if( nPoints == 0 )
  10. return 0;
  11. if (nPoints <=4)
  12. return nPoints;
  13. if (nPoints >64)
  14. nPoints = 64;
  15. b3Float4 center = b3MakeFloat4(0,0,0,0);
  16. {
  17. for (int i=0;i<nPoints;i++)
  18. center += p[i];
  19. center /= (float)nPoints;
  20. }
  21. // sample 4 directions
  22. b3Float4 aVector = p[0] - center;
  23. b3Float4 u = b3Cross( nearNormal, aVector );
  24. b3Float4 v = b3Cross( nearNormal, u );
  25. u = b3Normalized( u );
  26. v = b3Normalized( v );
  27. //keep point with deepest penetration
  28. float minW= FLT_MAX;
  29. int minIndex=-1;
  30. b3Float4 maxDots;
  31. maxDots.x = FLT_MIN;
  32. maxDots.y = FLT_MIN;
  33. maxDots.z = FLT_MIN;
  34. maxDots.w = FLT_MIN;
  35. // idx, distance
  36. for(int ie = 0; ie<nPoints; ie++ )
  37. {
  38. if (p[ie].w<minW)
  39. {
  40. minW = p[ie].w;
  41. minIndex=ie;
  42. }
  43. float f;
  44. b3Float4 r = p[ie]-center;
  45. f = b3Dot( u, r );
  46. if (f<maxDots.x)
  47. {
  48. maxDots.x = f;
  49. contactIdx[0].x = ie;
  50. }
  51. f = b3Dot( -u, r );
  52. if (f<maxDots.y)
  53. {
  54. maxDots.y = f;
  55. contactIdx[0].y = ie;
  56. }
  57. f = b3Dot( v, r );
  58. if (f<maxDots.z)
  59. {
  60. maxDots.z = f;
  61. contactIdx[0].z = ie;
  62. }
  63. f = b3Dot( -v, r );
  64. if (f<maxDots.w)
  65. {
  66. maxDots.w = f;
  67. contactIdx[0].w = ie;
  68. }
  69. }
  70. if (contactIdx[0].x != minIndex && contactIdx[0].y != minIndex && contactIdx[0].z != minIndex && contactIdx[0].w != minIndex)
  71. {
  72. //replace the first contact with minimum (todo: replace contact with least penetration)
  73. contactIdx[0].x = minIndex;
  74. }
  75. return 4;
  76. }
  77. __kernel void b3NewContactReductionKernel( __global b3Int4* pairs,
  78. __global const b3RigidBodyData_t* rigidBodies,
  79. __global const b3Float4* separatingNormals,
  80. __global const int* hasSeparatingAxis,
  81. __global struct b3Contact4Data* globalContactsOut,
  82. __global b3Int4* clippingFaces,
  83. __global b3Float4* worldVertsB2,
  84. volatile __global int* nGlobalContactsOut,
  85. int vertexFaceCapacity,
  86. int contactCapacity,
  87. int numPairs,
  88. int pairIndex
  89. )
  90. {
  91. // int i = get_global_id(0);
  92. //int pairIndex = i;
  93. int i = pairIndex;
  94. b3Int4 contactIdx;
  95. contactIdx=b3MakeInt4(0,1,2,3);
  96. if (i<numPairs)
  97. {
  98. if (hasSeparatingAxis[i])
  99. {
  100. int nPoints = clippingFaces[pairIndex].w;
  101. if (nPoints>0)
  102. {
  103. __global b3Float4* pointsIn = &worldVertsB2[pairIndex*vertexFaceCapacity];
  104. b3Float4 normal = -separatingNormals[i];
  105. int nReducedContacts = b3ExtractManifoldSequentialGlobal(pointsIn, nPoints, normal, &contactIdx);
  106. int dstIdx;
  107. dstIdx = b3AtomicInc( nGlobalContactsOut);
  108. //#if 0
  109. b3Assert(dstIdx < contactCapacity);
  110. if (dstIdx < contactCapacity)
  111. {
  112. __global struct b3Contact4Data* c = &globalContactsOut[dstIdx];
  113. c->m_worldNormalOnB = -normal;
  114. c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff);
  115. c->m_batchIdx = pairIndex;
  116. int bodyA = pairs[pairIndex].x;
  117. int bodyB = pairs[pairIndex].y;
  118. pairs[pairIndex].w = dstIdx;
  119. c->m_bodyAPtrAndSignBit = rigidBodies[bodyA].m_invMass==0?-bodyA:bodyA;
  120. c->m_bodyBPtrAndSignBit = rigidBodies[bodyB].m_invMass==0?-bodyB:bodyB;
  121. c->m_childIndexA =-1;
  122. c->m_childIndexB =-1;
  123. switch (nReducedContacts)
  124. {
  125. case 4:
  126. c->m_worldPosB[3] = pointsIn[contactIdx.w];
  127. case 3:
  128. c->m_worldPosB[2] = pointsIn[contactIdx.z];
  129. case 2:
  130. c->m_worldPosB[1] = pointsIn[contactIdx.y];
  131. case 1:
  132. c->m_worldPosB[0] = pointsIn[contactIdx.x];
  133. default:
  134. {
  135. }
  136. };
  137. GET_NPOINTS(*c) = nReducedContacts;
  138. }
  139. //#endif
  140. }// if (numContactsOut>0)
  141. }// if (hasSeparatingAxis[i])
  142. }// if (i<numPairs)
  143. }
  144. #endif