1 //keep this enum in sync with the CPU version (in btCollidable.h)
2 //written by Erwin Coumans
5 #define SHAPE_CONVEX_HULL 3
6 #define SHAPE_CONCAVE_TRIMESH 5
7 #define TRIANGLE_NUM_CONVEX_FACES 5
8 #define SHAPE_COMPOUND_OF_CONVEX_HULLS 6
10 #define B3_MAX_STACK_DEPTH 256
13 typedef unsigned int u32;
15 ///keep this in sync with btCollidable.h
25 int m_compoundBvhIndex;
33 #define MAX_NUM_PARTS_IN_BITS 10
35 ///b3QuantizedBvhNode is a compressed aabb node, 16 bytes.
36 ///Node can be used for leafnode or internal node. Leafnodes can point to 32-bit triangle index (non-negative range).
40 unsigned short int m_quantizedAabbMin[3];
41 unsigned short int m_quantizedAabbMax[3];
43 int m_escapeIndexOrTriangleIndex;
50 float4 m_quantization;
59 int getTriangleIndex(const b3QuantizedBvhNode* rootNode)
62 unsigned int y = (~(x&0))<<(31-MAX_NUM_PARTS_IN_BITS);
63 // Get only the lower bits where the triangle index is stored
64 return (rootNode->m_escapeIndexOrTriangleIndex&~(y));
67 int getTriangleIndexGlobal(__global const b3QuantizedBvhNode* rootNode)
70 unsigned int y = (~(x&0))<<(31-MAX_NUM_PARTS_IN_BITS);
71 // Get only the lower bits where the triangle index is stored
72 return (rootNode->m_escapeIndexOrTriangleIndex&~(y));
75 int isLeafNode(const b3QuantizedBvhNode* rootNode)
77 //skipindex is negative (internal node), triangleindex >=0 (leafnode)
78 return (rootNode->m_escapeIndexOrTriangleIndex >= 0)? 1 : 0;
81 int isLeafNodeGlobal(__global const b3QuantizedBvhNode* rootNode)
83 //skipindex is negative (internal node), triangleindex >=0 (leafnode)
84 return (rootNode->m_escapeIndexOrTriangleIndex >= 0)? 1 : 0;
87 int getEscapeIndex(const b3QuantizedBvhNode* rootNode)
89 return -rootNode->m_escapeIndexOrTriangleIndex;
92 int getEscapeIndexGlobal(__global const b3QuantizedBvhNode* rootNode)
94 return -rootNode->m_escapeIndexOrTriangleIndex;
101 unsigned short int m_quantizedAabbMin[3];
102 unsigned short int m_quantizedAabbMax[3];
103 //4 bytes, points to the root of the subtree
118 float4 m_childPosition;
119 float4 m_childOrientation;
136 float m_restituitionCoeff;
137 float m_frictionCoeff;
143 float4 m_localCenter;
154 int m_uniqueEdgesOffset;
155 int m_numUniqueEdges;
157 } ConvexPolyhedronCL;
175 #include "Bullet3Collision/BroadPhaseCollision/shared/b3Aabb.h"
176 #include "Bullet3Common/shared/b3Int2.h"
187 #define make_float4 (float4)
191 float4 cross3(float4 a, float4 b)
196 // float4 a1 = make_float4(a.xyz,0.f);
197 // float4 b1 = make_float4(b.xyz,0.f);
199 // return cross(a1,b1);
201 //float4 c = make_float4(a.y*b.z - a.z*b.y,a.z*b.x - a.x*b.z,a.x*b.y - a.y*b.x,0.f);
203 // float4 c = make_float4(a.y*b.z - a.z*b.y,1.f,a.x*b.y - a.y*b.x,0.f);
209 float dot3F4(float4 a, float4 b)
211 float4 a1 = make_float4(a.xyz,0.f);
212 float4 b1 = make_float4(b.xyz,0.f);
217 float4 fastNormalize4(float4 v)
219 v = make_float4(v.xyz,0.f);
220 return fast_normalize(v);
224 ///////////////////////////////////////
226 ///////////////////////////////////////
228 typedef float4 Quaternion;
231 Quaternion qtMul(Quaternion a, Quaternion b);
234 Quaternion qtNormalize(Quaternion in);
237 float4 qtRotate(Quaternion q, float4 vec);
240 Quaternion qtInvert(Quaternion q);
246 Quaternion qtMul(Quaternion a, Quaternion b)
249 ans = cross3( a, b );
251 // ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);
252 ans.w = a.w*b.w - dot3F4(a, b);
257 Quaternion qtNormalize(Quaternion in)
259 return fastNormalize4(in);
260 // in /= length( in );
264 float4 qtRotate(Quaternion q, float4 vec)
266 Quaternion qInv = qtInvert( q );
269 float4 out = qtMul(qtMul(q,vcpy),qInv);
274 Quaternion qtInvert(Quaternion q)
276 return (Quaternion)(-q.xyz, q.w);
280 float4 qtInvRotate(const Quaternion q, float4 vec)
282 return qtRotate( qtInvert( q ), vec );
286 float4 transform(const float4* p, const float4* translation, const Quaternion* orientation)
288 return qtRotate( *orientation, *p ) + (*translation);
294 float4 normalize3(const float4 a)
296 float4 n = make_float4(a.x, a.y, a.z, 0.f);
297 return fastNormalize4( n );
300 inline void projectLocal(const ConvexPolyhedronCL* hull, const float4 pos, const float4 orn,
301 const float4* dir, const float4* vertices, float* min, float* max)
305 int numVerts = hull->m_numVertices;
307 const float4 localDir = qtInvRotate(orn,*dir);
308 float offset = dot(pos,*dir);
309 for(int i=0;i<numVerts;i++)
311 float dp = dot(vertices[hull->m_vertexOffset+i],localDir);
327 inline void project(__global const ConvexPolyhedronCL* hull, const float4 pos, const float4 orn,
328 const float4* dir, __global const float4* vertices, float* min, float* max)
332 int numVerts = hull->m_numVertices;
334 const float4 localDir = qtInvRotate(orn,*dir);
335 float offset = dot(pos,*dir);
336 for(int i=0;i<numVerts;i++)
338 float dp = dot(vertices[hull->m_vertexOffset+i],localDir);
354 inline bool TestSepAxisLocalA(const ConvexPolyhedronCL* hullA, __global const ConvexPolyhedronCL* hullB,
355 const float4 posA,const float4 ornA,
356 const float4 posB,const float4 ornB,
357 float4* sep_axis, const float4* verticesA, __global const float4* verticesB,float* depth)
361 projectLocal(hullA,posA,ornA,sep_axis,verticesA, &Min0, &Max0);
362 project(hullB,posB,ornB, sep_axis,verticesB, &Min1, &Max1);
364 if(Max0<Min1 || Max1<Min0)
367 float d0 = Max0 - Min1;
368 float d1 = Max1 - Min0;
369 *depth = d0<d1 ? d0:d1;
376 inline bool IsAlmostZero(const float4 v)
378 if(fabs(v.x)>1e-6f || fabs(v.y)>1e-6f || fabs(v.z)>1e-6f)
385 bool findSeparatingAxisLocalA( const ConvexPolyhedronCL* hullA, __global const ConvexPolyhedronCL* hullB,
390 const float4 DeltaC2,
392 const float4* verticesA,
393 const float4* uniqueEdgesA,
394 const btGpuFace* facesA,
397 __global const float4* verticesB,
398 __global const float4* uniqueEdgesB,
399 __global const btGpuFace* facesB,
400 __global const int* indicesB,
412 int numFacesA = hullA->m_numFaces;
413 // Test normals from hullA
414 for(int i=0;i<numFacesA;i++)
416 const float4 normal = facesA[hullA->m_faceOffset+i].m_plane;
417 float4 faceANormalWS = qtRotate(ornA,normal);
418 if (dot3F4(DeltaC2,faceANormalWS)<0)
422 if(!TestSepAxisLocalA( hullA, hullB, posA,ornA,posB,ornB,&faceANormalWS, verticesA, verticesB,&d))
427 *sep = faceANormalWS;
431 if((dot3F4(-DeltaC2,*sep))>0.0f)
438 bool findSeparatingAxisLocalB( __global const ConvexPolyhedronCL* hullA, const ConvexPolyhedronCL* hullB,
443 const float4 DeltaC2,
444 __global const float4* verticesA,
445 __global const float4* uniqueEdgesA,
446 __global const btGpuFace* facesA,
447 __global const int* indicesA,
448 const float4* verticesB,
449 const float4* uniqueEdgesB,
450 const btGpuFace* facesB,
463 int numFacesA = hullA->m_numFaces;
464 // Test normals from hullA
465 for(int i=0;i<numFacesA;i++)
467 const float4 normal = facesA[hullA->m_faceOffset+i].m_plane;
468 float4 faceANormalWS = qtRotate(ornA,normal);
469 if (dot3F4(DeltaC2,faceANormalWS)<0)
470 faceANormalWS *= -1.f;
473 if(!TestSepAxisLocalA( hullB, hullA, posB,ornB,posA,ornA, &faceANormalWS, verticesB,verticesA, &d))
478 *sep = faceANormalWS;
482 if((dot3F4(-DeltaC2,*sep))>0.0f)
491 bool findSeparatingAxisEdgeEdgeLocalA( const ConvexPolyhedronCL* hullA, __global const ConvexPolyhedronCL* hullB,
496 const float4 DeltaC2,
497 const float4* verticesA,
498 const float4* uniqueEdgesA,
499 const btGpuFace* facesA,
501 __global const float4* verticesB,
502 __global const float4* uniqueEdgesB,
503 __global const btGpuFace* facesB,
504 __global const int* indicesB,
519 for(int e0=0;e0<hullA->m_numUniqueEdges;e0++)
521 const float4 edge0 = uniqueEdgesA[hullA->m_uniqueEdgesOffset+e0];
522 float4 edge0World = qtRotate(ornA,edge0);
524 for(int e1=0;e1<hullB->m_numUniqueEdges;e1++)
526 const float4 edge1 = uniqueEdgesB[hullB->m_uniqueEdgesOffset+e1];
527 float4 edge1World = qtRotate(ornB,edge1);
530 float4 crossje = cross3(edge0World,edge1World);
533 if(!IsAlmostZero(crossje))
535 crossje = normalize3(crossje);
536 if (dot3F4(DeltaC2,crossje)<0)
544 projectLocal(hullA,posA,ornA,&crossje,verticesA, &Min0, &Max0);
545 project(hullB,posB,ornB,&crossje,verticesB, &Min1, &Max1);
547 if(Max0<Min1 || Max1<Min0)
550 float d0 = Max0 - Min1;
551 float d1 = Max1 - Min0;
552 dist = d0<d1 ? d0:d1;
569 if((dot3F4(-DeltaC2,*sep))>0.0f)
577 inline bool TestSepAxis(__global const ConvexPolyhedronCL* hullA, __global const ConvexPolyhedronCL* hullB,
578 const float4 posA,const float4 ornA,
579 const float4 posB,const float4 ornB,
580 float4* sep_axis, __global const float4* vertices,float* depth)
584 project(hullA,posA,ornA,sep_axis,vertices, &Min0, &Max0);
585 project(hullB,posB,ornB, sep_axis,vertices, &Min1, &Max1);
587 if(Max0<Min1 || Max1<Min0)
590 float d0 = Max0 - Min1;
591 float d1 = Max1 - Min0;
592 *depth = d0<d1 ? d0:d1;
597 bool findSeparatingAxis( __global const ConvexPolyhedronCL* hullA, __global const ConvexPolyhedronCL* hullB,
602 const float4 DeltaC2,
603 __global const float4* vertices,
604 __global const float4* uniqueEdges,
605 __global const btGpuFace* faces,
606 __global const int* indices,
620 int numFacesA = hullA->m_numFaces;
621 // Test normals from hullA
622 for(int i=0;i<numFacesA;i++)
624 const float4 normal = faces[hullA->m_faceOffset+i].m_plane;
625 float4 faceANormalWS = qtRotate(ornA,normal);
627 if (dot3F4(DeltaC2,faceANormalWS)<0)
633 if(!TestSepAxis( hullA, hullB, posA,ornA,posB,ornB,&faceANormalWS, vertices,&d))
639 *sep = faceANormalWS;
645 if((dot3F4(-DeltaC2,*sep))>0.0f)
656 bool findSeparatingAxisUnitSphere( __global const ConvexPolyhedronCL* hullA, __global const ConvexPolyhedronCL* hullB,
661 const float4 DeltaC2,
662 __global const float4* vertices,
663 __global const float4* unitSphereDirections,
664 int numUnitSphereDirections,
677 // Test unit sphere directions
678 for (int i=0;i<numUnitSphereDirections;i++)
682 crossje = unitSphereDirections[i];
684 if (dot3F4(DeltaC2,crossje)>0)
691 project(hullA,posA,ornA,&crossje,vertices, &Min0, &Max0);
692 project(hullB,posB,ornB,&crossje,vertices, &Min1, &Max1);
694 if(Max0<Min1 || Max1<Min0)
697 float d0 = Max0 - Min1;
698 float d1 = Max1 - Min0;
699 dist = d0<d1 ? d0:d1;
711 if((dot3F4(-DeltaC2,*sep))>0.0f)
719 bool findSeparatingAxisEdgeEdge( __global const ConvexPolyhedronCL* hullA, __global const ConvexPolyhedronCL* hullB,
724 const float4 DeltaC2,
725 __global const float4* vertices,
726 __global const float4* uniqueEdges,
727 __global const btGpuFace* faces,
728 __global const int* indices,
743 for(int e0=0;e0<hullA->m_numUniqueEdges;e0++)
745 const float4 edge0 = uniqueEdges[hullA->m_uniqueEdgesOffset+e0];
746 float4 edge0World = qtRotate(ornA,edge0);
748 for(int e1=0;e1<hullB->m_numUniqueEdges;e1++)
750 const float4 edge1 = uniqueEdges[hullB->m_uniqueEdgesOffset+e1];
751 float4 edge1World = qtRotate(ornB,edge1);
754 float4 crossje = cross3(edge0World,edge1World);
757 if(!IsAlmostZero(crossje))
759 crossje = normalize3(crossje);
760 if (dot3F4(DeltaC2,crossje)<0)
768 project(hullA,posA,ornA,&crossje,vertices, &Min0, &Max0);
769 project(hullB,posB,ornB,&crossje,vertices, &Min1, &Max1);
771 if(Max0<Min1 || Max1<Min0)
774 float d0 = Max0 - Min1;
775 float d1 = Max1 - Min0;
776 dist = d0<d1 ? d0:d1;
793 if((dot3F4(-DeltaC2,*sep))>0.0f)
802 __kernel void processCompoundPairsKernel( __global const int4* gpuCompoundPairs,
803 __global const BodyData* rigidBodies,
804 __global const btCollidableGpu* collidables,
805 __global const ConvexPolyhedronCL* convexShapes,
806 __global const float4* vertices,
807 __global const float4* uniqueEdges,
808 __global const btGpuFace* faces,
809 __global const int* indices,
810 __global btAabbCL* aabbs,
811 __global const btGpuChildShape* gpuChildShapes,
812 __global volatile float4* gpuCompoundSepNormalsOut,
813 __global volatile int* gpuHasCompoundSepNormalsOut,
818 int i = get_global_id(0);
819 if (i<numCompoundPairs)
821 int bodyIndexA = gpuCompoundPairs[i].x;
822 int bodyIndexB = gpuCompoundPairs[i].y;
824 int childShapeIndexA = gpuCompoundPairs[i].z;
825 int childShapeIndexB = gpuCompoundPairs[i].w;
827 int collidableIndexA = -1;
828 int collidableIndexB = -1;
830 float4 ornA = rigidBodies[bodyIndexA].m_quat;
831 float4 posA = rigidBodies[bodyIndexA].m_pos;
833 float4 ornB = rigidBodies[bodyIndexB].m_quat;
834 float4 posB = rigidBodies[bodyIndexB].m_pos;
836 if (childShapeIndexA >= 0)
838 collidableIndexA = gpuChildShapes[childShapeIndexA].m_shapeIndex;
839 float4 childPosA = gpuChildShapes[childShapeIndexA].m_childPosition;
840 float4 childOrnA = gpuChildShapes[childShapeIndexA].m_childOrientation;
841 float4 newPosA = qtRotate(ornA,childPosA)+posA;
842 float4 newOrnA = qtMul(ornA,childOrnA);
847 collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;
850 if (childShapeIndexB>=0)
852 collidableIndexB = gpuChildShapes[childShapeIndexB].m_shapeIndex;
853 float4 childPosB = gpuChildShapes[childShapeIndexB].m_childPosition;
854 float4 childOrnB = gpuChildShapes[childShapeIndexB].m_childOrientation;
855 float4 newPosB = transform(&childPosB,&posB,&ornB);
856 float4 newOrnB = qtMul(ornB,childOrnB);
861 collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx;
864 gpuHasCompoundSepNormalsOut[i] = 0;
866 int shapeIndexA = collidables[collidableIndexA].m_shapeIndex;
867 int shapeIndexB = collidables[collidableIndexB].m_shapeIndex;
869 int shapeTypeA = collidables[collidableIndexA].m_shapeType;
870 int shapeTypeB = collidables[collidableIndexB].m_shapeType;
873 if ((shapeTypeA != SHAPE_CONVEX_HULL) || (shapeTypeB != SHAPE_CONVEX_HULL))
878 int hasSeparatingAxis = 5;
880 int numFacesA = convexShapes[shapeIndexA].m_numFaces;
881 float dmin = FLT_MAX;
884 float4 c0local = convexShapes[shapeIndexA].m_localCenter;
885 float4 c0 = transform(&c0local, &posA, &ornA);
886 float4 c1local = convexShapes[shapeIndexB].m_localCenter;
887 float4 c1 = transform(&c1local,&posB,&ornB);
888 const float4 DeltaC2 = c0 - c1;
889 float4 sepNormal = make_float4(1,0,0,0);
890 bool sepA = findSeparatingAxis( &convexShapes[shapeIndexA], &convexShapes[shapeIndexB],posA,ornA,posB,ornB,DeltaC2,vertices,uniqueEdges,faces,indices,&sepNormal,&dmin);
891 hasSeparatingAxis = 4;
894 hasSeparatingAxis = 0;
897 bool sepB = findSeparatingAxis( &convexShapes[shapeIndexB],&convexShapes[shapeIndexA],posB,ornB,posA,ornA,DeltaC2,vertices,uniqueEdges,faces,indices,&sepNormal,&dmin);
901 hasSeparatingAxis = 0;
904 bool sepEE = findSeparatingAxisEdgeEdge( &convexShapes[shapeIndexA], &convexShapes[shapeIndexB],posA,ornA,posB,ornB,DeltaC2,vertices,uniqueEdges,faces,indices,&sepNormal,&dmin);
907 gpuCompoundSepNormalsOut[i] = sepNormal;//fastNormalize4(sepNormal);
908 gpuHasCompoundSepNormalsOut[i] = 1;
919 inline b3Float4 MyUnQuantize(const unsigned short* vecIn, b3Float4 quantization, b3Float4 bvhAabbMin)
922 vecOut = b3MakeFloat4(
923 (float)(vecIn[0]) / (quantization.x),
924 (float)(vecIn[1]) / (quantization.y),
925 (float)(vecIn[2]) / (quantization.z),
928 vecOut += bvhAabbMin;
932 inline b3Float4 MyUnQuantizeGlobal(__global const unsigned short* vecIn, b3Float4 quantization, b3Float4 bvhAabbMin)
935 vecOut = b3MakeFloat4(
936 (float)(vecIn[0]) / (quantization.x),
937 (float)(vecIn[1]) / (quantization.y),
938 (float)(vecIn[2]) / (quantization.z),
941 vecOut += bvhAabbMin;
947 __kernel void findCompoundPairsKernel( __global const int4* pairs,
948 __global const BodyData* rigidBodies,
949 __global const btCollidableGpu* collidables,
950 __global const ConvexPolyhedronCL* convexShapes,
951 __global const float4* vertices,
952 __global const float4* uniqueEdges,
953 __global const btGpuFace* faces,
954 __global const int* indices,
955 __global b3Aabb_t* aabbLocalSpace,
956 __global const btGpuChildShape* gpuChildShapes,
957 __global volatile int4* gpuCompoundPairsOut,
958 __global volatile int* numCompoundPairsOut,
959 __global const b3BvhSubtreeInfo* subtrees,
960 __global const b3QuantizedBvhNode* quantizedNodes,
961 __global const b3BvhInfo* bvhInfos,
963 int maxNumCompoundPairsCapacity
967 int i = get_global_id(0);
971 int bodyIndexA = pairs[i].x;
972 int bodyIndexB = pairs[i].y;
974 int collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;
975 int collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx;
977 int shapeIndexA = collidables[collidableIndexA].m_shapeIndex;
978 int shapeIndexB = collidables[collidableIndexB].m_shapeIndex;
981 //once the broadphase avoids static-static pairs, we can remove this test
982 if ((rigidBodies[bodyIndexA].m_invMass==0) &&(rigidBodies[bodyIndexB].m_invMass==0))
987 if ((collidables[collidableIndexA].m_shapeType==SHAPE_COMPOUND_OF_CONVEX_HULLS) &&(collidables[collidableIndexB].m_shapeType==SHAPE_COMPOUND_OF_CONVEX_HULLS))
989 int bvhA = collidables[collidableIndexA].m_compoundBvhIndex;
990 int bvhB = collidables[collidableIndexB].m_compoundBvhIndex;
991 int numSubTreesA = bvhInfos[bvhA].m_numSubTrees;
992 int subTreesOffsetA = bvhInfos[bvhA].m_subTreeOffset;
993 int subTreesOffsetB = bvhInfos[bvhB].m_subTreeOffset;
996 int numSubTreesB = bvhInfos[bvhB].m_numSubTrees;
998 float4 posA = rigidBodies[bodyIndexA].m_pos;
999 b3Quat ornA = rigidBodies[bodyIndexA].m_quat;
1001 b3Quat ornB = rigidBodies[bodyIndexB].m_quat;
1002 float4 posB = rigidBodies[bodyIndexB].m_pos;
1005 for (int p=0;p<numSubTreesA;p++)
1007 b3BvhSubtreeInfo subtreeA = subtrees[subTreesOffsetA+p];
1008 //bvhInfos[bvhA].m_quantization
1009 b3Float4 treeAminLocal = MyUnQuantize(subtreeA.m_quantizedAabbMin,bvhInfos[bvhA].m_quantization,bvhInfos[bvhA].m_aabbMin);
1010 b3Float4 treeAmaxLocal = MyUnQuantize(subtreeA.m_quantizedAabbMax,bvhInfos[bvhA].m_quantization,bvhInfos[bvhA].m_aabbMin);
1012 b3Float4 aabbAMinOut,aabbAMaxOut;
1014 b3TransformAabb2(treeAminLocal,treeAmaxLocal, margin,posA,ornA,&aabbAMinOut,&aabbAMaxOut);
1016 for (int q=0;q<numSubTreesB;q++)
1018 b3BvhSubtreeInfo subtreeB = subtrees[subTreesOffsetB+q];
1020 b3Float4 treeBminLocal = MyUnQuantize(subtreeB.m_quantizedAabbMin,bvhInfos[bvhB].m_quantization,bvhInfos[bvhB].m_aabbMin);
1021 b3Float4 treeBmaxLocal = MyUnQuantize(subtreeB.m_quantizedAabbMax,bvhInfos[bvhB].m_quantization,bvhInfos[bvhB].m_aabbMin);
1023 b3Float4 aabbBMinOut,aabbBMaxOut;
1025 b3TransformAabb2(treeBminLocal,treeBmaxLocal, margin,posB,ornB,&aabbBMinOut,&aabbBMaxOut);
1029 bool aabbOverlap = b3TestAabbAgainstAabb(aabbAMinOut,aabbAMaxOut,aabbBMinOut,aabbBMaxOut);
1033 int startNodeIndexA = subtreeA.m_rootNodeIndex+bvhInfos[bvhA].m_nodeOffset;
1034 int endNodeIndexA = startNodeIndexA+subtreeA.m_subtreeSize;
1036 int startNodeIndexB = subtreeB.m_rootNodeIndex+bvhInfos[bvhB].m_nodeOffset;
1037 int endNodeIndexB = startNodeIndexB+subtreeB.m_subtreeSize;
1040 b3Int2 nodeStack[B3_MAX_STACK_DEPTH];
1042 node0.x = startNodeIndexA;
1043 node0.y = startNodeIndexB;
1044 int maxStackDepth = B3_MAX_STACK_DEPTH;
1046 nodeStack[depth++]=node0;
1050 b3Int2 node = nodeStack[--depth];
1052 b3Float4 aMinLocal = MyUnQuantizeGlobal(quantizedNodes[node.x].m_quantizedAabbMin,bvhInfos[bvhA].m_quantization,bvhInfos[bvhA].m_aabbMin);
1053 b3Float4 aMaxLocal = MyUnQuantizeGlobal(quantizedNodes[node.x].m_quantizedAabbMax,bvhInfos[bvhA].m_quantization,bvhInfos[bvhA].m_aabbMin);
1055 b3Float4 bMinLocal = MyUnQuantizeGlobal(quantizedNodes[node.y].m_quantizedAabbMin,bvhInfos[bvhB].m_quantization,bvhInfos[bvhB].m_aabbMin);
1056 b3Float4 bMaxLocal = MyUnQuantizeGlobal(quantizedNodes[node.y].m_quantizedAabbMax,bvhInfos[bvhB].m_quantization,bvhInfos[bvhB].m_aabbMin);
1059 b3Float4 aabbAMinOut,aabbAMaxOut;
1060 b3TransformAabb2(aMinLocal,aMaxLocal, margin,posA,ornA,&aabbAMinOut,&aabbAMaxOut);
1062 b3Float4 aabbBMinOut,aabbBMaxOut;
1063 b3TransformAabb2(bMinLocal,bMaxLocal, margin,posB,ornB,&aabbBMinOut,&aabbBMaxOut);
1066 bool nodeOverlap = b3TestAabbAgainstAabb(aabbAMinOut,aabbAMaxOut,aabbBMinOut,aabbBMaxOut);
1069 bool isLeafA = isLeafNodeGlobal(&quantizedNodes[node.x]);
1070 bool isLeafB = isLeafNodeGlobal(&quantizedNodes[node.y]);
1071 bool isInternalA = !isLeafA;
1072 bool isInternalB = !isLeafB;
1074 //fail, even though it might hit two leaf nodes
1075 if (depth+4>maxStackDepth && !(isLeafA && isLeafB))
1077 //printf("Error: traversal exceeded maxStackDepth");
1083 int nodeAleftChild = node.x+1;
1084 bool isNodeALeftChildLeaf = isLeafNodeGlobal(&quantizedNodes[node.x+1]);
1085 int nodeArightChild = isNodeALeftChildLeaf? node.x+2 : node.x+1 + getEscapeIndexGlobal(&quantizedNodes[node.x+1]);
1089 int nodeBleftChild = node.y+1;
1090 bool isNodeBLeftChildLeaf = isLeafNodeGlobal(&quantizedNodes[node.y+1]);
1091 int nodeBrightChild = isNodeBLeftChildLeaf? node.y+2 : node.y+1 + getEscapeIndexGlobal(&quantizedNodes[node.y+1]);
1093 nodeStack[depth++] = b3MakeInt2(nodeAleftChild, nodeBleftChild);
1094 nodeStack[depth++] = b3MakeInt2(nodeArightChild, nodeBleftChild);
1095 nodeStack[depth++] = b3MakeInt2(nodeAleftChild, nodeBrightChild);
1096 nodeStack[depth++] = b3MakeInt2(nodeArightChild, nodeBrightChild);
1100 nodeStack[depth++] = b3MakeInt2(nodeAleftChild,node.y);
1101 nodeStack[depth++] = b3MakeInt2(nodeArightChild,node.y);
1108 int nodeBleftChild = node.y+1;
1109 bool isNodeBLeftChildLeaf = isLeafNodeGlobal(&quantizedNodes[node.y+1]);
1110 int nodeBrightChild = isNodeBLeftChildLeaf? node.y+2 : node.y+1 + getEscapeIndexGlobal(&quantizedNodes[node.y+1]);
1111 nodeStack[depth++] = b3MakeInt2(node.x,nodeBleftChild);
1112 nodeStack[depth++] = b3MakeInt2(node.x,nodeBrightChild);
1116 int compoundPairIdx = atomic_inc(numCompoundPairsOut);
1117 if (compoundPairIdx<maxNumCompoundPairsCapacity)
1119 int childShapeIndexA = getTriangleIndexGlobal(&quantizedNodes[node.x]);
1120 int childShapeIndexB = getTriangleIndexGlobal(&quantizedNodes[node.y]);
1121 gpuCompoundPairsOut[compoundPairIdx] = (int4)(bodyIndexA,bodyIndexB,childShapeIndexA,childShapeIndexB);
1138 if ((collidables[collidableIndexA].m_shapeType==SHAPE_COMPOUND_OF_CONVEX_HULLS) ||(collidables[collidableIndexB].m_shapeType==SHAPE_COMPOUND_OF_CONVEX_HULLS))
1141 if (collidables[collidableIndexA].m_shapeType==SHAPE_COMPOUND_OF_CONVEX_HULLS)
1144 int numChildrenA = collidables[collidableIndexA].m_numChildShapes;
1145 for (int c=0;c<numChildrenA;c++)
1147 int childShapeIndexA = collidables[collidableIndexA].m_shapeIndex+c;
1148 int childColIndexA = gpuChildShapes[childShapeIndexA].m_shapeIndex;
1150 float4 posA = rigidBodies[bodyIndexA].m_pos;
1151 float4 ornA = rigidBodies[bodyIndexA].m_quat;
1152 float4 childPosA = gpuChildShapes[childShapeIndexA].m_childPosition;
1153 float4 childOrnA = gpuChildShapes[childShapeIndexA].m_childOrientation;
1154 float4 newPosA = qtRotate(ornA,childPosA)+posA;
1155 float4 newOrnA = qtMul(ornA,childOrnA);
1157 int shapeIndexA = collidables[childColIndexA].m_shapeIndex;
1158 b3Aabb_t aabbAlocal = aabbLocalSpace[shapeIndexA];
1161 b3Float4 aabbAMinWS;
1162 b3Float4 aabbAMaxWS;
1164 b3TransformAabb2(aabbAlocal.m_minVec,aabbAlocal.m_maxVec,margin,
1167 &aabbAMinWS,&aabbAMaxWS);
1170 if (collidables[collidableIndexB].m_shapeType==SHAPE_COMPOUND_OF_CONVEX_HULLS)
1172 int numChildrenB = collidables[collidableIndexB].m_numChildShapes;
1173 for (int b=0;b<numChildrenB;b++)
1175 int childShapeIndexB = collidables[collidableIndexB].m_shapeIndex+b;
1176 int childColIndexB = gpuChildShapes[childShapeIndexB].m_shapeIndex;
1177 float4 ornB = rigidBodies[bodyIndexB].m_quat;
1178 float4 posB = rigidBodies[bodyIndexB].m_pos;
1179 float4 childPosB = gpuChildShapes[childShapeIndexB].m_childPosition;
1180 float4 childOrnB = gpuChildShapes[childShapeIndexB].m_childOrientation;
1181 float4 newPosB = transform(&childPosB,&posB,&ornB);
1182 float4 newOrnB = qtMul(ornB,childOrnB);
1184 int shapeIndexB = collidables[childColIndexB].m_shapeIndex;
1185 b3Aabb_t aabbBlocal = aabbLocalSpace[shapeIndexB];
1187 b3Float4 aabbBMinWS;
1188 b3Float4 aabbBMaxWS;
1190 b3TransformAabb2(aabbBlocal.m_minVec,aabbBlocal.m_maxVec,margin,
1193 &aabbBMinWS,&aabbBMaxWS);
1197 bool aabbOverlap = b3TestAabbAgainstAabb(aabbAMinWS,aabbAMaxWS,aabbBMinWS,aabbBMaxWS);
1200 int numFacesA = convexShapes[shapeIndexA].m_numFaces;
1201 float dmin = FLT_MAX;
1202 float4 posA = newPosA;
1204 float4 posB = newPosB;
1206 float4 c0local = convexShapes[shapeIndexA].m_localCenter;
1207 float4 ornA = newOrnA;
1208 float4 c0 = transform(&c0local, &posA, &ornA);
1209 float4 c1local = convexShapes[shapeIndexB].m_localCenter;
1210 float4 ornB =newOrnB;
1211 float4 c1 = transform(&c1local,&posB,&ornB);
1212 const float4 DeltaC2 = c0 - c1;
1215 int compoundPairIdx = atomic_inc(numCompoundPairsOut);
1216 if (compoundPairIdx<maxNumCompoundPairsCapacity)
1218 gpuCompoundPairsOut[compoundPairIdx] = (int4)(bodyIndexA,bodyIndexB,childShapeIndexA,childShapeIndexB);
1223 }//if (collidables[collidableIndexB].
1224 else//if (collidables[collidableIndexB].m_shapeType==SHAPE_COMPOUND_OF_CONVEX_HULLS)
1228 int numFacesA = convexShapes[shapeIndexA].m_numFaces;
1229 float dmin = FLT_MAX;
1230 float4 posA = newPosA;
1232 float4 posB = rigidBodies[bodyIndexB].m_pos;
1234 float4 c0local = convexShapes[shapeIndexA].m_localCenter;
1235 float4 ornA = newOrnA;
1236 float4 c0 = transform(&c0local, &posA, &ornA);
1237 float4 c1local = convexShapes[shapeIndexB].m_localCenter;
1238 float4 ornB = rigidBodies[bodyIndexB].m_quat;
1239 float4 c1 = transform(&c1local,&posB,&ornB);
1240 const float4 DeltaC2 = c0 - c1;
1243 int compoundPairIdx = atomic_inc(numCompoundPairsOut);
1244 if (compoundPairIdx<maxNumCompoundPairsCapacity)
1246 gpuCompoundPairsOut[compoundPairIdx] = (int4)(bodyIndexA,bodyIndexB,childShapeIndexA,-1);
1247 }//if (compoundPairIdx<maxNumCompoundPairsCapacity)
1250 }//if (collidables[collidableIndexB].m_shapeType==SHAPE_COMPOUND_OF_CONVEX_HULLS)
1251 }//for (int b=0;b<numChildrenB;b++)
1253 }//if (collidables[collidableIndexB].m_shapeType==SHAPE_COMPOUND_OF_CONVEX_HULLS)
1254 if ((collidables[collidableIndexA].m_shapeType!=SHAPE_CONCAVE_TRIMESH)
1255 && (collidables[collidableIndexB].m_shapeType==SHAPE_COMPOUND_OF_CONVEX_HULLS))
1257 int numChildrenB = collidables[collidableIndexB].m_numChildShapes;
1258 for (int b=0;b<numChildrenB;b++)
1260 int childShapeIndexB = collidables[collidableIndexB].m_shapeIndex+b;
1261 int childColIndexB = gpuChildShapes[childShapeIndexB].m_shapeIndex;
1262 float4 ornB = rigidBodies[bodyIndexB].m_quat;
1263 float4 posB = rigidBodies[bodyIndexB].m_pos;
1264 float4 childPosB = gpuChildShapes[childShapeIndexB].m_childPosition;
1265 float4 childOrnB = gpuChildShapes[childShapeIndexB].m_childOrientation;
1266 float4 newPosB = qtRotate(ornB,childPosB)+posB;
1267 float4 newOrnB = qtMul(ornB,childOrnB);
1269 int shapeIndexB = collidables[childColIndexB].m_shapeIndex;
1272 //////////////////////////////////////
1276 int numFacesA = convexShapes[shapeIndexA].m_numFaces;
1277 float dmin = FLT_MAX;
1278 float4 posA = rigidBodies[bodyIndexA].m_pos;
1280 float4 posB = newPosB;
1282 float4 c0local = convexShapes[shapeIndexA].m_localCenter;
1283 float4 ornA = rigidBodies[bodyIndexA].m_quat;
1284 float4 c0 = transform(&c0local, &posA, &ornA);
1285 float4 c1local = convexShapes[shapeIndexB].m_localCenter;
1286 float4 ornB =newOrnB;
1287 float4 c1 = transform(&c1local,&posB,&ornB);
1288 const float4 DeltaC2 = c0 - c1;
1290 int compoundPairIdx = atomic_inc(numCompoundPairsOut);
1291 if (compoundPairIdx<maxNumCompoundPairsCapacity)
1293 gpuCompoundPairsOut[compoundPairIdx] = (int4)(bodyIndexA,bodyIndexB,-1,childShapeIndexB);
1294 }//fi (compoundPairIdx<maxNumCompoundPairsCapacity)
1297 }//for (int b=0;b<numChildrenB;b++)
1299 }//if (collidables[collidableIndexB].m_shapeType==SHAPE_COMPOUND_OF_CONVEX_HULLS)
1301 }//fi ((collidables[collidableIndexA].m_shapeType==SHAPE_COMPOUND_OF_CONVEX_HULLS) ||(collidables[collidableIndexB].m_shapeType==SHAPE_COMPOUND_OF_CONVEX_HULLS))
1306 __kernel void findSeparatingAxisKernel( __global const int4* pairs,
1307 __global const BodyData* rigidBodies,
1308 __global const btCollidableGpu* collidables,
1309 __global const ConvexPolyhedronCL* convexShapes,
1310 __global const float4* vertices,
1311 __global const float4* uniqueEdges,
1312 __global const btGpuFace* faces,
1313 __global const int* indices,
1314 __global btAabbCL* aabbs,
1315 __global volatile float4* separatingNormals,
1316 __global volatile int* hasSeparatingAxis,
1321 int i = get_global_id(0);
1327 int bodyIndexA = pairs[i].x;
1328 int bodyIndexB = pairs[i].y;
1330 int collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;
1331 int collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx;
1333 int shapeIndexA = collidables[collidableIndexA].m_shapeIndex;
1334 int shapeIndexB = collidables[collidableIndexB].m_shapeIndex;
1337 //once the broadphase avoids static-static pairs, we can remove this test
1338 if ((rigidBodies[bodyIndexA].m_invMass==0) &&(rigidBodies[bodyIndexB].m_invMass==0))
1340 hasSeparatingAxis[i] = 0;
1345 if ((collidables[collidableIndexA].m_shapeType!=SHAPE_CONVEX_HULL) ||(collidables[collidableIndexB].m_shapeType!=SHAPE_CONVEX_HULL))
1347 hasSeparatingAxis[i] = 0;
1351 if ((collidables[collidableIndexA].m_shapeType==SHAPE_CONCAVE_TRIMESH))
1353 hasSeparatingAxis[i] = 0;
1357 int numFacesA = convexShapes[shapeIndexA].m_numFaces;
1359 float dmin = FLT_MAX;
1361 float4 posA = rigidBodies[bodyIndexA].m_pos;
1363 float4 posB = rigidBodies[bodyIndexB].m_pos;
1365 float4 c0local = convexShapes[shapeIndexA].m_localCenter;
1366 float4 ornA = rigidBodies[bodyIndexA].m_quat;
1367 float4 c0 = transform(&c0local, &posA, &ornA);
1368 float4 c1local = convexShapes[shapeIndexB].m_localCenter;
1369 float4 ornB =rigidBodies[bodyIndexB].m_quat;
1370 float4 c1 = transform(&c1local,&posB,&ornB);
1371 const float4 DeltaC2 = c0 - c1;
1374 bool sepA = findSeparatingAxis( &convexShapes[shapeIndexA], &convexShapes[shapeIndexB],posA,ornA,
1377 vertices,uniqueEdges,faces,
1378 indices,&sepNormal,&dmin);
1379 hasSeparatingAxis[i] = 4;
1382 hasSeparatingAxis[i] = 0;
1385 bool sepB = findSeparatingAxis( &convexShapes[shapeIndexB],&convexShapes[shapeIndexA],posB,ornB,
1388 vertices,uniqueEdges,faces,
1389 indices,&sepNormal,&dmin);
1393 hasSeparatingAxis[i] = 0;
1396 bool sepEE = findSeparatingAxisEdgeEdge( &convexShapes[shapeIndexA], &convexShapes[shapeIndexB],posA,ornA,
1399 vertices,uniqueEdges,faces,
1400 indices,&sepNormal,&dmin);
1403 hasSeparatingAxis[i] = 0;
1406 hasSeparatingAxis[i] = 1;
1407 separatingNormals[i] = sepNormal;
1417 __kernel void findSeparatingAxisVertexFaceKernel( __global const int4* pairs,
1418 __global const BodyData* rigidBodies,
1419 __global const btCollidableGpu* collidables,
1420 __global const ConvexPolyhedronCL* convexShapes,
1421 __global const float4* vertices,
1422 __global const float4* uniqueEdges,
1423 __global const btGpuFace* faces,
1424 __global const int* indices,
1425 __global btAabbCL* aabbs,
1426 __global volatile float4* separatingNormals,
1427 __global volatile int* hasSeparatingAxis,
1428 __global float* dmins,
1433 int i = get_global_id(0);
1439 int bodyIndexA = pairs[i].x;
1440 int bodyIndexB = pairs[i].y;
1442 int collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;
1443 int collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx;
1445 int shapeIndexA = collidables[collidableIndexA].m_shapeIndex;
1446 int shapeIndexB = collidables[collidableIndexB].m_shapeIndex;
1448 hasSeparatingAxis[i] = 0;
1450 //once the broadphase avoids static-static pairs, we can remove this test
1451 if ((rigidBodies[bodyIndexA].m_invMass==0) &&(rigidBodies[bodyIndexB].m_invMass==0))
1457 if ((collidables[collidableIndexA].m_shapeType!=SHAPE_CONVEX_HULL) ||(collidables[collidableIndexB].m_shapeType!=SHAPE_CONVEX_HULL))
1463 int numFacesA = convexShapes[shapeIndexA].m_numFaces;
1465 float dmin = FLT_MAX;
1469 float4 posA = rigidBodies[bodyIndexA].m_pos;
1471 float4 posB = rigidBodies[bodyIndexB].m_pos;
1473 float4 c0local = convexShapes[shapeIndexA].m_localCenter;
1474 float4 ornA = rigidBodies[bodyIndexA].m_quat;
1475 float4 c0 = transform(&c0local, &posA, &ornA);
1476 float4 c1local = convexShapes[shapeIndexB].m_localCenter;
1477 float4 ornB =rigidBodies[bodyIndexB].m_quat;
1478 float4 c1 = transform(&c1local,&posB,&ornB);
1479 const float4 DeltaC2 = c0 - c1;
1482 bool sepA = findSeparatingAxis( &convexShapes[shapeIndexA], &convexShapes[shapeIndexB],posA,ornA,
1485 vertices,uniqueEdges,faces,
1486 indices,&sepNormal,&dmin);
1487 hasSeparatingAxis[i] = 4;
1490 hasSeparatingAxis[i] = 0;
1493 bool sepB = findSeparatingAxis( &convexShapes[shapeIndexB],&convexShapes[shapeIndexA],posB,ornB,
1496 vertices,uniqueEdges,faces,
1497 indices,&sepNormal,&dmin);
1502 hasSeparatingAxis[i] = 1;
1503 separatingNormals[i] = sepNormal;
1512 __kernel void findSeparatingAxisEdgeEdgeKernel( __global const int4* pairs,
1513 __global const BodyData* rigidBodies,
1514 __global const btCollidableGpu* collidables,
1515 __global const ConvexPolyhedronCL* convexShapes,
1516 __global const float4* vertices,
1517 __global const float4* uniqueEdges,
1518 __global const btGpuFace* faces,
1519 __global const int* indices,
1520 __global btAabbCL* aabbs,
1521 __global float4* separatingNormals,
1522 __global int* hasSeparatingAxis,
1523 __global float* dmins,
1524 __global const float4* unitSphereDirections,
1525 int numUnitSphereDirections,
1530 int i = get_global_id(0);
1535 if (hasSeparatingAxis[i])
1538 int bodyIndexA = pairs[i].x;
1539 int bodyIndexB = pairs[i].y;
1541 int collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;
1542 int collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx;
1544 int shapeIndexA = collidables[collidableIndexA].m_shapeIndex;
1545 int shapeIndexB = collidables[collidableIndexB].m_shapeIndex;
1548 int numFacesA = convexShapes[shapeIndexA].m_numFaces;
1550 float dmin = dmins[i];
1552 float4 posA = rigidBodies[bodyIndexA].m_pos;
1554 float4 posB = rigidBodies[bodyIndexB].m_pos;
1556 float4 c0local = convexShapes[shapeIndexA].m_localCenter;
1557 float4 ornA = rigidBodies[bodyIndexA].m_quat;
1558 float4 c0 = transform(&c0local, &posA, &ornA);
1559 float4 c1local = convexShapes[shapeIndexB].m_localCenter;
1560 float4 ornB =rigidBodies[bodyIndexB].m_quat;
1561 float4 c1 = transform(&c1local,&posB,&ornB);
1562 const float4 DeltaC2 = c0 - c1;
1563 float4 sepNormal = separatingNormals[i];
1568 int numEdgeEdgeDirections = convexShapes[shapeIndexA].m_numUniqueEdges*convexShapes[shapeIndexB].m_numUniqueEdges;
1569 if (numEdgeEdgeDirections<=numUnitSphereDirections)
1571 sepEE = findSeparatingAxisEdgeEdge( &convexShapes[shapeIndexA], &convexShapes[shapeIndexB],posA,ornA,
1574 vertices,uniqueEdges,faces,
1575 indices,&sepNormal,&dmin);
1579 hasSeparatingAxis[i] = 0;
1582 hasSeparatingAxis[i] = 1;
1583 separatingNormals[i] = sepNormal;
1587 ///else case is a separate kernel, to make Mac OSX OpenCL compiler happy
1590 sepEE = findSeparatingAxisUnitSphere(&convexShapes[shapeIndexA], &convexShapes[shapeIndexB],posA,ornA,
1593 vertices,unitSphereDirections,numUnitSphereDirections,
1597 hasSeparatingAxis[i] = 0;
1600 hasSeparatingAxis[i] = 1;
1601 separatingNormals[i] = sepNormal;
1605 } //if (hasSeparatingAxis[i])
1613 inline int findClippingFaces(const float4 separatingNormal,
1614 const ConvexPolyhedronCL* hullA,
1615 __global const ConvexPolyhedronCL* hullB,
1616 const float4 posA, const Quaternion ornA,const float4 posB, const Quaternion ornB,
1617 __global float4* worldVertsA1,
1618 __global float4* worldNormalsA1,
1619 __global float4* worldVertsB1,
1620 int capacityWorldVerts,
1621 const float minDist, float maxDist,
1622 const float4* verticesA,
1623 const btGpuFace* facesA,
1624 const int* indicesA,
1625 __global const float4* verticesB,
1626 __global const btGpuFace* facesB,
1627 __global const int* indicesB,
1628 __global int4* clippingFaces, int pairIndex)
1630 int numContactsOut = 0;
1631 int numWorldVertsB1= 0;
1635 float dmax = -FLT_MAX;
1638 for(int face=0;face<hullB->m_numFaces;face++)
1640 const float4 Normal = make_float4(facesB[hullB->m_faceOffset+face].m_plane.x,
1641 facesB[hullB->m_faceOffset+face].m_plane.y, facesB[hullB->m_faceOffset+face].m_plane.z,0.f);
1642 const float4 WorldNormal = qtRotate(ornB, Normal);
1643 float d = dot3F4(WorldNormal,separatingNormal);
1647 closestFaceB = face;
1653 const btGpuFace polyB = facesB[hullB->m_faceOffset+closestFaceB];
1654 int numVertices = polyB.m_numIndices;
1655 if (numVertices>capacityWorldVerts)
1656 numVertices = capacityWorldVerts;
1658 for(int e0=0;e0<numVertices;e0++)
1660 if (e0<capacityWorldVerts)
1662 const float4 b = verticesB[hullB->m_vertexOffset+indicesB[polyB.m_indexOffset+e0]];
1663 worldVertsB1[pairIndex*capacityWorldVerts+numWorldVertsB1++] = transform(&b,&posB,&ornB);
1670 float dmin = FLT_MAX;
1671 for(int face=0;face<hullA->m_numFaces;face++)
1673 const float4 Normal = make_float4(
1674 facesA[hullA->m_faceOffset+face].m_plane.x,
1675 facesA[hullA->m_faceOffset+face].m_plane.y,
1676 facesA[hullA->m_faceOffset+face].m_plane.z,
1678 const float4 faceANormalWS = qtRotate(ornA,Normal);
1680 float d = dot3F4(faceANormalWS,separatingNormal);
1684 closestFaceA = face;
1685 worldNormalsA1[pairIndex] = faceANormalWS;
1690 int numVerticesA = facesA[hullA->m_faceOffset+closestFaceA].m_numIndices;
1691 if (numVerticesA>capacityWorldVerts)
1692 numVerticesA = capacityWorldVerts;
1694 for(int e0=0;e0<numVerticesA;e0++)
1696 if (e0<capacityWorldVerts)
1698 const float4 a = verticesA[hullA->m_vertexOffset+indicesA[facesA[hullA->m_faceOffset+closestFaceA].m_indexOffset+e0]];
1699 worldVertsA1[pairIndex*capacityWorldVerts+e0] = transform(&a, &posA,&ornA);
1703 clippingFaces[pairIndex].x = closestFaceA;
1704 clippingFaces[pairIndex].y = closestFaceB;
1705 clippingFaces[pairIndex].z = numVerticesA;
1706 clippingFaces[pairIndex].w = numWorldVertsB1;
1709 return numContactsOut;
1716 __kernel void findConcaveSeparatingAxisKernel( __global int4* concavePairs,
1717 __global const BodyData* rigidBodies,
1718 __global const btCollidableGpu* collidables,
1719 __global const ConvexPolyhedronCL* convexShapes,
1720 __global const float4* vertices,
1721 __global const float4* uniqueEdges,
1722 __global const btGpuFace* faces,
1723 __global const int* indices,
1724 __global const btGpuChildShape* gpuChildShapes,
1725 __global btAabbCL* aabbs,
1726 __global float4* concaveSeparatingNormalsOut,
1727 __global int* concaveHasSeparatingNormals,
1728 __global int4* clippingFacesOut,
1729 __global float4* worldVertsA1GPU,
1730 __global float4* worldNormalsAGPU,
1731 __global float4* worldVertsB1GPU,
1732 int vertexFaceCapacity,
1737 int i = get_global_id(0);
1738 if (i>=numConcavePairs)
1741 concaveHasSeparatingNormals[i] = 0;
1745 int bodyIndexA = concavePairs[i].x;
1746 int bodyIndexB = concavePairs[i].y;
1748 int collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;
1749 int collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx;
1751 int shapeIndexA = collidables[collidableIndexA].m_shapeIndex;
1752 int shapeIndexB = collidables[collidableIndexB].m_shapeIndex;
1754 if (collidables[collidableIndexB].m_shapeType!=SHAPE_CONVEX_HULL&&
1755 collidables[collidableIndexB].m_shapeType!=SHAPE_COMPOUND_OF_CONVEX_HULLS)
1757 concavePairs[pairIdx].w = -1;
1763 int numFacesA = convexShapes[shapeIndexA].m_numFaces;
1764 int numActualConcaveConvexTests = 0;
1766 int f = concavePairs[i].z;
1768 bool overlap = false;
1770 ConvexPolyhedronCL convexPolyhedronA;
1772 //add 3 vertices of the triangle
1773 convexPolyhedronA.m_numVertices = 3;
1774 convexPolyhedronA.m_vertexOffset = 0;
1775 float4 localCenter = make_float4(0.f,0.f,0.f,0.f);
1777 btGpuFace face = faces[convexShapes[shapeIndexA].m_faceOffset+f];
1778 float4 triMinAabb, triMaxAabb;
1780 triAabb.m_min = make_float4(1e30f,1e30f,1e30f,0.f);
1781 triAabb.m_max = make_float4(-1e30f,-1e30f,-1e30f,0.f);
1783 float4 verticesA[3];
1784 for (int i=0;i<3;i++)
1786 int index = indices[face.m_indexOffset+i];
1787 float4 vert = vertices[convexShapes[shapeIndexA].m_vertexOffset+index];
1788 verticesA[i] = vert;
1789 localCenter += vert;
1791 triAabb.m_min = min(triAabb.m_min,vert);
1792 triAabb.m_max = max(triAabb.m_max,vert);
1797 overlap = (triAabb.m_min.x > aabbs[bodyIndexB].m_max.x || triAabb.m_max.x < aabbs[bodyIndexB].m_min.x) ? false : overlap;
1798 overlap = (triAabb.m_min.z > aabbs[bodyIndexB].m_max.z || triAabb.m_max.z < aabbs[bodyIndexB].m_min.z) ? false : overlap;
1799 overlap = (triAabb.m_min.y > aabbs[bodyIndexB].m_max.y || triAabb.m_max.y < aabbs[bodyIndexB].m_min.y) ? false : overlap;
1803 float dmin = FLT_MAX;
1804 int hasSeparatingAxis=5;
1805 float4 sepAxis=make_float4(1,2,3,4);
1808 numActualConcaveConvexTests++;
1810 //a triangle has 3 unique edges
1811 convexPolyhedronA.m_numUniqueEdges = 3;
1812 convexPolyhedronA.m_uniqueEdgesOffset = 0;
1813 float4 uniqueEdgesA[3];
1815 uniqueEdgesA[0] = (verticesA[1]-verticesA[0]);
1816 uniqueEdgesA[1] = (verticesA[2]-verticesA[1]);
1817 uniqueEdgesA[2] = (verticesA[0]-verticesA[2]);
1820 convexPolyhedronA.m_faceOffset = 0;
1822 float4 normal = make_float4(face.m_plane.x,face.m_plane.y,face.m_plane.z,0.f);
1824 btGpuFace facesA[TRIANGLE_NUM_CONVEX_FACES];
1825 int indicesA[3+3+2+2+2];
1826 int curUsedIndices=0;
1829 //front size of triangle
1831 facesA[fidx].m_indexOffset=curUsedIndices;
1836 float c = face.m_plane.w;
1837 facesA[fidx].m_plane.x = normal.x;
1838 facesA[fidx].m_plane.y = normal.y;
1839 facesA[fidx].m_plane.z = normal.z;
1840 facesA[fidx].m_plane.w = c;
1841 facesA[fidx].m_numIndices=3;
1844 //back size of triangle
1846 facesA[fidx].m_indexOffset=curUsedIndices;
1851 float c = dot(normal,verticesA[0]);
1852 float c1 = -face.m_plane.w;
1853 facesA[fidx].m_plane.x = -normal.x;
1854 facesA[fidx].m_plane.y = -normal.y;
1855 facesA[fidx].m_plane.z = -normal.z;
1856 facesA[fidx].m_plane.w = c;
1857 facesA[fidx].m_numIndices=3;
1861 bool addEdgePlanes = true;
1865 int prevVertex = numVertices-1;
1866 for (int i=0;i<numVertices;i++)
1868 float4 v0 = verticesA[i];
1869 float4 v1 = verticesA[prevVertex];
1871 float4 edgeNormal = normalize(cross(normal,v1-v0));
1872 float c = -dot(edgeNormal,v0);
1874 facesA[fidx].m_numIndices = 2;
1875 facesA[fidx].m_indexOffset=curUsedIndices;
1876 indicesA[curUsedIndices++]=i;
1877 indicesA[curUsedIndices++]=prevVertex;
1879 facesA[fidx].m_plane.x = edgeNormal.x;
1880 facesA[fidx].m_plane.y = edgeNormal.y;
1881 facesA[fidx].m_plane.z = edgeNormal.z;
1882 facesA[fidx].m_plane.w = c;
1887 convexPolyhedronA.m_numFaces = TRIANGLE_NUM_CONVEX_FACES;
1888 convexPolyhedronA.m_localCenter = localCenter*(1.f/3.f);
1891 float4 posA = rigidBodies[bodyIndexA].m_pos;
1893 float4 posB = rigidBodies[bodyIndexB].m_pos;
1896 float4 ornA = rigidBodies[bodyIndexA].m_quat;
1897 float4 ornB =rigidBodies[bodyIndexB].m_quat;
1903 ///compound shape support
1905 if (collidables[collidableIndexB].m_shapeType==SHAPE_COMPOUND_OF_CONVEX_HULLS)
1907 int compoundChild = concavePairs[pairIdx].w;
1908 int childShapeIndexB = compoundChild;//collidables[collidableIndexB].m_shapeIndex+compoundChild;
1909 int childColIndexB = gpuChildShapes[childShapeIndexB].m_shapeIndex;
1910 float4 childPosB = gpuChildShapes[childShapeIndexB].m_childPosition;
1911 float4 childOrnB = gpuChildShapes[childShapeIndexB].m_childOrientation;
1912 float4 newPosB = transform(&childPosB,&posB,&ornB);
1913 float4 newOrnB = qtMul(ornB,childOrnB);
1916 shapeIndexB = collidables[childColIndexB].m_shapeIndex;
1920 float4 c0local = convexPolyhedronA.m_localCenter;
1921 float4 c0 = transform(&c0local, &posA, &ornA);
1922 float4 c1local = convexShapes[shapeIndexB].m_localCenter;
1923 float4 c1 = transform(&c1local,&posB,&ornB);
1924 const float4 DeltaC2 = c0 - c1;
1927 bool sepA = findSeparatingAxisLocalA( &convexPolyhedronA, &convexShapes[shapeIndexB],
1931 verticesA,uniqueEdgesA,facesA,indicesA,
1932 vertices,uniqueEdges,faces,indices,
1934 hasSeparatingAxis = 4;
1937 hasSeparatingAxis = 0;
1940 bool sepB = findSeparatingAxisLocalB( &convexShapes[shapeIndexB],&convexPolyhedronA,
1944 vertices,uniqueEdges,faces,indices,
1945 verticesA,uniqueEdgesA,facesA,indicesA,
1950 hasSeparatingAxis = 0;
1953 bool sepEE = findSeparatingAxisEdgeEdgeLocalA( &convexPolyhedronA, &convexShapes[shapeIndexB],
1957 verticesA,uniqueEdgesA,facesA,indicesA,
1958 vertices,uniqueEdges,faces,indices,
1963 hasSeparatingAxis = 0;
1966 hasSeparatingAxis = 1;
1971 if (hasSeparatingAxis)
1974 concaveSeparatingNormalsOut[pairIdx]=sepAxis;
1975 concaveHasSeparatingNormals[i]=1;
1978 float minDist = -1e30f;
1979 float maxDist = 0.02f;
1983 findClippingFaces(sepAxis,
1985 &convexShapes[shapeIndexB],
1999 clippingFacesOut, pairIdx);
2004 //mark this pair as in-active
2005 concavePairs[pairIdx].w = -1;
2010 //mark this pair as in-active
2011 concavePairs[pairIdx].w = -1;
2014 concavePairs[pairIdx].z = -1;//now z is used for existing/persistent contacts