satClipHullContacts.cl 55 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888
  1. #define TRIANGLE_NUM_CONVEX_FACES 5
  2. #pragma OPENCL EXTENSION cl_amd_printf : enable
  3. #pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable
  4. #pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable
  5. #pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics : enable
  6. #pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable
  7. #ifdef cl_ext_atomic_counters_32
  8. #pragma OPENCL EXTENSION cl_ext_atomic_counters_32 : enable
  9. #else
  10. #define counter32_t volatile __global int*
  11. #endif
  12. #define GET_GROUP_IDX get_group_id(0)
  13. #define GET_LOCAL_IDX get_local_id(0)
  14. #define GET_GLOBAL_IDX get_global_id(0)
  15. #define GET_GROUP_SIZE get_local_size(0)
  16. #define GET_NUM_GROUPS get_num_groups(0)
  17. #define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)
  18. #define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE)
  19. #define AtomInc(x) atom_inc(&(x))
  20. #define AtomInc1(x, out) out = atom_inc(&(x))
  21. #define AppendInc(x, out) out = atomic_inc(x)
  22. #define AtomAdd(x, value) atom_add(&(x), value)
  23. #define AtomCmpxhg(x, cmp, value) atom_cmpxchg( &(x), cmp, value )
  24. #define AtomXhg(x, value) atom_xchg ( &(x), value )
  25. #define max2 max
  26. #define min2 min
  27. typedef unsigned int u32;
  28. #include "Bullet3Collision/NarrowPhaseCollision/shared/b3Contact4Data.h"
  29. #include "Bullet3Collision/NarrowPhaseCollision/shared/b3ConvexPolyhedronData.h"
  30. #include "Bullet3Collision/NarrowPhaseCollision/shared/b3Collidable.h"
  31. #include "Bullet3Collision/NarrowPhaseCollision/shared/b3RigidBodyData.h"
  32. #define GET_NPOINTS(x) (x).m_worldNormalOnB.w
  33. #define SELECT_UINT4( b, a, condition ) select( b,a,condition )
  34. #define make_float4 (float4)
  35. #define make_float2 (float2)
  36. #define make_uint4 (uint4)
  37. #define make_int4 (int4)
  38. #define make_uint2 (uint2)
  39. #define make_int2 (int2)
  40. __inline
  41. float fastDiv(float numerator, float denominator)
  42. {
  43. return native_divide(numerator, denominator);
  44. // return numerator/denominator;
  45. }
  46. __inline
  47. float4 fastDiv4(float4 numerator, float4 denominator)
  48. {
  49. return native_divide(numerator, denominator);
  50. }
  51. __inline
  52. float4 cross3(float4 a, float4 b)
  53. {
  54. return cross(a,b);
  55. }
  56. //#define dot3F4 dot
  57. __inline
  58. float dot3F4(float4 a, float4 b)
  59. {
  60. float4 a1 = make_float4(a.xyz,0.f);
  61. float4 b1 = make_float4(b.xyz,0.f);
  62. return dot(a1, b1);
  63. }
  64. __inline
  65. float4 fastNormalize4(float4 v)
  66. {
  67. return fast_normalize(v);
  68. }
  69. ///////////////////////////////////////
  70. // Quaternion
  71. ///////////////////////////////////////
  72. typedef float4 Quaternion;
  73. __inline
  74. Quaternion qtMul(Quaternion a, Quaternion b);
  75. __inline
  76. Quaternion qtNormalize(Quaternion in);
  77. __inline
  78. float4 qtRotate(Quaternion q, float4 vec);
  79. __inline
  80. Quaternion qtInvert(Quaternion q);
  81. __inline
  82. Quaternion qtMul(Quaternion a, Quaternion b)
  83. {
  84. Quaternion ans;
  85. ans = cross3( a, b );
  86. ans += a.w*b+b.w*a;
  87. // ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);
  88. ans.w = a.w*b.w - dot3F4(a, b);
  89. return ans;
  90. }
  91. __inline
  92. Quaternion qtNormalize(Quaternion in)
  93. {
  94. return fastNormalize4(in);
  95. // in /= length( in );
  96. // return in;
  97. }
  98. __inline
  99. float4 qtRotate(Quaternion q, float4 vec)
  100. {
  101. Quaternion qInv = qtInvert( q );
  102. float4 vcpy = vec;
  103. vcpy.w = 0.f;
  104. float4 out = qtMul(qtMul(q,vcpy),qInv);
  105. return out;
  106. }
  107. __inline
  108. Quaternion qtInvert(Quaternion q)
  109. {
  110. return (Quaternion)(-q.xyz, q.w);
  111. }
  112. __inline
  113. float4 qtInvRotate(const Quaternion q, float4 vec)
  114. {
  115. return qtRotate( qtInvert( q ), vec );
  116. }
  117. __inline
  118. float4 transform(const float4* p, const float4* translation, const Quaternion* orientation)
  119. {
  120. return qtRotate( *orientation, *p ) + (*translation);
  121. }
  122. __inline
  123. float4 normalize3(const float4 a)
  124. {
  125. float4 n = make_float4(a.x, a.y, a.z, 0.f);
  126. return fastNormalize4( n );
  127. }
  128. __inline float4 lerp3(const float4 a,const float4 b, float t)
  129. {
  130. return make_float4( a.x + (b.x - a.x) * t,
  131. a.y + (b.y - a.y) * t,
  132. a.z + (b.z - a.z) * t,
  133. 0.f);
  134. }
  135. // Clips a face to the back of a plane, return the number of vertices out, stored in ppVtxOut
  136. int clipFaceGlobal(__global const float4* pVtxIn, int numVertsIn, float4 planeNormalWS,float planeEqWS, __global float4* ppVtxOut)
  137. {
  138. int ve;
  139. float ds, de;
  140. int numVertsOut = 0;
  141. //double-check next test
  142. if (numVertsIn < 2)
  143. return 0;
  144. float4 firstVertex=pVtxIn[numVertsIn-1];
  145. float4 endVertex = pVtxIn[0];
  146. ds = dot3F4(planeNormalWS,firstVertex)+planeEqWS;
  147. for (ve = 0; ve < numVertsIn; ve++)
  148. {
  149. endVertex=pVtxIn[ve];
  150. de = dot3F4(planeNormalWS,endVertex)+planeEqWS;
  151. if (ds<0)
  152. {
  153. if (de<0)
  154. {
  155. // Start < 0, end < 0, so output endVertex
  156. ppVtxOut[numVertsOut++] = endVertex;
  157. }
  158. else
  159. {
  160. // Start < 0, end >= 0, so output intersection
  161. ppVtxOut[numVertsOut++] = lerp3(firstVertex, endVertex,(ds * 1.f/(ds - de)) );
  162. }
  163. }
  164. else
  165. {
  166. if (de<0)
  167. {
  168. // Start >= 0, end < 0 so output intersection and end
  169. ppVtxOut[numVertsOut++] = lerp3(firstVertex, endVertex,(ds * 1.f/(ds - de)) );
  170. ppVtxOut[numVertsOut++] = endVertex;
  171. }
  172. }
  173. firstVertex = endVertex;
  174. ds = de;
  175. }
  176. return numVertsOut;
  177. }
  178. // Clips a face to the back of a plane, return the number of vertices out, stored in ppVtxOut
  179. int clipFace(const float4* pVtxIn, int numVertsIn, float4 planeNormalWS,float planeEqWS, float4* ppVtxOut)
  180. {
  181. int ve;
  182. float ds, de;
  183. int numVertsOut = 0;
  184. //double-check next test
  185. if (numVertsIn < 2)
  186. return 0;
  187. float4 firstVertex=pVtxIn[numVertsIn-1];
  188. float4 endVertex = pVtxIn[0];
  189. ds = dot3F4(planeNormalWS,firstVertex)+planeEqWS;
  190. for (ve = 0; ve < numVertsIn; ve++)
  191. {
  192. endVertex=pVtxIn[ve];
  193. de = dot3F4(planeNormalWS,endVertex)+planeEqWS;
  194. if (ds<0)
  195. {
  196. if (de<0)
  197. {
  198. // Start < 0, end < 0, so output endVertex
  199. ppVtxOut[numVertsOut++] = endVertex;
  200. }
  201. else
  202. {
  203. // Start < 0, end >= 0, so output intersection
  204. ppVtxOut[numVertsOut++] = lerp3(firstVertex, endVertex,(ds * 1.f/(ds - de)) );
  205. }
  206. }
  207. else
  208. {
  209. if (de<0)
  210. {
  211. // Start >= 0, end < 0 so output intersection and end
  212. ppVtxOut[numVertsOut++] = lerp3(firstVertex, endVertex,(ds * 1.f/(ds - de)) );
  213. ppVtxOut[numVertsOut++] = endVertex;
  214. }
  215. }
  216. firstVertex = endVertex;
  217. ds = de;
  218. }
  219. return numVertsOut;
  220. }
  221. int clipFaceAgainstHull(const float4 separatingNormal, __global const b3ConvexPolyhedronData_t* hullA,
  222. const float4 posA, const Quaternion ornA, float4* worldVertsB1, int numWorldVertsB1,
  223. float4* worldVertsB2, int capacityWorldVertsB2,
  224. const float minDist, float maxDist,
  225. __global const float4* vertices,
  226. __global const b3GpuFace_t* faces,
  227. __global const int* indices,
  228. float4* contactsOut,
  229. int contactCapacity)
  230. {
  231. int numContactsOut = 0;
  232. float4* pVtxIn = worldVertsB1;
  233. float4* pVtxOut = worldVertsB2;
  234. int numVertsIn = numWorldVertsB1;
  235. int numVertsOut = 0;
  236. int closestFaceA=-1;
  237. {
  238. float dmin = FLT_MAX;
  239. for(int face=0;face<hullA->m_numFaces;face++)
  240. {
  241. const float4 Normal = make_float4(
  242. faces[hullA->m_faceOffset+face].m_plane.x,
  243. faces[hullA->m_faceOffset+face].m_plane.y,
  244. faces[hullA->m_faceOffset+face].m_plane.z,0.f);
  245. const float4 faceANormalWS = qtRotate(ornA,Normal);
  246. float d = dot3F4(faceANormalWS,separatingNormal);
  247. if (d < dmin)
  248. {
  249. dmin = d;
  250. closestFaceA = face;
  251. }
  252. }
  253. }
  254. if (closestFaceA<0)
  255. return numContactsOut;
  256. b3GpuFace_t polyA = faces[hullA->m_faceOffset+closestFaceA];
  257. // clip polygon to back of planes of all faces of hull A that are adjacent to witness face
  258. int numVerticesA = polyA.m_numIndices;
  259. for(int e0=0;e0<numVerticesA;e0++)
  260. {
  261. const float4 a = vertices[hullA->m_vertexOffset+indices[polyA.m_indexOffset+e0]];
  262. const float4 b = vertices[hullA->m_vertexOffset+indices[polyA.m_indexOffset+((e0+1)%numVerticesA)]];
  263. const float4 edge0 = a - b;
  264. const float4 WorldEdge0 = qtRotate(ornA,edge0);
  265. float4 planeNormalA = make_float4(polyA.m_plane.x,polyA.m_plane.y,polyA.m_plane.z,0.f);
  266. float4 worldPlaneAnormal1 = qtRotate(ornA,planeNormalA);
  267. float4 planeNormalWS1 = -cross3(WorldEdge0,worldPlaneAnormal1);
  268. float4 worldA1 = transform(&a,&posA,&ornA);
  269. float planeEqWS1 = -dot3F4(worldA1,planeNormalWS1);
  270. float4 planeNormalWS = planeNormalWS1;
  271. float planeEqWS=planeEqWS1;
  272. //clip face
  273. //clipFace(*pVtxIn, *pVtxOut,planeNormalWS,planeEqWS);
  274. numVertsOut = clipFace(pVtxIn, numVertsIn, planeNormalWS,planeEqWS, pVtxOut);
  275. //btSwap(pVtxIn,pVtxOut);
  276. float4* tmp = pVtxOut;
  277. pVtxOut = pVtxIn;
  278. pVtxIn = tmp;
  279. numVertsIn = numVertsOut;
  280. numVertsOut = 0;
  281. }
  282. // only keep points that are behind the witness face
  283. {
  284. float4 localPlaneNormal = make_float4(polyA.m_plane.x,polyA.m_plane.y,polyA.m_plane.z,0.f);
  285. float localPlaneEq = polyA.m_plane.w;
  286. float4 planeNormalWS = qtRotate(ornA,localPlaneNormal);
  287. float planeEqWS=localPlaneEq-dot3F4(planeNormalWS,posA);
  288. for (int i=0;i<numVertsIn;i++)
  289. {
  290. float depth = dot3F4(planeNormalWS,pVtxIn[i])+planeEqWS;
  291. if (depth <=minDist)
  292. {
  293. depth = minDist;
  294. }
  295. if (depth <=maxDist)
  296. {
  297. float4 pointInWorld = pVtxIn[i];
  298. //resultOut.addContactPoint(separatingNormal,point,depth);
  299. contactsOut[numContactsOut++] = make_float4(pointInWorld.x,pointInWorld.y,pointInWorld.z,depth);
  300. }
  301. }
  302. }
  303. return numContactsOut;
  304. }
  305. int clipFaceAgainstHullLocalA(const float4 separatingNormal, const b3ConvexPolyhedronData_t* hullA,
  306. const float4 posA, const Quaternion ornA, float4* worldVertsB1, int numWorldVertsB1,
  307. float4* worldVertsB2, int capacityWorldVertsB2,
  308. const float minDist, float maxDist,
  309. const float4* verticesA,
  310. const b3GpuFace_t* facesA,
  311. const int* indicesA,
  312. __global const float4* verticesB,
  313. __global const b3GpuFace_t* facesB,
  314. __global const int* indicesB,
  315. float4* contactsOut,
  316. int contactCapacity)
  317. {
  318. int numContactsOut = 0;
  319. float4* pVtxIn = worldVertsB1;
  320. float4* pVtxOut = worldVertsB2;
  321. int numVertsIn = numWorldVertsB1;
  322. int numVertsOut = 0;
  323. int closestFaceA=-1;
  324. {
  325. float dmin = FLT_MAX;
  326. for(int face=0;face<hullA->m_numFaces;face++)
  327. {
  328. const float4 Normal = make_float4(
  329. facesA[hullA->m_faceOffset+face].m_plane.x,
  330. facesA[hullA->m_faceOffset+face].m_plane.y,
  331. facesA[hullA->m_faceOffset+face].m_plane.z,0.f);
  332. const float4 faceANormalWS = qtRotate(ornA,Normal);
  333. float d = dot3F4(faceANormalWS,separatingNormal);
  334. if (d < dmin)
  335. {
  336. dmin = d;
  337. closestFaceA = face;
  338. }
  339. }
  340. }
  341. if (closestFaceA<0)
  342. return numContactsOut;
  343. b3GpuFace_t polyA = facesA[hullA->m_faceOffset+closestFaceA];
  344. // clip polygon to back of planes of all faces of hull A that are adjacent to witness face
  345. int numVerticesA = polyA.m_numIndices;
  346. for(int e0=0;e0<numVerticesA;e0++)
  347. {
  348. const float4 a = verticesA[hullA->m_vertexOffset+indicesA[polyA.m_indexOffset+e0]];
  349. const float4 b = verticesA[hullA->m_vertexOffset+indicesA[polyA.m_indexOffset+((e0+1)%numVerticesA)]];
  350. const float4 edge0 = a - b;
  351. const float4 WorldEdge0 = qtRotate(ornA,edge0);
  352. float4 planeNormalA = make_float4(polyA.m_plane.x,polyA.m_plane.y,polyA.m_plane.z,0.f);
  353. float4 worldPlaneAnormal1 = qtRotate(ornA,planeNormalA);
  354. float4 planeNormalWS1 = -cross3(WorldEdge0,worldPlaneAnormal1);
  355. float4 worldA1 = transform(&a,&posA,&ornA);
  356. float planeEqWS1 = -dot3F4(worldA1,planeNormalWS1);
  357. float4 planeNormalWS = planeNormalWS1;
  358. float planeEqWS=planeEqWS1;
  359. //clip face
  360. //clipFace(*pVtxIn, *pVtxOut,planeNormalWS,planeEqWS);
  361. numVertsOut = clipFace(pVtxIn, numVertsIn, planeNormalWS,planeEqWS, pVtxOut);
  362. //btSwap(pVtxIn,pVtxOut);
  363. float4* tmp = pVtxOut;
  364. pVtxOut = pVtxIn;
  365. pVtxIn = tmp;
  366. numVertsIn = numVertsOut;
  367. numVertsOut = 0;
  368. }
  369. // only keep points that are behind the witness face
  370. {
  371. float4 localPlaneNormal = make_float4(polyA.m_plane.x,polyA.m_plane.y,polyA.m_plane.z,0.f);
  372. float localPlaneEq = polyA.m_plane.w;
  373. float4 planeNormalWS = qtRotate(ornA,localPlaneNormal);
  374. float planeEqWS=localPlaneEq-dot3F4(planeNormalWS,posA);
  375. for (int i=0;i<numVertsIn;i++)
  376. {
  377. float depth = dot3F4(planeNormalWS,pVtxIn[i])+planeEqWS;
  378. if (depth <=minDist)
  379. {
  380. depth = minDist;
  381. }
  382. if (depth <=maxDist)
  383. {
  384. float4 pointInWorld = pVtxIn[i];
  385. //resultOut.addContactPoint(separatingNormal,point,depth);
  386. contactsOut[numContactsOut++] = make_float4(pointInWorld.x,pointInWorld.y,pointInWorld.z,depth);
  387. }
  388. }
  389. }
  390. return numContactsOut;
  391. }
  392. int clipHullAgainstHull(const float4 separatingNormal,
  393. __global const b3ConvexPolyhedronData_t* hullA, __global const b3ConvexPolyhedronData_t* hullB,
  394. const float4 posA, const Quaternion ornA,const float4 posB, const Quaternion ornB,
  395. float4* worldVertsB1, float4* worldVertsB2, int capacityWorldVerts,
  396. const float minDist, float maxDist,
  397. __global const float4* vertices,
  398. __global const b3GpuFace_t* faces,
  399. __global const int* indices,
  400. float4* localContactsOut,
  401. int localContactCapacity)
  402. {
  403. int numContactsOut = 0;
  404. int numWorldVertsB1= 0;
  405. int closestFaceB=-1;
  406. float dmax = -FLT_MAX;
  407. {
  408. for(int face=0;face<hullB->m_numFaces;face++)
  409. {
  410. const float4 Normal = make_float4(faces[hullB->m_faceOffset+face].m_plane.x,
  411. faces[hullB->m_faceOffset+face].m_plane.y, faces[hullB->m_faceOffset+face].m_plane.z,0.f);
  412. const float4 WorldNormal = qtRotate(ornB, Normal);
  413. float d = dot3F4(WorldNormal,separatingNormal);
  414. if (d > dmax)
  415. {
  416. dmax = d;
  417. closestFaceB = face;
  418. }
  419. }
  420. }
  421. {
  422. const b3GpuFace_t polyB = faces[hullB->m_faceOffset+closestFaceB];
  423. const int numVertices = polyB.m_numIndices;
  424. for(int e0=0;e0<numVertices;e0++)
  425. {
  426. const float4 b = vertices[hullB->m_vertexOffset+indices[polyB.m_indexOffset+e0]];
  427. worldVertsB1[numWorldVertsB1++] = transform(&b,&posB,&ornB);
  428. }
  429. }
  430. if (closestFaceB>=0)
  431. {
  432. numContactsOut = clipFaceAgainstHull(separatingNormal, hullA,
  433. posA,ornA,
  434. worldVertsB1,numWorldVertsB1,worldVertsB2,capacityWorldVerts, minDist, maxDist,vertices,
  435. faces,
  436. indices,localContactsOut,localContactCapacity);
  437. }
  438. return numContactsOut;
  439. }
  440. int clipHullAgainstHullLocalA(const float4 separatingNormal,
  441. const b3ConvexPolyhedronData_t* hullA, __global const b3ConvexPolyhedronData_t* hullB,
  442. const float4 posA, const Quaternion ornA,const float4 posB, const Quaternion ornB,
  443. float4* worldVertsB1, float4* worldVertsB2, int capacityWorldVerts,
  444. const float minDist, float maxDist,
  445. const float4* verticesA,
  446. const b3GpuFace_t* facesA,
  447. const int* indicesA,
  448. __global const float4* verticesB,
  449. __global const b3GpuFace_t* facesB,
  450. __global const int* indicesB,
  451. float4* localContactsOut,
  452. int localContactCapacity)
  453. {
  454. int numContactsOut = 0;
  455. int numWorldVertsB1= 0;
  456. int closestFaceB=-1;
  457. float dmax = -FLT_MAX;
  458. {
  459. for(int face=0;face<hullB->m_numFaces;face++)
  460. {
  461. const float4 Normal = make_float4(facesB[hullB->m_faceOffset+face].m_plane.x,
  462. facesB[hullB->m_faceOffset+face].m_plane.y, facesB[hullB->m_faceOffset+face].m_plane.z,0.f);
  463. const float4 WorldNormal = qtRotate(ornB, Normal);
  464. float d = dot3F4(WorldNormal,separatingNormal);
  465. if (d > dmax)
  466. {
  467. dmax = d;
  468. closestFaceB = face;
  469. }
  470. }
  471. }
  472. {
  473. const b3GpuFace_t polyB = facesB[hullB->m_faceOffset+closestFaceB];
  474. const int numVertices = polyB.m_numIndices;
  475. for(int e0=0;e0<numVertices;e0++)
  476. {
  477. const float4 b = verticesB[hullB->m_vertexOffset+indicesB[polyB.m_indexOffset+e0]];
  478. worldVertsB1[numWorldVertsB1++] = transform(&b,&posB,&ornB);
  479. }
  480. }
  481. if (closestFaceB>=0)
  482. {
  483. numContactsOut = clipFaceAgainstHullLocalA(separatingNormal, hullA,
  484. posA,ornA,
  485. worldVertsB1,numWorldVertsB1,worldVertsB2,capacityWorldVerts, minDist, maxDist,
  486. verticesA,facesA,indicesA,
  487. verticesB,facesB,indicesB,
  488. localContactsOut,localContactCapacity);
  489. }
  490. return numContactsOut;
  491. }
  492. #define PARALLEL_SUM(v, n) for(int j=1; j<n; j++) v[0] += v[j];
  493. #define PARALLEL_DO(execution, n) for(int ie=0; ie<n; ie++){execution;}
  494. #define REDUCE_MAX(v, n) {int i=0;\
  495. for(int offset=0; offset<n; offset++) v[i] = (v[i].y > v[i+offset].y)? v[i]: v[i+offset]; }
  496. #define REDUCE_MIN(v, n) {int i=0;\
  497. for(int offset=0; offset<n; offset++) v[i] = (v[i].y < v[i+offset].y)? v[i]: v[i+offset]; }
  498. int extractManifoldSequentialGlobal(__global const float4* p, int nPoints, float4 nearNormal, int4* contactIdx)
  499. {
  500. if( nPoints == 0 )
  501. return 0;
  502. if (nPoints <=4)
  503. return nPoints;
  504. if (nPoints >64)
  505. nPoints = 64;
  506. float4 center = make_float4(0.f);
  507. {
  508. for (int i=0;i<nPoints;i++)
  509. center += p[i];
  510. center /= (float)nPoints;
  511. }
  512. // sample 4 directions
  513. float4 aVector = p[0] - center;
  514. float4 u = cross3( nearNormal, aVector );
  515. float4 v = cross3( nearNormal, u );
  516. u = normalize3( u );
  517. v = normalize3( v );
  518. //keep point with deepest penetration
  519. float minW= FLT_MAX;
  520. int minIndex=-1;
  521. float4 maxDots;
  522. maxDots.x = FLT_MIN;
  523. maxDots.y = FLT_MIN;
  524. maxDots.z = FLT_MIN;
  525. maxDots.w = FLT_MIN;
  526. // idx, distance
  527. for(int ie = 0; ie<nPoints; ie++ )
  528. {
  529. if (p[ie].w<minW)
  530. {
  531. minW = p[ie].w;
  532. minIndex=ie;
  533. }
  534. float f;
  535. float4 r = p[ie]-center;
  536. f = dot3F4( u, r );
  537. if (f<maxDots.x)
  538. {
  539. maxDots.x = f;
  540. contactIdx[0].x = ie;
  541. }
  542. f = dot3F4( -u, r );
  543. if (f<maxDots.y)
  544. {
  545. maxDots.y = f;
  546. contactIdx[0].y = ie;
  547. }
  548. f = dot3F4( v, r );
  549. if (f<maxDots.z)
  550. {
  551. maxDots.z = f;
  552. contactIdx[0].z = ie;
  553. }
  554. f = dot3F4( -v, r );
  555. if (f<maxDots.w)
  556. {
  557. maxDots.w = f;
  558. contactIdx[0].w = ie;
  559. }
  560. }
  561. if (contactIdx[0].x != minIndex && contactIdx[0].y != minIndex && contactIdx[0].z != minIndex && contactIdx[0].w != minIndex)
  562. {
  563. //replace the first contact with minimum (todo: replace contact with least penetration)
  564. contactIdx[0].x = minIndex;
  565. }
  566. return 4;
  567. }
  568. int extractManifoldSequentialGlobalFake(__global const float4* p, int nPoints, float4 nearNormal, int* contactIdx)
  569. {
  570. contactIdx[0] = 0;
  571. contactIdx[1] = 1;
  572. contactIdx[2] = 2;
  573. contactIdx[3] = 3;
  574. if( nPoints == 0 ) return 0;
  575. nPoints = min2( nPoints, 4 );
  576. return nPoints;
  577. }
  578. int extractManifoldSequential(const float4* p, int nPoints, float4 nearNormal, int* contactIdx)
  579. {
  580. if( nPoints == 0 ) return 0;
  581. nPoints = min2( nPoints, 64 );
  582. float4 center = make_float4(0.f);
  583. {
  584. float4 v[64];
  585. for (int i=0;i<nPoints;i++)
  586. v[i] = p[i];
  587. //memcpy( v, p, nPoints*sizeof(float4) );
  588. PARALLEL_SUM( v, nPoints );
  589. center = v[0]/(float)nPoints;
  590. }
  591. { // sample 4 directions
  592. if( nPoints < 4 )
  593. {
  594. for(int i=0; i<nPoints; i++)
  595. contactIdx[i] = i;
  596. return nPoints;
  597. }
  598. float4 aVector = p[0] - center;
  599. float4 u = cross3( nearNormal, aVector );
  600. float4 v = cross3( nearNormal, u );
  601. u = normalize3( u );
  602. v = normalize3( v );
  603. int idx[4];
  604. float2 max00 = make_float2(0,FLT_MAX);
  605. {
  606. // idx, distance
  607. {
  608. {
  609. int4 a[64];
  610. for(int ie = 0; ie<nPoints; ie++ )
  611. {
  612. float f;
  613. float4 r = p[ie]-center;
  614. f = dot3F4( u, r );
  615. a[ie].x = ((*(u32*)&f) & 0xffffff00) | (0xff & ie);
  616. f = dot3F4( -u, r );
  617. a[ie].y = ((*(u32*)&f) & 0xffffff00) | (0xff & ie);
  618. f = dot3F4( v, r );
  619. a[ie].z = ((*(u32*)&f) & 0xffffff00) | (0xff & ie);
  620. f = dot3F4( -v, r );
  621. a[ie].w = ((*(u32*)&f) & 0xffffff00) | (0xff & ie);
  622. }
  623. for(int ie=0; ie<nPoints; ie++)
  624. {
  625. a[0].x = (a[0].x > a[ie].x )? a[0].x: a[ie].x;
  626. a[0].y = (a[0].y > a[ie].y )? a[0].y: a[ie].y;
  627. a[0].z = (a[0].z > a[ie].z )? a[0].z: a[ie].z;
  628. a[0].w = (a[0].w > a[ie].w )? a[0].w: a[ie].w;
  629. }
  630. idx[0] = (int)a[0].x & 0xff;
  631. idx[1] = (int)a[0].y & 0xff;
  632. idx[2] = (int)a[0].z & 0xff;
  633. idx[3] = (int)a[0].w & 0xff;
  634. }
  635. }
  636. {
  637. float2 h[64];
  638. PARALLEL_DO( h[ie] = make_float2((float)ie, p[ie].w), nPoints );
  639. REDUCE_MIN( h, nPoints );
  640. max00 = h[0];
  641. }
  642. }
  643. contactIdx[0] = idx[0];
  644. contactIdx[1] = idx[1];
  645. contactIdx[2] = idx[2];
  646. contactIdx[3] = idx[3];
  647. return 4;
  648. }
  649. }
  650. __kernel void extractManifoldAndAddContactKernel(__global const int4* pairs,
  651. __global const b3RigidBodyData_t* rigidBodies,
  652. __global const float4* closestPointsWorld,
  653. __global const float4* separatingNormalsWorld,
  654. __global const int* contactCounts,
  655. __global const int* contactOffsets,
  656. __global struct b3Contact4Data* restrict contactsOut,
  657. counter32_t nContactsOut,
  658. int contactCapacity,
  659. int numPairs,
  660. int pairIndex
  661. )
  662. {
  663. int idx = get_global_id(0);
  664. if (idx<numPairs)
  665. {
  666. float4 normal = separatingNormalsWorld[idx];
  667. int nPoints = contactCounts[idx];
  668. __global const float4* pointsIn = &closestPointsWorld[contactOffsets[idx]];
  669. float4 localPoints[64];
  670. for (int i=0;i<nPoints;i++)
  671. {
  672. localPoints[i] = pointsIn[i];
  673. }
  674. int contactIdx[4];// = {-1,-1,-1,-1};
  675. contactIdx[0] = -1;
  676. contactIdx[1] = -1;
  677. contactIdx[2] = -1;
  678. contactIdx[3] = -1;
  679. int nContacts = extractManifoldSequential(localPoints, nPoints, normal, contactIdx);
  680. int dstIdx;
  681. AppendInc( nContactsOut, dstIdx );
  682. if (dstIdx<contactCapacity)
  683. {
  684. __global struct b3Contact4Data* c = contactsOut + dstIdx;
  685. c->m_worldNormalOnB = -normal;
  686. c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff);
  687. c->m_batchIdx = idx;
  688. int bodyA = pairs[pairIndex].x;
  689. int bodyB = pairs[pairIndex].y;
  690. c->m_bodyAPtrAndSignBit = rigidBodies[bodyA].m_invMass==0 ? -bodyA:bodyA;
  691. c->m_bodyBPtrAndSignBit = rigidBodies[bodyB].m_invMass==0 ? -bodyB:bodyB;
  692. c->m_childIndexA = -1;
  693. c->m_childIndexB = -1;
  694. for (int i=0;i<nContacts;i++)
  695. {
  696. c->m_worldPosB[i] = localPoints[contactIdx[i]];
  697. }
  698. GET_NPOINTS(*c) = nContacts;
  699. }
  700. }
  701. }
  702. void trInverse(float4 translationIn, Quaternion orientationIn,
  703. float4* translationOut, Quaternion* orientationOut)
  704. {
  705. *orientationOut = qtInvert(orientationIn);
  706. *translationOut = qtRotate(*orientationOut, -translationIn);
  707. }
  708. void trMul(float4 translationA, Quaternion orientationA,
  709. float4 translationB, Quaternion orientationB,
  710. float4* translationOut, Quaternion* orientationOut)
  711. {
  712. *orientationOut = qtMul(orientationA,orientationB);
  713. *translationOut = transform(&translationB,&translationA,&orientationA);
  714. }
  715. __kernel void clipHullHullKernel( __global int4* pairs,
  716. __global const b3RigidBodyData_t* rigidBodies,
  717. __global const b3Collidable_t* collidables,
  718. __global const b3ConvexPolyhedronData_t* convexShapes,
  719. __global const float4* vertices,
  720. __global const float4* uniqueEdges,
  721. __global const b3GpuFace_t* faces,
  722. __global const int* indices,
  723. __global const float4* separatingNormals,
  724. __global const int* hasSeparatingAxis,
  725. __global struct b3Contact4Data* restrict globalContactsOut,
  726. counter32_t nGlobalContactsOut,
  727. int numPairs,
  728. int contactCapacity)
  729. {
  730. int i = get_global_id(0);
  731. int pairIndex = i;
  732. float4 worldVertsB1[64];
  733. float4 worldVertsB2[64];
  734. int capacityWorldVerts = 64;
  735. float4 localContactsOut[64];
  736. int localContactCapacity=64;
  737. float minDist = -1e30f;
  738. float maxDist = 0.02f;
  739. if (i<numPairs)
  740. {
  741. int bodyIndexA = pairs[i].x;
  742. int bodyIndexB = pairs[i].y;
  743. int collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;
  744. int collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx;
  745. if (hasSeparatingAxis[i])
  746. {
  747. int shapeIndexA = collidables[collidableIndexA].m_shapeIndex;
  748. int shapeIndexB = collidables[collidableIndexB].m_shapeIndex;
  749. int numLocalContactsOut = clipHullAgainstHull(separatingNormals[i],
  750. &convexShapes[shapeIndexA], &convexShapes[shapeIndexB],
  751. rigidBodies[bodyIndexA].m_pos,rigidBodies[bodyIndexA].m_quat,
  752. rigidBodies[bodyIndexB].m_pos,rigidBodies[bodyIndexB].m_quat,
  753. worldVertsB1,worldVertsB2,capacityWorldVerts,
  754. minDist, maxDist,
  755. vertices,faces,indices,
  756. localContactsOut,localContactCapacity);
  757. if (numLocalContactsOut>0)
  758. {
  759. float4 normal = -separatingNormals[i];
  760. int nPoints = numLocalContactsOut;
  761. float4* pointsIn = localContactsOut;
  762. int contactIdx[4];// = {-1,-1,-1,-1};
  763. contactIdx[0] = -1;
  764. contactIdx[1] = -1;
  765. contactIdx[2] = -1;
  766. contactIdx[3] = -1;
  767. int nReducedContacts = extractManifoldSequential(pointsIn, nPoints, normal, contactIdx);
  768. int mprContactIndex = pairs[pairIndex].z;
  769. int dstIdx = mprContactIndex;
  770. if (dstIdx<0)
  771. {
  772. AppendInc( nGlobalContactsOut, dstIdx );
  773. }
  774. if (dstIdx<contactCapacity)
  775. {
  776. pairs[pairIndex].z = dstIdx;
  777. __global struct b3Contact4Data* c = globalContactsOut+ dstIdx;
  778. c->m_worldNormalOnB = -normal;
  779. c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff);
  780. c->m_batchIdx = pairIndex;
  781. int bodyA = pairs[pairIndex].x;
  782. int bodyB = pairs[pairIndex].y;
  783. c->m_bodyAPtrAndSignBit = rigidBodies[bodyA].m_invMass==0?-bodyA:bodyA;
  784. c->m_bodyBPtrAndSignBit = rigidBodies[bodyB].m_invMass==0?-bodyB:bodyB;
  785. c->m_childIndexA = -1;
  786. c->m_childIndexB = -1;
  787. for (int i=0;i<nReducedContacts;i++)
  788. {
  789. //this condition means: overwrite contact point, unless at index i==0 we have a valid 'mpr' contact
  790. if (i>0||(mprContactIndex<0))
  791. {
  792. c->m_worldPosB[i] = pointsIn[contactIdx[i]];
  793. }
  794. }
  795. GET_NPOINTS(*c) = nReducedContacts;
  796. }
  797. }// if (numContactsOut>0)
  798. }// if (hasSeparatingAxis[i])
  799. }// if (i<numPairs)
  800. }
  801. __kernel void clipCompoundsHullHullKernel( __global const int4* gpuCompoundPairs,
  802. __global const b3RigidBodyData_t* rigidBodies,
  803. __global const b3Collidable_t* collidables,
  804. __global const b3ConvexPolyhedronData_t* convexShapes,
  805. __global const float4* vertices,
  806. __global const float4* uniqueEdges,
  807. __global const b3GpuFace_t* faces,
  808. __global const int* indices,
  809. __global const b3GpuChildShape_t* gpuChildShapes,
  810. __global const float4* gpuCompoundSepNormalsOut,
  811. __global const int* gpuHasCompoundSepNormalsOut,
  812. __global struct b3Contact4Data* restrict globalContactsOut,
  813. counter32_t nGlobalContactsOut,
  814. int numCompoundPairs, int maxContactCapacity)
  815. {
  816. int i = get_global_id(0);
  817. int pairIndex = i;
  818. float4 worldVertsB1[64];
  819. float4 worldVertsB2[64];
  820. int capacityWorldVerts = 64;
  821. float4 localContactsOut[64];
  822. int localContactCapacity=64;
  823. float minDist = -1e30f;
  824. float maxDist = 0.02f;
  825. if (i<numCompoundPairs)
  826. {
  827. if (gpuHasCompoundSepNormalsOut[i])
  828. {
  829. int bodyIndexA = gpuCompoundPairs[i].x;
  830. int bodyIndexB = gpuCompoundPairs[i].y;
  831. int childShapeIndexA = gpuCompoundPairs[i].z;
  832. int childShapeIndexB = gpuCompoundPairs[i].w;
  833. int collidableIndexA = -1;
  834. int collidableIndexB = -1;
  835. float4 ornA = rigidBodies[bodyIndexA].m_quat;
  836. float4 posA = rigidBodies[bodyIndexA].m_pos;
  837. float4 ornB = rigidBodies[bodyIndexB].m_quat;
  838. float4 posB = rigidBodies[bodyIndexB].m_pos;
  839. if (childShapeIndexA >= 0)
  840. {
  841. collidableIndexA = gpuChildShapes[childShapeIndexA].m_shapeIndex;
  842. float4 childPosA = gpuChildShapes[childShapeIndexA].m_childPosition;
  843. float4 childOrnA = gpuChildShapes[childShapeIndexA].m_childOrientation;
  844. float4 newPosA = qtRotate(ornA,childPosA)+posA;
  845. float4 newOrnA = qtMul(ornA,childOrnA);
  846. posA = newPosA;
  847. ornA = newOrnA;
  848. } else
  849. {
  850. collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;
  851. }
  852. if (childShapeIndexB>=0)
  853. {
  854. collidableIndexB = gpuChildShapes[childShapeIndexB].m_shapeIndex;
  855. float4 childPosB = gpuChildShapes[childShapeIndexB].m_childPosition;
  856. float4 childOrnB = gpuChildShapes[childShapeIndexB].m_childOrientation;
  857. float4 newPosB = transform(&childPosB,&posB,&ornB);
  858. float4 newOrnB = qtMul(ornB,childOrnB);
  859. posB = newPosB;
  860. ornB = newOrnB;
  861. } else
  862. {
  863. collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx;
  864. }
  865. int shapeIndexA = collidables[collidableIndexA].m_shapeIndex;
  866. int shapeIndexB = collidables[collidableIndexB].m_shapeIndex;
  867. int numLocalContactsOut = clipHullAgainstHull(gpuCompoundSepNormalsOut[i],
  868. &convexShapes[shapeIndexA], &convexShapes[shapeIndexB],
  869. posA,ornA,
  870. posB,ornB,
  871. worldVertsB1,worldVertsB2,capacityWorldVerts,
  872. minDist, maxDist,
  873. vertices,faces,indices,
  874. localContactsOut,localContactCapacity);
  875. if (numLocalContactsOut>0)
  876. {
  877. float4 normal = -gpuCompoundSepNormalsOut[i];
  878. int nPoints = numLocalContactsOut;
  879. float4* pointsIn = localContactsOut;
  880. int contactIdx[4];// = {-1,-1,-1,-1};
  881. contactIdx[0] = -1;
  882. contactIdx[1] = -1;
  883. contactIdx[2] = -1;
  884. contactIdx[3] = -1;
  885. int nReducedContacts = extractManifoldSequential(pointsIn, nPoints, normal, contactIdx);
  886. int dstIdx;
  887. AppendInc( nGlobalContactsOut, dstIdx );
  888. if ((dstIdx+nReducedContacts) < maxContactCapacity)
  889. {
  890. __global struct b3Contact4Data* c = globalContactsOut+ dstIdx;
  891. c->m_worldNormalOnB = -normal;
  892. c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff);
  893. c->m_batchIdx = pairIndex;
  894. int bodyA = gpuCompoundPairs[pairIndex].x;
  895. int bodyB = gpuCompoundPairs[pairIndex].y;
  896. c->m_bodyAPtrAndSignBit = rigidBodies[bodyA].m_invMass==0?-bodyA:bodyA;
  897. c->m_bodyBPtrAndSignBit = rigidBodies[bodyB].m_invMass==0?-bodyB:bodyB;
  898. c->m_childIndexA = childShapeIndexA;
  899. c->m_childIndexB = childShapeIndexB;
  900. for (int i=0;i<nReducedContacts;i++)
  901. {
  902. c->m_worldPosB[i] = pointsIn[contactIdx[i]];
  903. }
  904. GET_NPOINTS(*c) = nReducedContacts;
  905. }
  906. }// if (numContactsOut>0)
  907. }// if (gpuHasCompoundSepNormalsOut[i])
  908. }// if (i<numCompoundPairs)
  909. }
  910. __kernel void sphereSphereCollisionKernel( __global const int4* pairs,
  911. __global const b3RigidBodyData_t* rigidBodies,
  912. __global const b3Collidable_t* collidables,
  913. __global const float4* separatingNormals,
  914. __global const int* hasSeparatingAxis,
  915. __global struct b3Contact4Data* restrict globalContactsOut,
  916. counter32_t nGlobalContactsOut,
  917. int contactCapacity,
  918. int numPairs)
  919. {
  920. int i = get_global_id(0);
  921. int pairIndex = i;
  922. if (i<numPairs)
  923. {
  924. int bodyIndexA = pairs[i].x;
  925. int bodyIndexB = pairs[i].y;
  926. int collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;
  927. int collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx;
  928. if (collidables[collidableIndexA].m_shapeType == SHAPE_SPHERE &&
  929. collidables[collidableIndexB].m_shapeType == SHAPE_SPHERE)
  930. {
  931. //sphere-sphere
  932. float radiusA = collidables[collidableIndexA].m_radius;
  933. float radiusB = collidables[collidableIndexB].m_radius;
  934. float4 posA = rigidBodies[bodyIndexA].m_pos;
  935. float4 posB = rigidBodies[bodyIndexB].m_pos;
  936. float4 diff = posA-posB;
  937. float len = length(diff);
  938. ///iff distance positive, don't generate a new contact
  939. if ( len <= (radiusA+radiusB))
  940. {
  941. ///distance (negative means penetration)
  942. float dist = len - (radiusA+radiusB);
  943. float4 normalOnSurfaceB = make_float4(1.f,0.f,0.f,0.f);
  944. if (len > 0.00001)
  945. {
  946. normalOnSurfaceB = diff / len;
  947. }
  948. float4 contactPosB = posB + normalOnSurfaceB*radiusB;
  949. contactPosB.w = dist;
  950. int dstIdx;
  951. AppendInc( nGlobalContactsOut, dstIdx );
  952. if (dstIdx < contactCapacity)
  953. {
  954. __global struct b3Contact4Data* c = &globalContactsOut[dstIdx];
  955. c->m_worldNormalOnB = -normalOnSurfaceB;
  956. c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff);
  957. c->m_batchIdx = pairIndex;
  958. int bodyA = pairs[pairIndex].x;
  959. int bodyB = pairs[pairIndex].y;
  960. c->m_bodyAPtrAndSignBit = rigidBodies[bodyA].m_invMass==0?-bodyA:bodyA;
  961. c->m_bodyBPtrAndSignBit = rigidBodies[bodyB].m_invMass==0?-bodyB:bodyB;
  962. c->m_worldPosB[0] = contactPosB;
  963. c->m_childIndexA = -1;
  964. c->m_childIndexB = -1;
  965. GET_NPOINTS(*c) = 1;
  966. }//if (dstIdx < numPairs)
  967. }//if ( len <= (radiusA+radiusB))
  968. }//SHAPE_SPHERE SHAPE_SPHERE
  969. }//if (i<numPairs)
  970. }
  971. __kernel void clipHullHullConcaveConvexKernel( __global int4* concavePairsIn,
  972. __global const b3RigidBodyData_t* rigidBodies,
  973. __global const b3Collidable_t* collidables,
  974. __global const b3ConvexPolyhedronData_t* convexShapes,
  975. __global const float4* vertices,
  976. __global const float4* uniqueEdges,
  977. __global const b3GpuFace_t* faces,
  978. __global const int* indices,
  979. __global const b3GpuChildShape_t* gpuChildShapes,
  980. __global const float4* separatingNormals,
  981. __global struct b3Contact4Data* restrict globalContactsOut,
  982. counter32_t nGlobalContactsOut,
  983. int contactCapacity,
  984. int numConcavePairs)
  985. {
  986. int i = get_global_id(0);
  987. int pairIndex = i;
  988. float4 worldVertsB1[64];
  989. float4 worldVertsB2[64];
  990. int capacityWorldVerts = 64;
  991. float4 localContactsOut[64];
  992. int localContactCapacity=64;
  993. float minDist = -1e30f;
  994. float maxDist = 0.02f;
  995. if (i<numConcavePairs)
  996. {
  997. //negative value means that the pair is invalid
  998. if (concavePairsIn[i].w<0)
  999. return;
  1000. int bodyIndexA = concavePairsIn[i].x;
  1001. int bodyIndexB = concavePairsIn[i].y;
  1002. int f = concavePairsIn[i].z;
  1003. int childShapeIndexA = f;
  1004. int collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;
  1005. int collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx;
  1006. int shapeIndexA = collidables[collidableIndexA].m_shapeIndex;
  1007. int shapeIndexB = collidables[collidableIndexB].m_shapeIndex;
  1008. ///////////////////////////////////////////////////////////////
  1009. bool overlap = false;
  1010. b3ConvexPolyhedronData_t convexPolyhedronA;
  1011. //add 3 vertices of the triangle
  1012. convexPolyhedronA.m_numVertices = 3;
  1013. convexPolyhedronA.m_vertexOffset = 0;
  1014. float4 localCenter = make_float4(0.f,0.f,0.f,0.f);
  1015. b3GpuFace_t face = faces[convexShapes[shapeIndexA].m_faceOffset+f];
  1016. float4 verticesA[3];
  1017. for (int i=0;i<3;i++)
  1018. {
  1019. int index = indices[face.m_indexOffset+i];
  1020. float4 vert = vertices[convexShapes[shapeIndexA].m_vertexOffset+index];
  1021. verticesA[i] = vert;
  1022. localCenter += vert;
  1023. }
  1024. float dmin = FLT_MAX;
  1025. int localCC=0;
  1026. //a triangle has 3 unique edges
  1027. convexPolyhedronA.m_numUniqueEdges = 3;
  1028. convexPolyhedronA.m_uniqueEdgesOffset = 0;
  1029. float4 uniqueEdgesA[3];
  1030. uniqueEdgesA[0] = (verticesA[1]-verticesA[0]);
  1031. uniqueEdgesA[1] = (verticesA[2]-verticesA[1]);
  1032. uniqueEdgesA[2] = (verticesA[0]-verticesA[2]);
  1033. convexPolyhedronA.m_faceOffset = 0;
  1034. float4 normal = make_float4(face.m_plane.x,face.m_plane.y,face.m_plane.z,0.f);
  1035. b3GpuFace_t facesA[TRIANGLE_NUM_CONVEX_FACES];
  1036. int indicesA[3+3+2+2+2];
  1037. int curUsedIndices=0;
  1038. int fidx=0;
  1039. //front size of triangle
  1040. {
  1041. facesA[fidx].m_indexOffset=curUsedIndices;
  1042. indicesA[0] = 0;
  1043. indicesA[1] = 1;
  1044. indicesA[2] = 2;
  1045. curUsedIndices+=3;
  1046. float c = face.m_plane.w;
  1047. facesA[fidx].m_plane.x = normal.x;
  1048. facesA[fidx].m_plane.y = normal.y;
  1049. facesA[fidx].m_plane.z = normal.z;
  1050. facesA[fidx].m_plane.w = c;
  1051. facesA[fidx].m_numIndices=3;
  1052. }
  1053. fidx++;
  1054. //back size of triangle
  1055. {
  1056. facesA[fidx].m_indexOffset=curUsedIndices;
  1057. indicesA[3]=2;
  1058. indicesA[4]=1;
  1059. indicesA[5]=0;
  1060. curUsedIndices+=3;
  1061. float c = dot3F4(normal,verticesA[0]);
  1062. float c1 = -face.m_plane.w;
  1063. facesA[fidx].m_plane.x = -normal.x;
  1064. facesA[fidx].m_plane.y = -normal.y;
  1065. facesA[fidx].m_plane.z = -normal.z;
  1066. facesA[fidx].m_plane.w = c;
  1067. facesA[fidx].m_numIndices=3;
  1068. }
  1069. fidx++;
  1070. bool addEdgePlanes = true;
  1071. if (addEdgePlanes)
  1072. {
  1073. int numVertices=3;
  1074. int prevVertex = numVertices-1;
  1075. for (int i=0;i<numVertices;i++)
  1076. {
  1077. float4 v0 = verticesA[i];
  1078. float4 v1 = verticesA[prevVertex];
  1079. float4 edgeNormal = normalize(cross(normal,v1-v0));
  1080. float c = -dot3F4(edgeNormal,v0);
  1081. facesA[fidx].m_numIndices = 2;
  1082. facesA[fidx].m_indexOffset=curUsedIndices;
  1083. indicesA[curUsedIndices++]=i;
  1084. indicesA[curUsedIndices++]=prevVertex;
  1085. facesA[fidx].m_plane.x = edgeNormal.x;
  1086. facesA[fidx].m_plane.y = edgeNormal.y;
  1087. facesA[fidx].m_plane.z = edgeNormal.z;
  1088. facesA[fidx].m_plane.w = c;
  1089. fidx++;
  1090. prevVertex = i;
  1091. }
  1092. }
  1093. convexPolyhedronA.m_numFaces = TRIANGLE_NUM_CONVEX_FACES;
  1094. convexPolyhedronA.m_localCenter = localCenter*(1.f/3.f);
  1095. float4 posA = rigidBodies[bodyIndexA].m_pos;
  1096. posA.w = 0.f;
  1097. float4 posB = rigidBodies[bodyIndexB].m_pos;
  1098. posB.w = 0.f;
  1099. float4 ornA = rigidBodies[bodyIndexA].m_quat;
  1100. float4 ornB =rigidBodies[bodyIndexB].m_quat;
  1101. float4 sepAxis = separatingNormals[i];
  1102. int shapeTypeB = collidables[collidableIndexB].m_shapeType;
  1103. int childShapeIndexB =-1;
  1104. if (shapeTypeB==SHAPE_COMPOUND_OF_CONVEX_HULLS)
  1105. {
  1106. ///////////////////
  1107. ///compound shape support
  1108. childShapeIndexB = concavePairsIn[pairIndex].w;
  1109. int childColIndexB = gpuChildShapes[childShapeIndexB].m_shapeIndex;
  1110. shapeIndexB = collidables[childColIndexB].m_shapeIndex;
  1111. float4 childPosB = gpuChildShapes[childShapeIndexB].m_childPosition;
  1112. float4 childOrnB = gpuChildShapes[childShapeIndexB].m_childOrientation;
  1113. float4 newPosB = transform(&childPosB,&posB,&ornB);
  1114. float4 newOrnB = qtMul(ornB,childOrnB);
  1115. posB = newPosB;
  1116. ornB = newOrnB;
  1117. }
  1118. ////////////////////////////////////////
  1119. int numLocalContactsOut = clipHullAgainstHullLocalA(sepAxis,
  1120. &convexPolyhedronA, &convexShapes[shapeIndexB],
  1121. posA,ornA,
  1122. posB,ornB,
  1123. worldVertsB1,worldVertsB2,capacityWorldVerts,
  1124. minDist, maxDist,
  1125. &verticesA,&facesA,&indicesA,
  1126. vertices,faces,indices,
  1127. localContactsOut,localContactCapacity);
  1128. if (numLocalContactsOut>0)
  1129. {
  1130. float4 normal = -separatingNormals[i];
  1131. int nPoints = numLocalContactsOut;
  1132. float4* pointsIn = localContactsOut;
  1133. int contactIdx[4];// = {-1,-1,-1,-1};
  1134. contactIdx[0] = -1;
  1135. contactIdx[1] = -1;
  1136. contactIdx[2] = -1;
  1137. contactIdx[3] = -1;
  1138. int nReducedContacts = extractManifoldSequential(pointsIn, nPoints, normal, contactIdx);
  1139. int dstIdx;
  1140. AppendInc( nGlobalContactsOut, dstIdx );
  1141. if (dstIdx<contactCapacity)
  1142. {
  1143. __global struct b3Contact4Data* c = globalContactsOut+ dstIdx;
  1144. c->m_worldNormalOnB = -normal;
  1145. c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff);
  1146. c->m_batchIdx = pairIndex;
  1147. int bodyA = concavePairsIn[pairIndex].x;
  1148. int bodyB = concavePairsIn[pairIndex].y;
  1149. c->m_bodyAPtrAndSignBit = rigidBodies[bodyA].m_invMass==0?-bodyA:bodyA;
  1150. c->m_bodyBPtrAndSignBit = rigidBodies[bodyB].m_invMass==0?-bodyB:bodyB;
  1151. c->m_childIndexA = childShapeIndexA;
  1152. c->m_childIndexB = childShapeIndexB;
  1153. for (int i=0;i<nReducedContacts;i++)
  1154. {
  1155. c->m_worldPosB[i] = pointsIn[contactIdx[i]];
  1156. }
  1157. GET_NPOINTS(*c) = nReducedContacts;
  1158. }
  1159. }// if (numContactsOut>0)
  1160. }// if (i<numPairs)
  1161. }
  1162. int findClippingFaces(const float4 separatingNormal,
  1163. __global const b3ConvexPolyhedronData_t* hullA, __global const b3ConvexPolyhedronData_t* hullB,
  1164. const float4 posA, const Quaternion ornA,const float4 posB, const Quaternion ornB,
  1165. __global float4* worldVertsA1,
  1166. __global float4* worldNormalsA1,
  1167. __global float4* worldVertsB1,
  1168. int capacityWorldVerts,
  1169. const float minDist, float maxDist,
  1170. __global const float4* vertices,
  1171. __global const b3GpuFace_t* faces,
  1172. __global const int* indices,
  1173. __global int4* clippingFaces, int pairIndex)
  1174. {
  1175. int numContactsOut = 0;
  1176. int numWorldVertsB1= 0;
  1177. int closestFaceB=-1;
  1178. float dmax = -FLT_MAX;
  1179. {
  1180. for(int face=0;face<hullB->m_numFaces;face++)
  1181. {
  1182. const float4 Normal = make_float4(faces[hullB->m_faceOffset+face].m_plane.x,
  1183. faces[hullB->m_faceOffset+face].m_plane.y, faces[hullB->m_faceOffset+face].m_plane.z,0.f);
  1184. const float4 WorldNormal = qtRotate(ornB, Normal);
  1185. float d = dot3F4(WorldNormal,separatingNormal);
  1186. if (d > dmax)
  1187. {
  1188. dmax = d;
  1189. closestFaceB = face;
  1190. }
  1191. }
  1192. }
  1193. {
  1194. const b3GpuFace_t polyB = faces[hullB->m_faceOffset+closestFaceB];
  1195. const int numVertices = polyB.m_numIndices;
  1196. for(int e0=0;e0<numVertices;e0++)
  1197. {
  1198. const float4 b = vertices[hullB->m_vertexOffset+indices[polyB.m_indexOffset+e0]];
  1199. worldVertsB1[pairIndex*capacityWorldVerts+numWorldVertsB1++] = transform(&b,&posB,&ornB);
  1200. }
  1201. }
  1202. int closestFaceA=-1;
  1203. {
  1204. float dmin = FLT_MAX;
  1205. for(int face=0;face<hullA->m_numFaces;face++)
  1206. {
  1207. const float4 Normal = make_float4(
  1208. faces[hullA->m_faceOffset+face].m_plane.x,
  1209. faces[hullA->m_faceOffset+face].m_plane.y,
  1210. faces[hullA->m_faceOffset+face].m_plane.z,
  1211. 0.f);
  1212. const float4 faceANormalWS = qtRotate(ornA,Normal);
  1213. float d = dot3F4(faceANormalWS,separatingNormal);
  1214. if (d < dmin)
  1215. {
  1216. dmin = d;
  1217. closestFaceA = face;
  1218. worldNormalsA1[pairIndex] = faceANormalWS;
  1219. }
  1220. }
  1221. }
  1222. int numVerticesA = faces[hullA->m_faceOffset+closestFaceA].m_numIndices;
  1223. for(int e0=0;e0<numVerticesA;e0++)
  1224. {
  1225. const float4 a = vertices[hullA->m_vertexOffset+indices[faces[hullA->m_faceOffset+closestFaceA].m_indexOffset+e0]];
  1226. worldVertsA1[pairIndex*capacityWorldVerts+e0] = transform(&a, &posA,&ornA);
  1227. }
  1228. clippingFaces[pairIndex].x = closestFaceA;
  1229. clippingFaces[pairIndex].y = closestFaceB;
  1230. clippingFaces[pairIndex].z = numVerticesA;
  1231. clippingFaces[pairIndex].w = numWorldVertsB1;
  1232. return numContactsOut;
  1233. }
  1234. int clipFaces(__global float4* worldVertsA1,
  1235. __global float4* worldNormalsA1,
  1236. __global float4* worldVertsB1,
  1237. __global float4* worldVertsB2,
  1238. int capacityWorldVertsB2,
  1239. const float minDist, float maxDist,
  1240. __global int4* clippingFaces,
  1241. int pairIndex)
  1242. {
  1243. int numContactsOut = 0;
  1244. int closestFaceA = clippingFaces[pairIndex].x;
  1245. int closestFaceB = clippingFaces[pairIndex].y;
  1246. int numVertsInA = clippingFaces[pairIndex].z;
  1247. int numVertsInB = clippingFaces[pairIndex].w;
  1248. int numVertsOut = 0;
  1249. if (closestFaceA<0)
  1250. return numContactsOut;
  1251. __global float4* pVtxIn = &worldVertsB1[pairIndex*capacityWorldVertsB2];
  1252. __global float4* pVtxOut = &worldVertsB2[pairIndex*capacityWorldVertsB2];
  1253. // clip polygon to back of planes of all faces of hull A that are adjacent to witness face
  1254. for(int e0=0;e0<numVertsInA;e0++)
  1255. {
  1256. const float4 aw = worldVertsA1[pairIndex*capacityWorldVertsB2+e0];
  1257. const float4 bw = worldVertsA1[pairIndex*capacityWorldVertsB2+((e0+1)%numVertsInA)];
  1258. const float4 WorldEdge0 = aw - bw;
  1259. float4 worldPlaneAnormal1 = worldNormalsA1[pairIndex];
  1260. float4 planeNormalWS1 = -cross3(WorldEdge0,worldPlaneAnormal1);
  1261. float4 worldA1 = aw;
  1262. float planeEqWS1 = -dot3F4(worldA1,planeNormalWS1);
  1263. float4 planeNormalWS = planeNormalWS1;
  1264. float planeEqWS=planeEqWS1;
  1265. numVertsOut = clipFaceGlobal(pVtxIn, numVertsInB, planeNormalWS,planeEqWS, pVtxOut);
  1266. __global float4* tmp = pVtxOut;
  1267. pVtxOut = pVtxIn;
  1268. pVtxIn = tmp;
  1269. numVertsInB = numVertsOut;
  1270. numVertsOut = 0;
  1271. }
  1272. //float4 planeNormalWS = worldNormalsA1[pairIndex];
  1273. //float planeEqWS=-dot3F4(planeNormalWS,worldVertsA1[pairIndex*capacityWorldVertsB2]);
  1274. /*for (int i=0;i<numVertsInB;i++)
  1275. {
  1276. pVtxOut[i] = pVtxIn[i];
  1277. }*/
  1278. //numVertsInB=0;
  1279. float4 planeNormalWS = worldNormalsA1[pairIndex];
  1280. float planeEqWS=-dot3F4(planeNormalWS,worldVertsA1[pairIndex*capacityWorldVertsB2]);
  1281. for (int i=0;i<numVertsInB;i++)
  1282. {
  1283. float depth = dot3F4(planeNormalWS,pVtxIn[i])+planeEqWS;
  1284. if (depth <=minDist)
  1285. {
  1286. depth = minDist;
  1287. }
  1288. if (depth <=maxDist)
  1289. {
  1290. float4 pointInWorld = pVtxIn[i];
  1291. pVtxOut[numContactsOut++] = make_float4(pointInWorld.x,pointInWorld.y,pointInWorld.z,depth);
  1292. }
  1293. }
  1294. clippingFaces[pairIndex].w =numContactsOut;
  1295. return numContactsOut;
  1296. }
  1297. __kernel void findClippingFacesKernel( __global const int4* pairs,
  1298. __global const b3RigidBodyData_t* rigidBodies,
  1299. __global const b3Collidable_t* collidables,
  1300. __global const b3ConvexPolyhedronData_t* convexShapes,
  1301. __global const float4* vertices,
  1302. __global const float4* uniqueEdges,
  1303. __global const b3GpuFace_t* faces,
  1304. __global const int* indices,
  1305. __global const float4* separatingNormals,
  1306. __global const int* hasSeparatingAxis,
  1307. __global int4* clippingFacesOut,
  1308. __global float4* worldVertsA1,
  1309. __global float4* worldNormalsA1,
  1310. __global float4* worldVertsB1,
  1311. int capacityWorldVerts,
  1312. int numPairs
  1313. )
  1314. {
  1315. int i = get_global_id(0);
  1316. int pairIndex = i;
  1317. float minDist = -1e30f;
  1318. float maxDist = 0.02f;
  1319. if (i<numPairs)
  1320. {
  1321. if (hasSeparatingAxis[i])
  1322. {
  1323. int bodyIndexA = pairs[i].x;
  1324. int bodyIndexB = pairs[i].y;
  1325. int collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;
  1326. int collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx;
  1327. int shapeIndexA = collidables[collidableIndexA].m_shapeIndex;
  1328. int shapeIndexB = collidables[collidableIndexB].m_shapeIndex;
  1329. int numLocalContactsOut = findClippingFaces(separatingNormals[i],
  1330. &convexShapes[shapeIndexA], &convexShapes[shapeIndexB],
  1331. rigidBodies[bodyIndexA].m_pos,rigidBodies[bodyIndexA].m_quat,
  1332. rigidBodies[bodyIndexB].m_pos,rigidBodies[bodyIndexB].m_quat,
  1333. worldVertsA1,
  1334. worldNormalsA1,
  1335. worldVertsB1,capacityWorldVerts,
  1336. minDist, maxDist,
  1337. vertices,faces,indices,
  1338. clippingFacesOut,i);
  1339. }// if (hasSeparatingAxis[i])
  1340. }// if (i<numPairs)
  1341. }
  1342. __kernel void clipFacesAndFindContactsKernel( __global const float4* separatingNormals,
  1343. __global const int* hasSeparatingAxis,
  1344. __global int4* clippingFacesOut,
  1345. __global float4* worldVertsA1,
  1346. __global float4* worldNormalsA1,
  1347. __global float4* worldVertsB1,
  1348. __global float4* worldVertsB2,
  1349. int vertexFaceCapacity,
  1350. int numPairs,
  1351. int debugMode
  1352. )
  1353. {
  1354. int i = get_global_id(0);
  1355. int pairIndex = i;
  1356. float minDist = -1e30f;
  1357. float maxDist = 0.02f;
  1358. if (i<numPairs)
  1359. {
  1360. if (hasSeparatingAxis[i])
  1361. {
  1362. // int bodyIndexA = pairs[i].x;
  1363. // int bodyIndexB = pairs[i].y;
  1364. int numLocalContactsOut = 0;
  1365. int capacityWorldVertsB2 = vertexFaceCapacity;
  1366. __global float4* pVtxIn = &worldVertsB1[pairIndex*capacityWorldVertsB2];
  1367. __global float4* pVtxOut = &worldVertsB2[pairIndex*capacityWorldVertsB2];
  1368. {
  1369. __global int4* clippingFaces = clippingFacesOut;
  1370. int closestFaceA = clippingFaces[pairIndex].x;
  1371. int closestFaceB = clippingFaces[pairIndex].y;
  1372. int numVertsInA = clippingFaces[pairIndex].z;
  1373. int numVertsInB = clippingFaces[pairIndex].w;
  1374. int numVertsOut = 0;
  1375. if (closestFaceA>=0)
  1376. {
  1377. // clip polygon to back of planes of all faces of hull A that are adjacent to witness face
  1378. for(int e0=0;e0<numVertsInA;e0++)
  1379. {
  1380. const float4 aw = worldVertsA1[pairIndex*capacityWorldVertsB2+e0];
  1381. const float4 bw = worldVertsA1[pairIndex*capacityWorldVertsB2+((e0+1)%numVertsInA)];
  1382. const float4 WorldEdge0 = aw - bw;
  1383. float4 worldPlaneAnormal1 = worldNormalsA1[pairIndex];
  1384. float4 planeNormalWS1 = -cross3(WorldEdge0,worldPlaneAnormal1);
  1385. float4 worldA1 = aw;
  1386. float planeEqWS1 = -dot3F4(worldA1,planeNormalWS1);
  1387. float4 planeNormalWS = planeNormalWS1;
  1388. float planeEqWS=planeEqWS1;
  1389. numVertsOut = clipFaceGlobal(pVtxIn, numVertsInB, planeNormalWS,planeEqWS, pVtxOut);
  1390. __global float4* tmp = pVtxOut;
  1391. pVtxOut = pVtxIn;
  1392. pVtxIn = tmp;
  1393. numVertsInB = numVertsOut;
  1394. numVertsOut = 0;
  1395. }
  1396. float4 planeNormalWS = worldNormalsA1[pairIndex];
  1397. float planeEqWS=-dot3F4(planeNormalWS,worldVertsA1[pairIndex*capacityWorldVertsB2]);
  1398. for (int i=0;i<numVertsInB;i++)
  1399. {
  1400. float depth = dot3F4(planeNormalWS,pVtxIn[i])+planeEqWS;
  1401. if (depth <=minDist)
  1402. {
  1403. depth = minDist;
  1404. }
  1405. if (depth <=maxDist)
  1406. {
  1407. float4 pointInWorld = pVtxIn[i];
  1408. pVtxOut[numLocalContactsOut++] = make_float4(pointInWorld.x,pointInWorld.y,pointInWorld.z,depth);
  1409. }
  1410. }
  1411. }
  1412. clippingFaces[pairIndex].w =numLocalContactsOut;
  1413. }
  1414. for (int i=0;i<numLocalContactsOut;i++)
  1415. pVtxIn[i] = pVtxOut[i];
  1416. }// if (hasSeparatingAxis[i])
  1417. }// if (i<numPairs)
  1418. }
  1419. __kernel void newContactReductionKernel( __global int4* pairs,
  1420. __global const b3RigidBodyData_t* rigidBodies,
  1421. __global const float4* separatingNormals,
  1422. __global const int* hasSeparatingAxis,
  1423. __global struct b3Contact4Data* globalContactsOut,
  1424. __global int4* clippingFaces,
  1425. __global float4* worldVertsB2,
  1426. volatile __global int* nGlobalContactsOut,
  1427. int vertexFaceCapacity,
  1428. int contactCapacity,
  1429. int numPairs
  1430. )
  1431. {
  1432. int i = get_global_id(0);
  1433. int pairIndex = i;
  1434. int4 contactIdx;
  1435. contactIdx=make_int4(0,1,2,3);
  1436. if (i<numPairs)
  1437. {
  1438. if (hasSeparatingAxis[i])
  1439. {
  1440. int nPoints = clippingFaces[pairIndex].w;
  1441. if (nPoints>0)
  1442. {
  1443. __global float4* pointsIn = &worldVertsB2[pairIndex*vertexFaceCapacity];
  1444. float4 normal = -separatingNormals[i];
  1445. int nReducedContacts = extractManifoldSequentialGlobal(pointsIn, nPoints, normal, &contactIdx);
  1446. int mprContactIndex = pairs[pairIndex].z;
  1447. int dstIdx = mprContactIndex;
  1448. if (dstIdx<0)
  1449. {
  1450. AppendInc( nGlobalContactsOut, dstIdx );
  1451. }
  1452. //#if 0
  1453. if (dstIdx < contactCapacity)
  1454. {
  1455. __global struct b3Contact4Data* c = &globalContactsOut[dstIdx];
  1456. c->m_worldNormalOnB = -normal;
  1457. c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff);
  1458. c->m_batchIdx = pairIndex;
  1459. int bodyA = pairs[pairIndex].x;
  1460. int bodyB = pairs[pairIndex].y;
  1461. pairs[pairIndex].w = dstIdx;
  1462. c->m_bodyAPtrAndSignBit = rigidBodies[bodyA].m_invMass==0?-bodyA:bodyA;
  1463. c->m_bodyBPtrAndSignBit = rigidBodies[bodyB].m_invMass==0?-bodyB:bodyB;
  1464. c->m_childIndexA =-1;
  1465. c->m_childIndexB =-1;
  1466. switch (nReducedContacts)
  1467. {
  1468. case 4:
  1469. c->m_worldPosB[3] = pointsIn[contactIdx.w];
  1470. case 3:
  1471. c->m_worldPosB[2] = pointsIn[contactIdx.z];
  1472. case 2:
  1473. c->m_worldPosB[1] = pointsIn[contactIdx.y];
  1474. case 1:
  1475. if (mprContactIndex<0)//test
  1476. c->m_worldPosB[0] = pointsIn[contactIdx.x];
  1477. default:
  1478. {
  1479. }
  1480. };
  1481. GET_NPOINTS(*c) = nReducedContacts;
  1482. }
  1483. //#endif
  1484. }// if (numContactsOut>0)
  1485. }// if (hasSeparatingAxis[i])
  1486. }// if (i<numPairs)
  1487. }