add re-usable createGraphicsSphere method in GpuDemo.

introduce and use maxContactCapacity (needs to be fixed in various other contact kernels)
implement sphere versus trimesh
disable new/sequential GPU batching (only uses 1 thread in a warp, slow but works on NVIDIA/Apple OpenCL)
This commit is contained in:
erwin coumans
2013-04-04 17:54:45 -07:00
parent 733572e625
commit 358f4f97a2
15 changed files with 1008 additions and 139 deletions

View File

@@ -53,6 +53,21 @@ static const char* primitiveContactsKernelsCL= \
" int m_bodyBPtrAndSignBit;\n"
"} Contact4;\n"
"\n"
"typedef struct \n"
"{\n"
" union\n"
" {\n"
" float4 m_min;\n"
" float m_minElems[4];\n"
" int m_minIndices[4];\n"
" };\n"
" union\n"
" {\n"
" float4 m_max;\n"
" float m_maxElems[4];\n"
" int m_maxIndices[4];\n"
" };\n"
"} btAabbCL;\n"
"\n"
"///keep this in sync with btCollidable.h\n"
"typedef struct\n"
@@ -275,8 +290,6 @@ static const char* primitiveContactsKernelsCL= \
"\n"
"\n"
"inline bool IsPointInPolygon(float4 p, \n"
" float4 posConvex,\n"
" float4 ornConvex,\n"
" const btGpuFace* face,\n"
" __global const float4* baseVertex,\n"
" __global const int* convexIndices,\n"
@@ -295,16 +308,14 @@ static const char* primitiveContactsKernelsCL= \
"\n"
" \n"
" float4 v0 = baseVertex[convexIndices[face->m_indexOffset + face->m_numIndices-1]];\n"
" float4 worldV0 = transform(&v0, &posConvex, &ornConvex);\n"
" \n"
" b = worldV0;\n"
" b = v0;\n"
"\n"
" for(unsigned i=0; i != face->m_numIndices; ++i)\n"
" {\n"
" a = b;\n"
" float4 vi = baseVertex[convexIndices[face->m_indexOffset + i]];\n"
" float4 worldVi = transform(&vi, &posConvex, &ornConvex);\n"
" b = worldVi;\n"
" b = vi;\n"
" ab = b-a;\n"
" ap = p-a;\n"
" v = cross3(ab,plane);\n"
@@ -324,9 +335,9 @@ static const char* primitiveContactsKernelsCL= \
" else\n"
" {\n"
" float s = 1.f - rt;\n"
" out[0].x = s * a.x + rt * b.x;\n"
" out[0].y = s * a.y + rt * b.y;\n"
" out[0].z = s * a.z + rt * b.z;\n"
" out[0].x = s * a.x + rt * b.x;\n"
" out[0].y = s * a.y + rt * b.y;\n"
" out[0].z = s * a.z + rt * b.z;\n"
" }\n"
" return false;\n"
" }\n"
@@ -348,22 +359,22 @@ static const char* primitiveContactsKernelsCL= \
" __global const btGpuFace* faces,\n"
" __global Contact4* restrict globalContactsOut,\n"
" counter32_t nGlobalContactsOut,\n"
" int numPairs)\n"
" int maxContactCapacity,\n"
" float4 spherePos2,\n"
" float radius,\n"
" float4 pos,\n"
" float4 quat\n"
" )\n"
"{\n"
"\n"
" float radius = collidables[collidableIndexA].m_radius;\n"
" float4 spherePos1 = rigidBodies[bodyIndexA].m_pos;\n"
" float4 sphereOrn = rigidBodies[bodyIndexA].m_quat;\n"
" float4 invPos;\n"
" float4 invOrn;\n"
"\n"
" trInverse(pos,quat, &invPos,&invOrn);\n"
"\n"
" float4 spherePos = transform(&spherePos2,&invPos,&invOrn);\n"
"\n"
" float4 pos = rigidBodies[bodyIndexB].m_pos;\n"
" float4 quat = rigidBodies[bodyIndexB].m_quat;\n"
"\n"
" float4 spherePos = spherePos1 - pos;\n"
"\n"
" int collidableIndex = rigidBodies[bodyIndexB].m_collidableIdx;\n"
" int shapeIndex = collidables[collidableIndex].m_shapeIndex;\n"
" int shapeIndex = collidables[collidableIndexB].m_shapeIndex;\n"
" int numFaces = convexShapes[shapeIndex].m_numFaces;\n"
" float4 closestPnt = (float4)(0, 0, 0, 0);\n"
" float4 hitNormalWorld = (float4)(0, 0, 0, 0);\n"
@@ -376,7 +387,8 @@ static const char* primitiveContactsKernelsCL= \
"\n"
" // set up a plane equation \n"
" float4 planeEqn;\n"
" float4 n1 = qtRotate(quat, (float4)(face.m_plane.xyz, 0));\n"
" float4 n1 = face.m_plane;\n"
" n1.w = 0.f;\n"
" planeEqn = n1;\n"
" planeEqn.w = face.m_plane.w;\n"
" \n"
@@ -397,9 +409,9 @@ static const char* primitiveContactsKernelsCL= \
" {\n"
" //might hit an edge or vertex\n"
" float4 out;\n"
" float4 zeroPos = make_float4(0,0,0,0);\n"
"\n"
" bool isInPoly = IsPointInPolygon(spherePos,\n"
" pos,\n"
" quat,\n"
" &face,\n"
" &convexVertices[convexShapes[shapeIndex].m_vertexOffset],\n"
" convexIndices,\n"
@@ -448,32 +460,42 @@ static const char* primitiveContactsKernelsCL= \
"\n"
" \n"
"\n"
" if (bCollide)\n"
" if (bCollide && minDist > -10000)\n"
" {\n"
" float4 normalOnSurfaceB1 = -hitNormalWorld;\n"
" float4 pOnB1 = closestPnt+pos;\n"
" float actualDepth = minDist-radius;\n"
" pOnB1.w = actualDepth;\n"
"\n"
" int dstIdx;\n"
" AppendInc( nGlobalContactsOut, dstIdx );\n"
" float4 normalOnSurfaceB1 = qtRotate(quat,-hitNormalWorld);\n"
" float4 pOnB1 = transform(&closestPnt,&pos,&quat);\n"
" \n"
" if (dstIdx < numPairs)\n"
" float actualDepth = minDist-radius;\n"
" if (actualDepth<=0.f)\n"
" {\n"
" __global Contact4* c = &globalContactsOut[dstIdx];\n"
" c->m_worldNormal = normalOnSurfaceB1;\n"
" c->m_coeffs = (u32)(0.f*0xffff) | ((u32)(0.7f*0xffff)<<16);\n"
" c->m_batchIdx = pairIndex;\n"
" c->m_bodyAPtrAndSignBit = rigidBodies[bodyIndexA].m_invMass==0?-bodyIndexA:bodyIndexA;\n"
" c->m_bodyBPtrAndSignBit = rigidBodies[bodyIndexB].m_invMass==0?-bodyIndexB:bodyIndexB;\n"
" c->m_worldPos[0] = pOnB1;\n"
" GET_NPOINTS(*c) = 1;\n"
" }//if (dstIdx < numPairs)\n"
" \n"
"\n"
" pOnB1.w = actualDepth;\n"
"\n"
" int dstIdx;\n"
" AppendInc( nGlobalContactsOut, dstIdx );\n"
" \n"
" \n"
" if (1)//dstIdx < maxContactCapacity)\n"
" {\n"
" __global Contact4* c = &globalContactsOut[dstIdx];\n"
" c->m_worldNormal = normalOnSurfaceB1;\n"
" c->m_coeffs = (u32)(0.f*0xffff) | ((u32)(0.7f*0xffff)<<16);\n"
" c->m_batchIdx = pairIndex;\n"
" c->m_bodyAPtrAndSignBit = rigidBodies[bodyIndexA].m_invMass==0?-bodyIndexA:bodyIndexA;\n"
" c->m_bodyBPtrAndSignBit = rigidBodies[bodyIndexB].m_invMass==0?-bodyIndexB:bodyIndexB;\n"
" c->m_worldPos[0] = pOnB1;\n"
" GET_NPOINTS(*c) = 1;\n"
" } \n"
"\n"
" }\n"
" }//if (hasCollision)\n"
"\n"
"}\n"
" \n"
"\n"
"\n"
"\n"
" \n"
"void computeContactPlaneConvex(int pairIndex,\n"
" int bodyIndexA, int bodyIndexB, \n"
@@ -483,7 +505,7 @@ static const char* primitiveContactsKernelsCL= \
" __global const btGpuFace* faces,\n"
" __global Contact4* restrict globalContactsOut,\n"
" counter32_t nGlobalContactsOut,\n"
" int numPairs)\n"
" int maxContactCapacity)\n"
"{\n"
" float4 planeEq = faces[collidables[collidableIndexA].m_shapeIndex].m_plane;\n"
" float radius = collidables[collidableIndexB].m_radius;\n"
@@ -522,7 +544,7 @@ static const char* primitiveContactsKernelsCL= \
" int dstIdx;\n"
" AppendInc( nGlobalContactsOut, dstIdx );\n"
" \n"
" if (dstIdx < numPairs)\n"
" if (dstIdx < maxContactCapacity)\n"
" {\n"
" __global Contact4* c = &globalContactsOut[dstIdx];\n"
" c->m_worldNormal = normalOnSurfaceB1;\n"
@@ -549,7 +571,7 @@ static const char* primitiveContactsKernelsCL= \
" __global const int* indices,\n"
" __global Contact4* restrict globalContactsOut,\n"
" counter32_t nGlobalContactsOut,\n"
" int numPairs)\n"
" int numPairs, int maxContactCapacity)\n"
"{\n"
"\n"
" int i = get_global_id(0);\n"
@@ -581,7 +603,7 @@ static const char* primitiveContactsKernelsCL= \
"\n"
"\n"
" computeContactPlaneConvex( pairIndex, bodyIndexB,bodyIndexA, collidableIndexB,collidableIndexA, \n"
" rigidBodies,collidables,faces, globalContactsOut, nGlobalContactsOut,numPairs);\n"
" rigidBodies,collidables,faces, globalContactsOut, nGlobalContactsOut,maxContactCapacity);\n"
" return;\n"
" }\n"
"\n"
@@ -591,7 +613,7 @@ static const char* primitiveContactsKernelsCL= \
"\n"
"\n"
" computeContactPlaneConvex(pairIndex, bodyIndexA, bodyIndexB, collidableIndexA, collidableIndexB, \n"
" rigidBodies,collidables,faces, globalContactsOut, nGlobalContactsOut,numPairs);\n"
" rigidBodies,collidables,faces, globalContactsOut, nGlobalContactsOut,maxContactCapacity);\n"
" return;\n"
" \n"
" }\n"
@@ -600,8 +622,15 @@ static const char* primitiveContactsKernelsCL= \
" collidables[collidableIndexB].m_shapeType == SHAPE_CONVEX_HULL)\n"
" {\n"
" \n"
" float4 spherePos = rigidBodies[bodyIndexA].m_pos;\n"
" float sphereRadius = collidables[collidableIndexA].m_radius;\n"
" float4 convexPos = rigidBodies[bodyIndexB].m_pos;\n"
" float4 convexOrn = rigidBodies[bodyIndexB].m_quat;\n"
"\n"
" computeContactSphereConvex(pairIndex, bodyIndexA, bodyIndexB, collidableIndexA, collidableIndexB, \n"
" rigidBodies,collidables,convexShapes,vertices,indices,faces, globalContactsOut, nGlobalContactsOut,numPairs);\n"
" rigidBodies,collidables,convexShapes,vertices,indices,faces, globalContactsOut, nGlobalContactsOut,maxContactCapacity,\n"
" spherePos,sphereRadius,convexPos,convexOrn);\n"
"\n"
" return;\n"
" }\n"
"\n"
@@ -609,8 +638,14 @@ static const char* primitiveContactsKernelsCL= \
" collidables[collidableIndexB].m_shapeType == SHAPE_SPHERE)\n"
" {\n"
" \n"
" float4 spherePos = rigidBodies[bodyIndexB].m_pos;\n"
" float sphereRadius = collidables[collidableIndexB].m_radius;\n"
" float4 convexPos = rigidBodies[bodyIndexA].m_pos;\n"
" float4 convexOrn = rigidBodies[bodyIndexA].m_quat;\n"
"\n"
" computeContactSphereConvex(pairIndex, bodyIndexB, bodyIndexA, collidableIndexB, collidableIndexA, \n"
" rigidBodies,collidables,convexShapes,vertices,indices,faces, globalContactsOut, nGlobalContactsOut,numPairs);\n"
" rigidBodies,collidables,convexShapes,vertices,indices,faces, globalContactsOut, nGlobalContactsOut,maxContactCapacity,\n"
" spherePos,sphereRadius,convexPos,convexOrn);\n"
" return;\n"
" }\n"
" \n"
@@ -644,9 +679,9 @@ static const char* primitiveContactsKernelsCL= \
" contactPosB.w = dist;\n"
" \n"
" int dstIdx;\n"
" AppendInc( nGlobalContactsOut, dstIdx );\n"
" AppendInc( nGlobalContactsOut, dstIdx );\n"
" \n"
" if (dstIdx < numPairs)\n"
" if (dstIdx < maxContactCapacity)\n"
" {\n"
" __global Contact4* c = &globalContactsOut[dstIdx];\n"
" c->m_worldNormal = -normalOnSurfaceB;\n"
@@ -668,4 +703,371 @@ static const char* primitiveContactsKernelsCL= \
"\n"
"}\n"
"\n"
"\n"
"// work-in-progress\n"
"__kernel void processCompoundPairsPrimitivesKernel( __global const int4* gpuCompoundPairs,\n"
" __global const BodyData* rigidBodies, \n"
" __global const btCollidableGpu* collidables,\n"
" __global const ConvexPolyhedronCL* convexShapes, \n"
" __global const float4* vertices,\n"
" __global const float4* uniqueEdges,\n"
" __global const btGpuFace* faces,\n"
" __global const int* indices,\n"
" __global btAabbCL* aabbs,\n"
" __global const btGpuChildShape* gpuChildShapes,\n"
" __global Contact4* restrict globalContactsOut,\n"
" counter32_t nGlobalContactsOut,\n"
" int numCompoundPairs, int maxContactCapacity\n"
" )\n"
"{\n"
"\n"
" int i = get_global_id(0);\n"
" if (i<numCompoundPairs)\n"
" {\n"
" int bodyIndexA = gpuCompoundPairs[i].x;\n"
" int bodyIndexB = gpuCompoundPairs[i].y;\n"
"\n"
" int childShapeIndexA = gpuCompoundPairs[i].z;\n"
" int childShapeIndexB = gpuCompoundPairs[i].w;\n"
" \n"
" int collidableIndexA = -1;\n"
" int collidableIndexB = -1;\n"
" \n"
" float4 ornA = rigidBodies[bodyIndexA].m_quat;\n"
" float4 posA = rigidBodies[bodyIndexA].m_pos;\n"
" \n"
" float4 ornB = rigidBodies[bodyIndexB].m_quat;\n"
" float4 posB = rigidBodies[bodyIndexB].m_pos;\n"
" \n"
" if (childShapeIndexA >= 0)\n"
" {\n"
" collidableIndexA = gpuChildShapes[childShapeIndexA].m_shapeIndex;\n"
" float4 childPosA = gpuChildShapes[childShapeIndexA].m_childPosition;\n"
" float4 childOrnA = gpuChildShapes[childShapeIndexA].m_childOrientation;\n"
" float4 newPosA = qtRotate(ornA,childPosA)+posA;\n"
" float4 newOrnA = qtMul(ornA,childOrnA);\n"
" posA = newPosA;\n"
" ornA = newOrnA;\n"
" } else\n"
" {\n"
" collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;\n"
" }\n"
" \n"
" if (childShapeIndexB>=0)\n"
" {\n"
" collidableIndexB = gpuChildShapes[childShapeIndexB].m_shapeIndex;\n"
" float4 childPosB = gpuChildShapes[childShapeIndexB].m_childPosition;\n"
" float4 childOrnB = gpuChildShapes[childShapeIndexB].m_childOrientation;\n"
" float4 newPosB = transform(&childPosB,&posB,&ornB);\n"
" float4 newOrnB = qtMul(ornB,childOrnB);\n"
" posB = newPosB;\n"
" ornB = newOrnB;\n"
" } else\n"
" {\n"
" collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx; \n"
" }\n"
" \n"
" int shapeIndexA = collidables[collidableIndexA].m_shapeIndex;\n"
" int shapeIndexB = collidables[collidableIndexB].m_shapeIndex;\n"
" \n"
" int shapeTypeA = collidables[collidableIndexA].m_shapeType;\n"
" int shapeTypeB = collidables[collidableIndexB].m_shapeType;\n"
"\n"
" int pairIndex = i;\n"
" if ((shapeTypeA == SHAPE_CONVEX_HULL) && (shapeTypeB == SHAPE_SPHERE))\n"
" {\n"
" float4 spherePos = rigidBodies[bodyIndexB].m_pos;\n"
" float sphereRadius = collidables[collidableIndexB].m_radius;\n"
" float4 convexPos = posA;\n"
" float4 convexOrn = ornA;\n"
" \n"
" computeContactSphereConvex(pairIndex, bodyIndexB, bodyIndexA , collidableIndexB,collidableIndexA, \n"
" rigidBodies,collidables,convexShapes,vertices,indices,faces, globalContactsOut, nGlobalContactsOut,maxContactCapacity,\n"
" spherePos,sphereRadius,convexPos,convexOrn);\n"
" \n"
" return;\n"
" }\n"
"\n"
" if ((shapeTypeA == SHAPE_SPHERE) && (shapeTypeB == SHAPE_CONVEX_HULL))\n"
" {\n"
"\n"
" float4 spherePos = rigidBodies[bodyIndexA].m_pos;\n"
" float sphereRadius = collidables[collidableIndexA].m_radius;\n"
" float4 convexPos = posB;\n"
" float4 convexOrn = ornB;\n"
"\n"
" \n"
" computeContactSphereConvex(pairIndex, bodyIndexA, bodyIndexB, collidableIndexA, collidableIndexB, \n"
" rigidBodies,collidables,convexShapes,vertices,indices,faces, globalContactsOut, nGlobalContactsOut,maxContactCapacity,\n"
" spherePos,sphereRadius,convexPos,convexOrn);\n"
" \n"
" return;\n"
" }\n"
" }// if (i<numCompoundPairs)\n"
"}\n"
"\n"
"\n"
"bool pointInTriangle(const float4* vertices, const float4* normal, float4 *p )\n"
"{\n"
"\n"
" const float4* p1 = &vertices[0];\n"
" const float4* p2 = &vertices[1];\n"
" const float4* p3 = &vertices[2];\n"
"\n"
" float4 edge1; edge1 = (*p2 - *p1);\n"
" float4 edge2; edge2 = ( *p3 - *p2 );\n"
" float4 edge3; edge3 = ( *p1 - *p3 );\n"
"\n"
" \n"
" float4 p1_to_p; p1_to_p = ( *p - *p1 );\n"
" float4 p2_to_p; p2_to_p = ( *p - *p2 );\n"
" float4 p3_to_p; p3_to_p = ( *p - *p3 );\n"
"\n"
" float4 edge1_normal; edge1_normal = ( cross(edge1,*normal));\n"
" float4 edge2_normal; edge2_normal = ( cross(edge2,*normal));\n"
" float4 edge3_normal; edge3_normal = ( cross(edge3,*normal));\n"
"\n"
" \n"
" \n"
" float r1, r2, r3;\n"
" r1 = dot(edge1_normal,p1_to_p );\n"
" r2 = dot(edge2_normal,p2_to_p );\n"
" r3 = dot(edge3_normal,p3_to_p );\n"
" \n"
" if ( r1 > 0 && r2 > 0 && r3 > 0 )\n"
" return true;\n"
" if ( r1 <= 0 && r2 <= 0 && r3 <= 0 ) \n"
" return true;\n"
" return false;\n"
"\n"
"}\n"
"\n"
"\n"
"float segmentSqrDistance(float4 from, float4 to,float4 p, float4* nearest) \n"
"{\n"
" float4 diff = p - from;\n"
" float4 v = to - from;\n"
" float t = dot(v,diff);\n"
" \n"
" if (t > 0) \n"
" {\n"
" float dotVV = dot(v,v);\n"
" if (t < dotVV) \n"
" {\n"
" t /= dotVV;\n"
" diff -= t*v;\n"
" } else \n"
" {\n"
" t = 1;\n"
" diff -= v;\n"
" }\n"
" } else\n"
" {\n"
" t = 0;\n"
" }\n"
" *nearest = from + t*v;\n"
" return dot(diff,diff); \n"
"}\n"
"\n"
"\n"
"void computeContactSphereTriangle(int pairIndex,\n"
" int bodyIndexA, int bodyIndexB,\n"
" int collidableIndexA, int collidableIndexB, \n"
" __global const BodyData* rigidBodies, \n"
" __global const btCollidableGpu* collidables,\n"
" const float4* triangleVertices,\n"
" __global Contact4* restrict globalContactsOut,\n"
" counter32_t nGlobalContactsOut,\n"
" int maxContactCapacity,\n"
" float4 spherePos2,\n"
" float radius,\n"
" float4 pos,\n"
" float4 quat\n"
" )\n"
"{\n"
"\n"
" float4 invPos;\n"
" float4 invOrn;\n"
"\n"
" trInverse(pos,quat, &invPos,&invOrn);\n"
" float4 spherePos = transform(&spherePos2,&invPos,&invOrn);\n"
" int numFaces = 3;\n"
" float4 closestPnt = (float4)(0, 0, 0, 0);\n"
" float4 hitNormalWorld = (float4)(0, 0, 0, 0);\n"
" float minDist = -1000000.f;\n"
" bool bCollide = true;\n"
"\n"
" \n"
" //////////////////////////////////////\n"
"\n"
" float4 sphereCenter;\n"
" sphereCenter = spherePos;\n"
"\n"
" const float4* vertices = triangleVertices;\n"
" float contactBreakingThreshold = 0.f;//todo?\n"
" float radiusWithThreshold = radius + contactBreakingThreshold;\n"
" float4 edge10;\n"
" edge10 = vertices[1]-vertices[0];\n"
" edge10.w = 0.f;//is this needed?\n"
" float4 edge20;\n"
" edge20 = vertices[2]-vertices[0];\n"
" edge20.w = 0.f;//is this needed?\n"
" float4 normal = cross3(edge10,edge20);\n"
" normal = normalize(normal);\n"
" float4 p1ToCenter;\n"
" p1ToCenter = sphereCenter - vertices[0];\n"
" \n"
" float distanceFromPlane = dot(p1ToCenter,normal);\n"
"\n"
" if (distanceFromPlane < 0.f)\n"
" {\n"
" //triangle facing the other way\n"
" distanceFromPlane *= -1.f;\n"
" normal *= -1.f;\n"
" }\n"
" hitNormalWorld = normal;\n"
"\n"
" bool isInsideContactPlane = distanceFromPlane < radiusWithThreshold;\n"
" \n"
" // Check for contact / intersection\n"
" bool hasContact = false;\n"
" float4 contactPoint;\n"
" if (isInsideContactPlane) \n"
" {\n"
" \n"
" if (pointInTriangle(vertices,&normal, &sphereCenter)) \n"
" {\n"
" // Inside the contact wedge - touches a point on the shell plane\n"
" hasContact = true;\n"
" contactPoint = sphereCenter - normal*distanceFromPlane;\n"
" \n"
" } else {\n"
" // Could be inside one of the contact capsules\n"
" float contactCapsuleRadiusSqr = radiusWithThreshold*radiusWithThreshold;\n"
" float4 nearestOnEdge;\n"
" int numEdges = 3;\n"
" for (int i = 0; i < numEdges; i++) \n"
" {\n"
" float4 pa =vertices[i];\n"
" float4 pb = vertices[(i+1)%3];\n"
"\n"
" float distanceSqr = segmentSqrDistance(pa,pb,sphereCenter, &nearestOnEdge);\n"
" if (distanceSqr < contactCapsuleRadiusSqr) \n"
" {\n"
" // Yep, we're inside a capsule\n"
" hasContact = true;\n"
" contactPoint = nearestOnEdge;\n"
" \n"
" }\n"
" \n"
" }\n"
" }\n"
" }\n"
"\n"
" if (hasContact) \n"
" {\n"
"\n"
" closestPnt = contactPoint;\n"
" float4 contactToCenter = sphereCenter - contactPoint;\n"
" minDist = length(contactToCenter);\n"
" if (minDist>0.f)\n"
" {\n"
" hitNormalWorld = normalize(contactToCenter);//*(1./minDist);\n"
" }\n"
" bCollide = true;\n"
" }\n"
"\n"
"\n"
" /////////////////////////////////////\n"
"\n"
" if (bCollide && minDist > -10000)\n"
" {\n"
" \n"
" float4 normalOnSurfaceB1 = qtRotate(quat,-hitNormalWorld);\n"
" float4 pOnB1 = transform(&closestPnt,&pos,&quat);\n"
" float actualDepth = minDist-radius;\n"
"\n"
" \n"
" if (actualDepth<=0.f)\n"
" {\n"
" pOnB1.w = actualDepth;\n"
" int dstIdx;\n"
" AppendInc( nGlobalContactsOut, dstIdx );\n"
" \n"
" if (dstIdx < maxContactCapacity)\n"
" {\n"
" __global Contact4* c = &globalContactsOut[dstIdx];\n"
" c->m_worldNormal = normalOnSurfaceB1;\n"
" c->m_coeffs = (u32)(0.f*0xffff) | ((u32)(0.7f*0xffff)<<16);\n"
" c->m_batchIdx = pairIndex;\n"
" c->m_bodyAPtrAndSignBit = rigidBodies[bodyIndexA].m_invMass==0?-bodyIndexA:bodyIndexA;\n"
" c->m_bodyBPtrAndSignBit = rigidBodies[bodyIndexB].m_invMass==0?-bodyIndexB:bodyIndexB;\n"
" c->m_worldPos[0] = pOnB1;\n"
" GET_NPOINTS(*c) = 1;\n"
" } \n"
"\n"
" }\n"
" }//if (hasCollision)\n"
"\n"
"}\n"
"\n"
"\n"
"\n"
"// work-in-progress\n"
"__kernel void findConcaveSphereContactsKernel( __global int4* concavePairs,\n"
" __global const BodyData* rigidBodies,\n"
" __global const btCollidableGpu* collidables,\n"
" __global const ConvexPolyhedronCL* convexShapes, \n"
" __global const float4* vertices,\n"
" __global const float4* uniqueEdges,\n"
" __global const btGpuFace* faces,\n"
" __global const int* indices,\n"
" __global btAabbCL* aabbs,\n"
" __global Contact4* restrict globalContactsOut,\n"
" counter32_t nGlobalContactsOut,\n"
" int numConcavePairs, int maxContactCapacity\n"
" )\n"
"{\n"
"\n"
" int i = get_global_id(0);\n"
" if (i>=numConcavePairs)\n"
" return;\n"
" int pairIdx = i;\n"
"\n"
" int bodyIndexA = concavePairs[i].x;\n"
" int bodyIndexB = concavePairs[i].y;\n"
"\n"
" int collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;\n"
" int collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx;\n"
"\n"
" int shapeIndexA = collidables[collidableIndexA].m_shapeIndex;\n"
" int shapeIndexB = collidables[collidableIndexB].m_shapeIndex;\n"
"\n"
" if (collidables[collidableIndexB].m_shapeType==SHAPE_SPHERE)\n"
" {\n"
" int f = concavePairs[i].z;\n"
" btGpuFace face = faces[convexShapes[shapeIndexA].m_faceOffset+f];\n"
" \n"
" float4 verticesA[3];\n"
" for (int i=0;i<3;i++)\n"
" {\n"
" int index = indices[face.m_indexOffset+i];\n"
" float4 vert = vertices[convexShapes[shapeIndexA].m_vertexOffset+index];\n"
" verticesA[i] = vert;\n"
" }\n"
"\n"
" float4 spherePos = rigidBodies[bodyIndexB].m_pos;\n"
" float sphereRadius = collidables[collidableIndexB].m_radius;\n"
" float4 convexPos = rigidBodies[bodyIndexA].m_pos;\n"
" float4 convexOrn = rigidBodies[bodyIndexA].m_quat;\n"
"\n"
" computeContactSphereTriangle(i, bodyIndexB, bodyIndexA, collidableIndexB, collidableIndexA, \n"
" rigidBodies,collidables,\n"
" verticesA,\n"
" globalContactsOut, nGlobalContactsOut,maxContactCapacity,\n"
" spherePos,sphereRadius,convexPos,convexOrn);\n"
"\n"
" return;\n"
" }\n"
"}\n"
;