2 #include "Bullet3Collision/NarrowPhaseCollision/shared/b3MprPenetration.h"
3 #include "Bullet3Collision/NarrowPhaseCollision/shared/b3Contact4Data.h"
5 #define AppendInc(x, out) out = atomic_inc(x)
6 #define GET_NPOINTS(x) (x).m_worldNormalOnB.w
7 #ifdef cl_ext_atomic_counters_32
8 #pragma OPENCL EXTENSION cl_ext_atomic_counters_32 : enable
10 #define counter32_t volatile __global int*
14 __kernel void mprPenetrationKernel( __global int4* pairs,
15 __global const b3RigidBodyData_t* rigidBodies,
16 __global const b3Collidable_t* collidables,
17 __global const b3ConvexPolyhedronData_t* convexShapes,
18 __global const float4* vertices,
19 __global float4* separatingNormals,
20 __global int* hasSeparatingAxis,
21 __global struct b3Contact4Data* restrict globalContactsOut,
22 counter32_t nGlobalContactsOut,
26 int i = get_global_id(0);
30 int bodyIndexA = pairs[i].x;
31 int bodyIndexB = pairs[i].y;
33 int collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;
34 int collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx;
36 int shapeIndexA = collidables[collidableIndexA].m_shapeIndex;
37 int shapeIndexB = collidables[collidableIndexB].m_shapeIndex;
40 //once the broadphase avoids static-static pairs, we can remove this test
41 if ((rigidBodies[bodyIndexA].m_invMass==0) &&(rigidBodies[bodyIndexB].m_invMass==0))
47 if ((collidables[collidableIndexA].m_shapeType!=SHAPE_CONVEX_HULL) ||(collidables[collidableIndexB].m_shapeType!=SHAPE_CONVEX_HULL))
57 int res = b3MprPenetration(pairIndex, bodyIndexA, bodyIndexB,rigidBodies,convexShapes,collidables,vertices,separatingNormals,hasSeparatingAxis,&depthOut, &dirOut, &posOut);
68 AppendInc( nGlobalContactsOut, dstIdx );
69 if (dstIdx<contactCapacity)
71 pairs[pairIndex].z = dstIdx;
72 __global struct b3Contact4Data* c = globalContactsOut + dstIdx;
73 c->m_worldNormalOnB = -dirOut;//normal;
74 c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff);
75 c->m_batchIdx = pairIndex;
76 int bodyA = pairs[pairIndex].x;
77 int bodyB = pairs[pairIndex].y;
78 c->m_bodyAPtrAndSignBit = rigidBodies[bodyA].m_invMass==0 ? -bodyA:bodyA;
79 c->m_bodyBPtrAndSignBit = rigidBodies[bodyB].m_invMass==0 ? -bodyB:bodyB;
80 c->m_childIndexA = -1;
81 c->m_childIndexB = -1;
82 //for (int i=0;i<nContacts;i++)
84 c->m_worldPosB[0] = posOut;//localPoints[contactIdx[i]];
85 GET_NPOINTS(*c) = 1;//nContacts;
92 typedef float4 Quaternion;
93 #define make_float4 (float4)
96 float dot3F4(float4 a, float4 b)
98 float4 a1 = make_float4(a.xyz,0.f);
99 float4 b1 = make_float4(b.xyz,0.f);
107 float4 cross3(float4 a, float4 b)
112 Quaternion qtMul(Quaternion a, Quaternion b)
115 ans = cross3( a, b );
117 // ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);
118 ans.w = a.w*b.w - dot3F4(a, b);
123 Quaternion qtInvert(Quaternion q)
125 return (Quaternion)(-q.xyz, q.w);
129 float4 qtRotate(Quaternion q, float4 vec)
131 Quaternion qInv = qtInvert( q );
134 float4 out = qtMul(qtMul(q,vcpy),qInv);
139 float4 transform(const float4* p, const float4* translation, const Quaternion* orientation)
141 return qtRotate( *orientation, *p ) + (*translation);
146 float4 qtInvRotate(const Quaternion q, float4 vec)
148 return qtRotate( qtInvert( q ), vec );
152 inline void project(__global const b3ConvexPolyhedronData_t* hull, const float4 pos, const float4 orn,
153 const float4* dir, __global const float4* vertices, float* min, float* max)
157 int numVerts = hull->m_numVertices;
159 const float4 localDir = qtInvRotate(orn,*dir);
160 float offset = dot(pos,*dir);
161 for(int i=0;i<numVerts;i++)
163 float dp = dot(vertices[hull->m_vertexOffset+i],localDir);
180 bool findSeparatingAxisUnitSphere( __global const b3ConvexPolyhedronData_t* hullA, __global const b3ConvexPolyhedronData_t* hullB,
185 const float4 DeltaC2,
186 __global const float4* vertices,
187 __global const float4* unitSphereDirections,
188 int numUnitSphereDirections,
201 // Test unit sphere directions
202 for (int i=0;i<numUnitSphereDirections;i++)
206 crossje = unitSphereDirections[i];
208 if (dot3F4(DeltaC2,crossje)>0)
215 project(hullA,posA,ornA,&crossje,vertices, &Min0, &Max0);
216 project(hullB,posB,ornB,&crossje,vertices, &Min1, &Max1);
218 if(Max0<Min1 || Max1<Min0)
221 float d0 = Max0 - Min1;
222 float d1 = Max1 - Min0;
223 dist = d0<d1 ? d0:d1;
235 if((dot3F4(-DeltaC2,*sep))>0.0f)
244 __kernel void findSeparatingAxisUnitSphereKernel( __global const int4* pairs,
245 __global const b3RigidBodyData_t* rigidBodies,
246 __global const b3Collidable_t* collidables,
247 __global const b3ConvexPolyhedronData_t* convexShapes,
248 __global const float4* vertices,
249 __global const float4* unitSphereDirections,
250 __global float4* separatingNormals,
251 __global int* hasSeparatingAxis,
252 __global float* dmins,
253 int numUnitSphereDirections,
258 int i = get_global_id(0);
263 if (hasSeparatingAxis[i])
266 int bodyIndexA = pairs[i].x;
267 int bodyIndexB = pairs[i].y;
269 int collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;
270 int collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx;
272 int shapeIndexA = collidables[collidableIndexA].m_shapeIndex;
273 int shapeIndexB = collidables[collidableIndexB].m_shapeIndex;
276 int numFacesA = convexShapes[shapeIndexA].m_numFaces;
278 float dmin = dmins[i];
280 float4 posA = rigidBodies[bodyIndexA].m_pos;
282 float4 posB = rigidBodies[bodyIndexB].m_pos;
284 float4 c0local = convexShapes[shapeIndexA].m_localCenter;
285 float4 ornA = rigidBodies[bodyIndexA].m_quat;
286 float4 c0 = transform(&c0local, &posA, &ornA);
287 float4 c1local = convexShapes[shapeIndexB].m_localCenter;
288 float4 ornB =rigidBodies[bodyIndexB].m_quat;
289 float4 c1 = transform(&c1local,&posB,&ornB);
290 const float4 DeltaC2 = c0 - c1;
291 float4 sepNormal = separatingNormals[i];
293 int numEdgeEdgeDirections = convexShapes[shapeIndexA].m_numUniqueEdges*convexShapes[shapeIndexB].m_numUniqueEdges;
294 if (numEdgeEdgeDirections>numUnitSphereDirections)
296 bool sepEE = findSeparatingAxisUnitSphere( &convexShapes[shapeIndexA], &convexShapes[shapeIndexB],posA,ornA,
299 vertices,unitSphereDirections,numUnitSphereDirections,&sepNormal,&dmin);
302 hasSeparatingAxis[i] = 0;
305 hasSeparatingAxis[i] = 1;
306 separatingNormals[i] = sepNormal;
309 } //if (hasSeparatingAxis[i])