#define TRIANGLE_NUM_CONVEX_FACES 5 #pragma OPENCL EXTENSION cl_amd_printf : enable #pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable #pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable #pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics : enable #pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable #ifdef cl_ext_atomic_counters_32 #pragma OPENCL EXTENSION cl_ext_atomic_counters_32 : enable #else #define counter32_t volatile __global int* #endif #define GET_GROUP_IDX get_group_id(0) #define GET_LOCAL_IDX get_local_id(0) #define GET_GLOBAL_IDX get_global_id(0) #define GET_GROUP_SIZE get_local_size(0) #define GET_NUM_GROUPS get_num_groups(0) #define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE) #define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE) #define AtomInc(x) atom_inc(&(x)) #define AtomInc1(x, out) out = atom_inc(&(x)) #define AppendInc(x, out) out = atomic_inc(x) #define AtomAdd(x, value) atom_add(&(x), value) #define AtomCmpxhg(x, cmp, value) atom_cmpxchg( &(x), cmp, value ) #define AtomXhg(x, value) atom_xchg ( &(x), value ) #define max2 max #define min2 min typedef unsigned int u32; #include "Bullet3Collision/NarrowPhaseCollision/shared/b3Contact4Data.h" #include "Bullet3Collision/NarrowPhaseCollision/shared/b3ConvexPolyhedronData.h" #include "Bullet3Collision/NarrowPhaseCollision/shared/b3Collidable.h" #include "Bullet3Collision/NarrowPhaseCollision/shared/b3RigidBodyData.h" #define GET_NPOINTS(x) (x).m_worldNormalOnB.w #define SELECT_UINT4( b, a, condition ) select( b,a,condition ) #define make_float4 (float4) #define make_float2 (float2) #define make_uint4 (uint4) #define make_int4 (int4) #define make_uint2 (uint2) #define make_int2 (int2) __inline float fastDiv(float numerator, float denominator) { return native_divide(numerator, denominator); // return numerator/denominator; } __inline float4 fastDiv4(float4 numerator, float4 denominator) { return native_divide(numerator, denominator); } __inline float4 cross3(float4 a, float4 b) { return cross(a,b); } //#define dot3F4 dot __inline float dot3F4(float4 a, float4 b) { float4 a1 = make_float4(a.xyz,0.f); float4 b1 = make_float4(b.xyz,0.f); return dot(a1, b1); } __inline float4 fastNormalize4(float4 v) { return fast_normalize(v); } /////////////////////////////////////// // Quaternion /////////////////////////////////////// typedef float4 Quaternion; __inline Quaternion qtMul(Quaternion a, Quaternion b); __inline Quaternion qtNormalize(Quaternion in); __inline float4 qtRotate(Quaternion q, float4 vec); __inline Quaternion qtInvert(Quaternion q); __inline Quaternion qtMul(Quaternion a, Quaternion b) { Quaternion ans; ans = cross3( a, b ); ans += a.w*b+b.w*a; // ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z); ans.w = a.w*b.w - dot3F4(a, b); return ans; } __inline Quaternion qtNormalize(Quaternion in) { return fastNormalize4(in); // in /= length( in ); // return in; } __inline float4 qtRotate(Quaternion q, float4 vec) { Quaternion qInv = qtInvert( q ); float4 vcpy = vec; vcpy.w = 0.f; float4 out = qtMul(qtMul(q,vcpy),qInv); return out; } __inline Quaternion qtInvert(Quaternion q) { return (Quaternion)(-q.xyz, q.w); } __inline float4 qtInvRotate(const Quaternion q, float4 vec) { return qtRotate( qtInvert( q ), vec ); } __inline float4 transform(const float4* p, const float4* translation, const Quaternion* orientation) { return qtRotate( *orientation, *p ) + (*translation); } __inline float4 normalize3(const float4 a) { float4 n = make_float4(a.x, a.y, a.z, 0.f); return fastNormalize4( n ); } __inline float4 lerp3(const float4 a,const float4 b, float t) { return make_float4( a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t, 0.f); } // Clips a face to the back of a plane, return the number of vertices out, stored in ppVtxOut int clipFaceGlobal(__global const float4* pVtxIn, int numVertsIn, float4 planeNormalWS,float planeEqWS, __global float4* ppVtxOut) { int ve; float ds, de; int numVertsOut = 0; //double-check next test if (numVertsIn < 2) return 0; float4 firstVertex=pVtxIn[numVertsIn-1]; float4 endVertex = pVtxIn[0]; ds = dot3F4(planeNormalWS,firstVertex)+planeEqWS; for (ve = 0; ve < numVertsIn; ve++) { endVertex=pVtxIn[ve]; de = dot3F4(planeNormalWS,endVertex)+planeEqWS; if (ds<0) { if (de<0) { // Start < 0, end < 0, so output endVertex ppVtxOut[numVertsOut++] = endVertex; } else { // Start < 0, end >= 0, so output intersection ppVtxOut[numVertsOut++] = lerp3(firstVertex, endVertex,(ds * 1.f/(ds - de)) ); } } else { if (de<0) { // Start >= 0, end < 0 so output intersection and end ppVtxOut[numVertsOut++] = lerp3(firstVertex, endVertex,(ds * 1.f/(ds - de)) ); ppVtxOut[numVertsOut++] = endVertex; } } firstVertex = endVertex; ds = de; } return numVertsOut; } // Clips a face to the back of a plane, return the number of vertices out, stored in ppVtxOut int clipFace(const float4* pVtxIn, int numVertsIn, float4 planeNormalWS,float planeEqWS, float4* ppVtxOut) { int ve; float ds, de; int numVertsOut = 0; //double-check next test if (numVertsIn < 2) return 0; float4 firstVertex=pVtxIn[numVertsIn-1]; float4 endVertex = pVtxIn[0]; ds = dot3F4(planeNormalWS,firstVertex)+planeEqWS; for (ve = 0; ve < numVertsIn; ve++) { endVertex=pVtxIn[ve]; de = dot3F4(planeNormalWS,endVertex)+planeEqWS; if (ds<0) { if (de<0) { // Start < 0, end < 0, so output endVertex ppVtxOut[numVertsOut++] = endVertex; } else { // Start < 0, end >= 0, so output intersection ppVtxOut[numVertsOut++] = lerp3(firstVertex, endVertex,(ds * 1.f/(ds - de)) ); } } else { if (de<0) { // Start >= 0, end < 0 so output intersection and end ppVtxOut[numVertsOut++] = lerp3(firstVertex, endVertex,(ds * 1.f/(ds - de)) ); ppVtxOut[numVertsOut++] = endVertex; } } firstVertex = endVertex; ds = de; } return numVertsOut; } int clipFaceAgainstHull(const float4 separatingNormal, __global const b3ConvexPolyhedronData_t* hullA, const float4 posA, const Quaternion ornA, float4* worldVertsB1, int numWorldVertsB1, float4* worldVertsB2, int capacityWorldVertsB2, const float minDist, float maxDist, __global const float4* vertices, __global const b3GpuFace_t* faces, __global const int* indices, float4* contactsOut, int contactCapacity) { int numContactsOut = 0; float4* pVtxIn = worldVertsB1; float4* pVtxOut = worldVertsB2; int numVertsIn = numWorldVertsB1; int numVertsOut = 0; int closestFaceA=-1; { float dmin = FLT_MAX; for(int face=0;facem_numFaces;face++) { const float4 Normal = make_float4( faces[hullA->m_faceOffset+face].m_plane.x, faces[hullA->m_faceOffset+face].m_plane.y, faces[hullA->m_faceOffset+face].m_plane.z,0.f); const float4 faceANormalWS = qtRotate(ornA,Normal); float d = dot3F4(faceANormalWS,separatingNormal); if (d < dmin) { dmin = d; closestFaceA = face; } } } if (closestFaceA<0) return numContactsOut; b3GpuFace_t polyA = faces[hullA->m_faceOffset+closestFaceA]; // clip polygon to back of planes of all faces of hull A that are adjacent to witness face int numVerticesA = polyA.m_numIndices; for(int e0=0;e0m_vertexOffset+indices[polyA.m_indexOffset+e0]]; const float4 b = vertices[hullA->m_vertexOffset+indices[polyA.m_indexOffset+((e0+1)%numVerticesA)]]; const float4 edge0 = a - b; const float4 WorldEdge0 = qtRotate(ornA,edge0); float4 planeNormalA = make_float4(polyA.m_plane.x,polyA.m_plane.y,polyA.m_plane.z,0.f); float4 worldPlaneAnormal1 = qtRotate(ornA,planeNormalA); float4 planeNormalWS1 = -cross3(WorldEdge0,worldPlaneAnormal1); float4 worldA1 = transform(&a,&posA,&ornA); float planeEqWS1 = -dot3F4(worldA1,planeNormalWS1); float4 planeNormalWS = planeNormalWS1; float planeEqWS=planeEqWS1; //clip face //clipFace(*pVtxIn, *pVtxOut,planeNormalWS,planeEqWS); numVertsOut = clipFace(pVtxIn, numVertsIn, planeNormalWS,planeEqWS, pVtxOut); //btSwap(pVtxIn,pVtxOut); float4* tmp = pVtxOut; pVtxOut = pVtxIn; pVtxIn = tmp; numVertsIn = numVertsOut; numVertsOut = 0; } // only keep points that are behind the witness face { float4 localPlaneNormal = make_float4(polyA.m_plane.x,polyA.m_plane.y,polyA.m_plane.z,0.f); float localPlaneEq = polyA.m_plane.w; float4 planeNormalWS = qtRotate(ornA,localPlaneNormal); float planeEqWS=localPlaneEq-dot3F4(planeNormalWS,posA); for (int i=0;im_numFaces;face++) { const float4 Normal = make_float4( facesA[hullA->m_faceOffset+face].m_plane.x, facesA[hullA->m_faceOffset+face].m_plane.y, facesA[hullA->m_faceOffset+face].m_plane.z,0.f); const float4 faceANormalWS = qtRotate(ornA,Normal); float d = dot3F4(faceANormalWS,separatingNormal); if (d < dmin) { dmin = d; closestFaceA = face; } } } if (closestFaceA<0) return numContactsOut; b3GpuFace_t polyA = facesA[hullA->m_faceOffset+closestFaceA]; // clip polygon to back of planes of all faces of hull A that are adjacent to witness face int numVerticesA = polyA.m_numIndices; for(int e0=0;e0m_vertexOffset+indicesA[polyA.m_indexOffset+e0]]; const float4 b = verticesA[hullA->m_vertexOffset+indicesA[polyA.m_indexOffset+((e0+1)%numVerticesA)]]; const float4 edge0 = a - b; const float4 WorldEdge0 = qtRotate(ornA,edge0); float4 planeNormalA = make_float4(polyA.m_plane.x,polyA.m_plane.y,polyA.m_plane.z,0.f); float4 worldPlaneAnormal1 = qtRotate(ornA,planeNormalA); float4 planeNormalWS1 = -cross3(WorldEdge0,worldPlaneAnormal1); float4 worldA1 = transform(&a,&posA,&ornA); float planeEqWS1 = -dot3F4(worldA1,planeNormalWS1); float4 planeNormalWS = planeNormalWS1; float planeEqWS=planeEqWS1; //clip face //clipFace(*pVtxIn, *pVtxOut,planeNormalWS,planeEqWS); numVertsOut = clipFace(pVtxIn, numVertsIn, planeNormalWS,planeEqWS, pVtxOut); //btSwap(pVtxIn,pVtxOut); float4* tmp = pVtxOut; pVtxOut = pVtxIn; pVtxIn = tmp; numVertsIn = numVertsOut; numVertsOut = 0; } // only keep points that are behind the witness face { float4 localPlaneNormal = make_float4(polyA.m_plane.x,polyA.m_plane.y,polyA.m_plane.z,0.f); float localPlaneEq = polyA.m_plane.w; float4 planeNormalWS = qtRotate(ornA,localPlaneNormal); float planeEqWS=localPlaneEq-dot3F4(planeNormalWS,posA); for (int i=0;im_numFaces;face++) { const float4 Normal = make_float4(faces[hullB->m_faceOffset+face].m_plane.x, faces[hullB->m_faceOffset+face].m_plane.y, faces[hullB->m_faceOffset+face].m_plane.z,0.f); const float4 WorldNormal = qtRotate(ornB, Normal); float d = dot3F4(WorldNormal,separatingNormal); if (d > dmax) { dmax = d; closestFaceB = face; } } } { const b3GpuFace_t polyB = faces[hullB->m_faceOffset+closestFaceB]; const int numVertices = polyB.m_numIndices; for(int e0=0;e0m_vertexOffset+indices[polyB.m_indexOffset+e0]]; worldVertsB1[numWorldVertsB1++] = transform(&b,&posB,&ornB); } } if (closestFaceB>=0) { numContactsOut = clipFaceAgainstHull(separatingNormal, hullA, posA,ornA, worldVertsB1,numWorldVertsB1,worldVertsB2,capacityWorldVerts, minDist, maxDist,vertices, faces, indices,localContactsOut,localContactCapacity); } return numContactsOut; } int clipHullAgainstHullLocalA(const float4 separatingNormal, const b3ConvexPolyhedronData_t* hullA, __global const b3ConvexPolyhedronData_t* hullB, const float4 posA, const Quaternion ornA,const float4 posB, const Quaternion ornB, float4* worldVertsB1, float4* worldVertsB2, int capacityWorldVerts, const float minDist, float maxDist, const float4* verticesA, const b3GpuFace_t* facesA, const int* indicesA, __global const float4* verticesB, __global const b3GpuFace_t* facesB, __global const int* indicesB, float4* localContactsOut, int localContactCapacity) { int numContactsOut = 0; int numWorldVertsB1= 0; int closestFaceB=-1; float dmax = -FLT_MAX; { for(int face=0;facem_numFaces;face++) { const float4 Normal = make_float4(facesB[hullB->m_faceOffset+face].m_plane.x, facesB[hullB->m_faceOffset+face].m_plane.y, facesB[hullB->m_faceOffset+face].m_plane.z,0.f); const float4 WorldNormal = qtRotate(ornB, Normal); float d = dot3F4(WorldNormal,separatingNormal); if (d > dmax) { dmax = d; closestFaceB = face; } } } { const b3GpuFace_t polyB = facesB[hullB->m_faceOffset+closestFaceB]; const int numVertices = polyB.m_numIndices; for(int e0=0;e0m_vertexOffset+indicesB[polyB.m_indexOffset+e0]]; worldVertsB1[numWorldVertsB1++] = transform(&b,&posB,&ornB); } } if (closestFaceB>=0) { numContactsOut = clipFaceAgainstHullLocalA(separatingNormal, hullA, posA,ornA, worldVertsB1,numWorldVertsB1,worldVertsB2,capacityWorldVerts, minDist, maxDist, verticesA,facesA,indicesA, verticesB,facesB,indicesB, localContactsOut,localContactCapacity); } return numContactsOut; } #define PARALLEL_SUM(v, n) for(int j=1; j v[i+offset].y)? v[i]: v[i+offset]; } #define REDUCE_MIN(v, n) {int i=0;\ for(int offset=0; offset64) nPoints = 64; float4 center = make_float4(0.f); { for (int i=0;i a[ie].x )? a[0].x: a[ie].x; a[0].y = (a[0].y > a[ie].y )? a[0].y: a[ie].y; a[0].z = (a[0].z > a[ie].z )? a[0].z: a[ie].z; a[0].w = (a[0].w > a[ie].w )? a[0].w: a[ie].w; } idx[0] = (int)a[0].x & 0xff; idx[1] = (int)a[0].y & 0xff; idx[2] = (int)a[0].z & 0xff; idx[3] = (int)a[0].w & 0xff; } } { float2 h[64]; PARALLEL_DO( h[ie] = make_float2((float)ie, p[ie].w), nPoints ); REDUCE_MIN( h, nPoints ); max00 = h[0]; } } contactIdx[0] = idx[0]; contactIdx[1] = idx[1]; contactIdx[2] = idx[2]; contactIdx[3] = idx[3]; return 4; } } __kernel void extractManifoldAndAddContactKernel(__global const int4* pairs, __global const b3RigidBodyData_t* rigidBodies, __global const float4* closestPointsWorld, __global const float4* separatingNormalsWorld, __global const int* contactCounts, __global const int* contactOffsets, __global struct b3Contact4Data* restrict contactsOut, counter32_t nContactsOut, int contactCapacity, int numPairs, int pairIndex ) { int idx = get_global_id(0); if (idxm_worldNormalOnB = -normal; c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff); c->m_batchIdx = idx; int bodyA = pairs[pairIndex].x; int bodyB = pairs[pairIndex].y; c->m_bodyAPtrAndSignBit = rigidBodies[bodyA].m_invMass==0 ? -bodyA:bodyA; c->m_bodyBPtrAndSignBit = rigidBodies[bodyB].m_invMass==0 ? -bodyB:bodyB; c->m_childIndexA = -1; c->m_childIndexB = -1; for (int i=0;im_worldPosB[i] = localPoints[contactIdx[i]]; } GET_NPOINTS(*c) = nContacts; } } } void trInverse(float4 translationIn, Quaternion orientationIn, float4* translationOut, Quaternion* orientationOut) { *orientationOut = qtInvert(orientationIn); *translationOut = qtRotate(*orientationOut, -translationIn); } void trMul(float4 translationA, Quaternion orientationA, float4 translationB, Quaternion orientationB, float4* translationOut, Quaternion* orientationOut) { *orientationOut = qtMul(orientationA,orientationB); *translationOut = transform(&translationB,&translationA,&orientationA); } __kernel void clipHullHullKernel( __global int4* pairs, __global const b3RigidBodyData_t* rigidBodies, __global const b3Collidable_t* collidables, __global const b3ConvexPolyhedronData_t* convexShapes, __global const float4* vertices, __global const float4* uniqueEdges, __global const b3GpuFace_t* faces, __global const int* indices, __global const float4* separatingNormals, __global const int* hasSeparatingAxis, __global struct b3Contact4Data* restrict globalContactsOut, counter32_t nGlobalContactsOut, int numPairs, int contactCapacity) { int i = get_global_id(0); int pairIndex = i; float4 worldVertsB1[64]; float4 worldVertsB2[64]; int capacityWorldVerts = 64; float4 localContactsOut[64]; int localContactCapacity=64; float minDist = -1e30f; float maxDist = 0.02f; if (i0) { float4 normal = -separatingNormals[i]; int nPoints = numLocalContactsOut; float4* pointsIn = localContactsOut; int contactIdx[4];// = {-1,-1,-1,-1}; contactIdx[0] = -1; contactIdx[1] = -1; contactIdx[2] = -1; contactIdx[3] = -1; int nReducedContacts = extractManifoldSequential(pointsIn, nPoints, normal, contactIdx); int mprContactIndex = pairs[pairIndex].z; int dstIdx = mprContactIndex; if (dstIdx<0) { AppendInc( nGlobalContactsOut, dstIdx ); } if (dstIdxm_worldNormalOnB = -normal; c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff); c->m_batchIdx = pairIndex; int bodyA = pairs[pairIndex].x; int bodyB = pairs[pairIndex].y; c->m_bodyAPtrAndSignBit = rigidBodies[bodyA].m_invMass==0?-bodyA:bodyA; c->m_bodyBPtrAndSignBit = rigidBodies[bodyB].m_invMass==0?-bodyB:bodyB; c->m_childIndexA = -1; c->m_childIndexB = -1; for (int i=0;i0||(mprContactIndex<0)) { c->m_worldPosB[i] = pointsIn[contactIdx[i]]; } } GET_NPOINTS(*c) = nReducedContacts; } }// if (numContactsOut>0) }// if (hasSeparatingAxis[i]) }// if (i= 0) { collidableIndexA = gpuChildShapes[childShapeIndexA].m_shapeIndex; float4 childPosA = gpuChildShapes[childShapeIndexA].m_childPosition; float4 childOrnA = gpuChildShapes[childShapeIndexA].m_childOrientation; float4 newPosA = qtRotate(ornA,childPosA)+posA; float4 newOrnA = qtMul(ornA,childOrnA); posA = newPosA; ornA = newOrnA; } else { collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx; } if (childShapeIndexB>=0) { collidableIndexB = gpuChildShapes[childShapeIndexB].m_shapeIndex; float4 childPosB = gpuChildShapes[childShapeIndexB].m_childPosition; float4 childOrnB = gpuChildShapes[childShapeIndexB].m_childOrientation; float4 newPosB = transform(&childPosB,&posB,&ornB); float4 newOrnB = qtMul(ornB,childOrnB); posB = newPosB; ornB = newOrnB; } else { collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx; } int shapeIndexA = collidables[collidableIndexA].m_shapeIndex; int shapeIndexB = collidables[collidableIndexB].m_shapeIndex; int numLocalContactsOut = clipHullAgainstHull(gpuCompoundSepNormalsOut[i], &convexShapes[shapeIndexA], &convexShapes[shapeIndexB], posA,ornA, posB,ornB, worldVertsB1,worldVertsB2,capacityWorldVerts, minDist, maxDist, vertices,faces,indices, localContactsOut,localContactCapacity); if (numLocalContactsOut>0) { float4 normal = -gpuCompoundSepNormalsOut[i]; int nPoints = numLocalContactsOut; float4* pointsIn = localContactsOut; int contactIdx[4];// = {-1,-1,-1,-1}; contactIdx[0] = -1; contactIdx[1] = -1; contactIdx[2] = -1; contactIdx[3] = -1; int nReducedContacts = extractManifoldSequential(pointsIn, nPoints, normal, contactIdx); int dstIdx; AppendInc( nGlobalContactsOut, dstIdx ); if ((dstIdx+nReducedContacts) < maxContactCapacity) { __global struct b3Contact4Data* c = globalContactsOut+ dstIdx; c->m_worldNormalOnB = -normal; c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff); c->m_batchIdx = pairIndex; int bodyA = gpuCompoundPairs[pairIndex].x; int bodyB = gpuCompoundPairs[pairIndex].y; c->m_bodyAPtrAndSignBit = rigidBodies[bodyA].m_invMass==0?-bodyA:bodyA; c->m_bodyBPtrAndSignBit = rigidBodies[bodyB].m_invMass==0?-bodyB:bodyB; c->m_childIndexA = childShapeIndexA; c->m_childIndexB = childShapeIndexB; for (int i=0;im_worldPosB[i] = pointsIn[contactIdx[i]]; } GET_NPOINTS(*c) = nReducedContacts; } }// if (numContactsOut>0) }// if (gpuHasCompoundSepNormalsOut[i]) }// if (i 0.00001) { normalOnSurfaceB = diff / len; } float4 contactPosB = posB + normalOnSurfaceB*radiusB; contactPosB.w = dist; int dstIdx; AppendInc( nGlobalContactsOut, dstIdx ); if (dstIdx < contactCapacity) { __global struct b3Contact4Data* c = &globalContactsOut[dstIdx]; c->m_worldNormalOnB = -normalOnSurfaceB; c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff); c->m_batchIdx = pairIndex; int bodyA = pairs[pairIndex].x; int bodyB = pairs[pairIndex].y; c->m_bodyAPtrAndSignBit = rigidBodies[bodyA].m_invMass==0?-bodyA:bodyA; c->m_bodyBPtrAndSignBit = rigidBodies[bodyB].m_invMass==0?-bodyB:bodyB; c->m_worldPosB[0] = contactPosB; c->m_childIndexA = -1; c->m_childIndexB = -1; GET_NPOINTS(*c) = 1; }//if (dstIdx < numPairs) }//if ( len <= (radiusA+radiusB)) }//SHAPE_SPHERE SHAPE_SPHERE }//if (i0) { float4 normal = -separatingNormals[i]; int nPoints = numLocalContactsOut; float4* pointsIn = localContactsOut; int contactIdx[4];// = {-1,-1,-1,-1}; contactIdx[0] = -1; contactIdx[1] = -1; contactIdx[2] = -1; contactIdx[3] = -1; int nReducedContacts = extractManifoldSequential(pointsIn, nPoints, normal, contactIdx); int dstIdx; AppendInc( nGlobalContactsOut, dstIdx ); if (dstIdxm_worldNormalOnB = -normal; c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff); c->m_batchIdx = pairIndex; int bodyA = concavePairsIn[pairIndex].x; int bodyB = concavePairsIn[pairIndex].y; c->m_bodyAPtrAndSignBit = rigidBodies[bodyA].m_invMass==0?-bodyA:bodyA; c->m_bodyBPtrAndSignBit = rigidBodies[bodyB].m_invMass==0?-bodyB:bodyB; c->m_childIndexA = childShapeIndexA; c->m_childIndexB = childShapeIndexB; for (int i=0;im_worldPosB[i] = pointsIn[contactIdx[i]]; } GET_NPOINTS(*c) = nReducedContacts; } }// if (numContactsOut>0) }// if (im_numFaces;face++) { const float4 Normal = make_float4(faces[hullB->m_faceOffset+face].m_plane.x, faces[hullB->m_faceOffset+face].m_plane.y, faces[hullB->m_faceOffset+face].m_plane.z,0.f); const float4 WorldNormal = qtRotate(ornB, Normal); float d = dot3F4(WorldNormal,separatingNormal); if (d > dmax) { dmax = d; closestFaceB = face; } } } { const b3GpuFace_t polyB = faces[hullB->m_faceOffset+closestFaceB]; const int numVertices = polyB.m_numIndices; for(int e0=0;e0m_vertexOffset+indices[polyB.m_indexOffset+e0]]; worldVertsB1[pairIndex*capacityWorldVerts+numWorldVertsB1++] = transform(&b,&posB,&ornB); } } int closestFaceA=-1; { float dmin = FLT_MAX; for(int face=0;facem_numFaces;face++) { const float4 Normal = make_float4( faces[hullA->m_faceOffset+face].m_plane.x, faces[hullA->m_faceOffset+face].m_plane.y, faces[hullA->m_faceOffset+face].m_plane.z, 0.f); const float4 faceANormalWS = qtRotate(ornA,Normal); float d = dot3F4(faceANormalWS,separatingNormal); if (d < dmin) { dmin = d; closestFaceA = face; worldNormalsA1[pairIndex] = faceANormalWS; } } } int numVerticesA = faces[hullA->m_faceOffset+closestFaceA].m_numIndices; for(int e0=0;e0m_vertexOffset+indices[faces[hullA->m_faceOffset+closestFaceA].m_indexOffset+e0]]; worldVertsA1[pairIndex*capacityWorldVerts+e0] = transform(&a, &posA,&ornA); } clippingFaces[pairIndex].x = closestFaceA; clippingFaces[pairIndex].y = closestFaceB; clippingFaces[pairIndex].z = numVerticesA; clippingFaces[pairIndex].w = numWorldVertsB1; return numContactsOut; } int clipFaces(__global float4* worldVertsA1, __global float4* worldNormalsA1, __global float4* worldVertsB1, __global float4* worldVertsB2, int capacityWorldVertsB2, const float minDist, float maxDist, __global int4* clippingFaces, int pairIndex) { int numContactsOut = 0; int closestFaceA = clippingFaces[pairIndex].x; int closestFaceB = clippingFaces[pairIndex].y; int numVertsInA = clippingFaces[pairIndex].z; int numVertsInB = clippingFaces[pairIndex].w; int numVertsOut = 0; if (closestFaceA<0) return numContactsOut; __global float4* pVtxIn = &worldVertsB1[pairIndex*capacityWorldVertsB2]; __global float4* pVtxOut = &worldVertsB2[pairIndex*capacityWorldVertsB2]; // clip polygon to back of planes of all faces of hull A that are adjacent to witness face for(int e0=0;e0=0) { // clip polygon to back of planes of all faces of hull A that are adjacent to witness face for(int e0=0;e00) { __global float4* pointsIn = &worldVertsB2[pairIndex*vertexFaceCapacity]; float4 normal = -separatingNormals[i]; int nReducedContacts = extractManifoldSequentialGlobal(pointsIn, nPoints, normal, &contactIdx); int mprContactIndex = pairs[pairIndex].z; int dstIdx = mprContactIndex; if (dstIdx<0) { AppendInc( nGlobalContactsOut, dstIdx ); } //#if 0 if (dstIdx < contactCapacity) { __global struct b3Contact4Data* c = &globalContactsOut[dstIdx]; c->m_worldNormalOnB = -normal; c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff); c->m_batchIdx = pairIndex; int bodyA = pairs[pairIndex].x; int bodyB = pairs[pairIndex].y; pairs[pairIndex].w = dstIdx; c->m_bodyAPtrAndSignBit = rigidBodies[bodyA].m_invMass==0?-bodyA:bodyA; c->m_bodyBPtrAndSignBit = rigidBodies[bodyB].m_invMass==0?-bodyB:bodyB; c->m_childIndexA =-1; c->m_childIndexB =-1; switch (nReducedContacts) { case 4: c->m_worldPosB[3] = pointsIn[contactIdx.w]; case 3: c->m_worldPosB[2] = pointsIn[contactIdx.z]; case 2: c->m_worldPosB[1] = pointsIn[contactIdx.y]; case 1: if (mprContactIndex<0)//test c->m_worldPosB[0] = pointsIn[contactIdx.x]; default: { } }; GET_NPOINTS(*c) = nReducedContacts; } //#endif }// if (numContactsOut>0) }// if (hasSeparatingAxis[i]) }// if (i