2 //keep this enum in sync with the CPU version (in btCollidable.h)
3 //written by Erwin Coumans
6 #define SHAPE_CONVEX_HULL 3
7 #define SHAPE_CONCAVE_TRIMESH 5
8 #define TRIANGLE_NUM_CONVEX_FACES 5
9 #define SHAPE_COMPOUND_OF_CONVEX_HULLS 6
11 #define B3_MAX_STACK_DEPTH 256
14 typedef unsigned int u32;
16 ///keep this in sync with btCollidable.h
26 int m_compoundBvhIndex;
34 #define MAX_NUM_PARTS_IN_BITS 10
36 ///b3QuantizedBvhNode is a compressed aabb node, 16 bytes.
37 ///Node can be used for leafnode or internal node. Leafnodes can point to 32-bit triangle index (non-negative range).
41 unsigned short int m_quantizedAabbMin[3];
42 unsigned short int m_quantizedAabbMax[3];
44 int m_escapeIndexOrTriangleIndex;
51 float4 m_quantization;
60 int getTriangleIndex(const b3QuantizedBvhNode* rootNode)
63 unsigned int y = (~(x&0))<<(31-MAX_NUM_PARTS_IN_BITS);
64 // Get only the lower bits where the triangle index is stored
65 return (rootNode->m_escapeIndexOrTriangleIndex&~(y));
68 int getTriangleIndexGlobal(__global const b3QuantizedBvhNode* rootNode)
71 unsigned int y = (~(x&0))<<(31-MAX_NUM_PARTS_IN_BITS);
72 // Get only the lower bits where the triangle index is stored
73 return (rootNode->m_escapeIndexOrTriangleIndex&~(y));
76 int isLeafNode(const b3QuantizedBvhNode* rootNode)
78 //skipindex is negative (internal node), triangleindex >=0 (leafnode)
79 return (rootNode->m_escapeIndexOrTriangleIndex >= 0)? 1 : 0;
82 int isLeafNodeGlobal(__global const b3QuantizedBvhNode* rootNode)
84 //skipindex is negative (internal node), triangleindex >=0 (leafnode)
85 return (rootNode->m_escapeIndexOrTriangleIndex >= 0)? 1 : 0;
88 int getEscapeIndex(const b3QuantizedBvhNode* rootNode)
90 return -rootNode->m_escapeIndexOrTriangleIndex;
93 int getEscapeIndexGlobal(__global const b3QuantizedBvhNode* rootNode)
95 return -rootNode->m_escapeIndexOrTriangleIndex;
102 unsigned short int m_quantizedAabbMin[3];
103 unsigned short int m_quantizedAabbMax[3];
104 //4 bytes, points to the root of the subtree
119 float4 m_childPosition;
120 float4 m_childOrientation;
137 float m_restituitionCoeff;
138 float m_frictionCoeff;
144 float4 m_localCenter;
155 int m_uniqueEdgesOffset;
156 int m_numUniqueEdges;
158 } ConvexPolyhedronCL;
176 #include "Bullet3Collision/BroadPhaseCollision/shared/b3Aabb.h"
177 #include "Bullet3Common/shared/b3Int2.h"
188 #define make_float4 (float4)
192 float4 cross3(float4 a, float4 b)
197 // float4 a1 = make_float4(a.xyz,0.f);
198 // float4 b1 = make_float4(b.xyz,0.f);
200 // return cross(a1,b1);
202 //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);
204 // float4 c = make_float4(a.y*b.z - a.z*b.y,1.f,a.x*b.y - a.y*b.x,0.f);
210 float dot3F4(float4 a, float4 b)
212 float4 a1 = make_float4(a.xyz,0.f);
213 float4 b1 = make_float4(b.xyz,0.f);
218 float4 fastNormalize4(float4 v)
220 v = make_float4(v.xyz,0.f);
221 return fast_normalize(v);
225 ///////////////////////////////////////
227 ///////////////////////////////////////
229 typedef float4 Quaternion;
232 Quaternion qtMul(Quaternion a, Quaternion b);
235 Quaternion qtNormalize(Quaternion in);
238 float4 qtRotate(Quaternion q, float4 vec);
241 Quaternion qtInvert(Quaternion q);
247 Quaternion qtMul(Quaternion a, Quaternion b)
250 ans = cross3( a, b );
252 // ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);
253 ans.w = a.w*b.w - dot3F4(a, b);
258 Quaternion qtNormalize(Quaternion in)
260 return fastNormalize4(in);
261 // in /= length( in );
265 float4 qtRotate(Quaternion q, float4 vec)
267 Quaternion qInv = qtInvert( q );
270 float4 out = qtMul(qtMul(q,vcpy),qInv);
275 Quaternion qtInvert(Quaternion q)
277 return (Quaternion)(-q.xyz, q.w);
281 float4 qtInvRotate(const Quaternion q, float4 vec)
283 return qtRotate( qtInvert( q ), vec );
287 float4 transform(const float4* p, const float4* translation, const Quaternion* orientation)
289 return qtRotate( *orientation, *p ) + (*translation);
295 float4 normalize3(const float4 a)
297 float4 n = make_float4(a.x, a.y, a.z, 0.f);
298 return fastNormalize4( n );
301 inline void projectLocal(const ConvexPolyhedronCL* hull, const float4 pos, const float4 orn,
302 const float4* dir, const float4* vertices, float* min, float* max)
306 int numVerts = hull->m_numVertices;
308 const float4 localDir = qtInvRotate(orn,*dir);
309 float offset = dot(pos,*dir);
310 for(int i=0;i<numVerts;i++)
312 float dp = dot(vertices[hull->m_vertexOffset+i],localDir);
328 inline void project(__global const ConvexPolyhedronCL* hull, const float4 pos, const float4 orn,
329 const float4* dir, __global const float4* vertices, float* min, float* max)
333 int numVerts = hull->m_numVertices;
335 const float4 localDir = qtInvRotate(orn,*dir);
336 float offset = dot(pos,*dir);
337 for(int i=0;i<numVerts;i++)
339 float dp = dot(vertices[hull->m_vertexOffset+i],localDir);
355 inline bool TestSepAxisLocalA(const ConvexPolyhedronCL* hullA, __global const ConvexPolyhedronCL* hullB,
356 const float4 posA,const float4 ornA,
357 const float4 posB,const float4 ornB,
358 float4* sep_axis, const float4* verticesA, __global const float4* verticesB,float* depth)
362 projectLocal(hullA,posA,ornA,sep_axis,verticesA, &Min0, &Max0);
363 project(hullB,posB,ornB, sep_axis,verticesB, &Min1, &Max1);
365 if(Max0<Min1 || Max1<Min0)
368 float d0 = Max0 - Min1;
369 float d1 = Max1 - Min0;
370 *depth = d0<d1 ? d0:d1;
377 inline bool IsAlmostZero(const float4 v)
379 if(fabs(v.x)>1e-6f || fabs(v.y)>1e-6f || fabs(v.z)>1e-6f)
386 bool findSeparatingAxisLocalA( const ConvexPolyhedronCL* hullA, __global const ConvexPolyhedronCL* hullB,
391 const float4 DeltaC2,
393 const float4* verticesA,
394 const float4* uniqueEdgesA,
395 const btGpuFace* facesA,
398 __global const float4* verticesB,
399 __global const float4* uniqueEdgesB,
400 __global const btGpuFace* facesB,
401 __global const int* indicesB,
413 int numFacesA = hullA->m_numFaces;
414 // Test normals from hullA
415 for(int i=0;i<numFacesA;i++)
417 const float4 normal = facesA[hullA->m_faceOffset+i].m_plane;
418 float4 faceANormalWS = qtRotate(ornA,normal);
419 if (dot3F4(DeltaC2,faceANormalWS)<0)
423 if(!TestSepAxisLocalA( hullA, hullB, posA,ornA,posB,ornB,&faceANormalWS, verticesA, verticesB,&d))
428 *sep = faceANormalWS;
432 if((dot3F4(-DeltaC2,*sep))>0.0f)
439 bool findSeparatingAxisLocalB( __global const ConvexPolyhedronCL* hullA, const ConvexPolyhedronCL* hullB,
444 const float4 DeltaC2,
445 __global const float4* verticesA,
446 __global const float4* uniqueEdgesA,
447 __global const btGpuFace* facesA,
448 __global const int* indicesA,
449 const float4* verticesB,
450 const float4* uniqueEdgesB,
451 const btGpuFace* facesB,
464 int numFacesA = hullA->m_numFaces;
465 // Test normals from hullA
466 for(int i=0;i<numFacesA;i++)
468 const float4 normal = facesA[hullA->m_faceOffset+i].m_plane;
469 float4 faceANormalWS = qtRotate(ornA,normal);
470 if (dot3F4(DeltaC2,faceANormalWS)<0)
471 faceANormalWS *= -1.f;
474 if(!TestSepAxisLocalA( hullB, hullA, posB,ornB,posA,ornA, &faceANormalWS, verticesB,verticesA, &d))
479 *sep = faceANormalWS;
483 if((dot3F4(-DeltaC2,*sep))>0.0f)
492 bool findSeparatingAxisEdgeEdgeLocalA( const ConvexPolyhedronCL* hullA, __global const ConvexPolyhedronCL* hullB,
497 const float4 DeltaC2,
498 const float4* verticesA,
499 const float4* uniqueEdgesA,
500 const btGpuFace* facesA,
502 __global const float4* verticesB,
503 __global const float4* uniqueEdgesB,
504 __global const btGpuFace* facesB,
505 __global const int* indicesB,
520 for(int e0=0;e0<hullA->m_numUniqueEdges;e0++)
522 const float4 edge0 = uniqueEdgesA[hullA->m_uniqueEdgesOffset+e0];
523 float4 edge0World = qtRotate(ornA,edge0);
525 for(int e1=0;e1<hullB->m_numUniqueEdges;e1++)
527 const float4 edge1 = uniqueEdgesB[hullB->m_uniqueEdgesOffset+e1];
528 float4 edge1World = qtRotate(ornB,edge1);
531 float4 crossje = cross3(edge0World,edge1World);
534 if(!IsAlmostZero(crossje))
536 crossje = normalize3(crossje);
537 if (dot3F4(DeltaC2,crossje)<0)
545 projectLocal(hullA,posA,ornA,&crossje,verticesA, &Min0, &Max0);
546 project(hullB,posB,ornB,&crossje,verticesB, &Min1, &Max1);
548 if(Max0<Min1 || Max1<Min0)
551 float d0 = Max0 - Min1;
552 float d1 = Max1 - Min0;
553 dist = d0<d1 ? d0:d1;
570 if((dot3F4(-DeltaC2,*sep))>0.0f)
579 inline int findClippingFaces(const float4 separatingNormal,
580 const ConvexPolyhedronCL* hullA,
581 __global const ConvexPolyhedronCL* hullB,
582 const float4 posA, const Quaternion ornA,const float4 posB, const Quaternion ornB,
583 __global float4* worldVertsA1,
584 __global float4* worldNormalsA1,
585 __global float4* worldVertsB1,
586 int capacityWorldVerts,
587 const float minDist, float maxDist,
588 const float4* verticesA,
589 const btGpuFace* facesA,
591 __global const float4* verticesB,
592 __global const btGpuFace* facesB,
593 __global const int* indicesB,
594 __global int4* clippingFaces, int pairIndex)
596 int numContactsOut = 0;
597 int numWorldVertsB1= 0;
601 float dmax = -FLT_MAX;
604 for(int face=0;face<hullB->m_numFaces;face++)
606 const float4 Normal = make_float4(facesB[hullB->m_faceOffset+face].m_plane.x,
607 facesB[hullB->m_faceOffset+face].m_plane.y, facesB[hullB->m_faceOffset+face].m_plane.z,0.f);
608 const float4 WorldNormal = qtRotate(ornB, Normal);
609 float d = dot3F4(WorldNormal,separatingNormal);
619 const btGpuFace polyB = facesB[hullB->m_faceOffset+closestFaceB];
620 int numVertices = polyB.m_numIndices;
621 if (numVertices>capacityWorldVerts)
622 numVertices = capacityWorldVerts;
626 for(int e0=0;e0<numVertices;e0++)
628 if (e0<capacityWorldVerts)
630 const float4 b = verticesB[hullB->m_vertexOffset+indicesB[polyB.m_indexOffset+e0]];
631 worldVertsB1[pairIndex*capacityWorldVerts+numWorldVertsB1++] = transform(&b,&posB,&ornB);
638 float dmin = FLT_MAX;
639 for(int face=0;face<hullA->m_numFaces;face++)
641 const float4 Normal = make_float4(
642 facesA[hullA->m_faceOffset+face].m_plane.x,
643 facesA[hullA->m_faceOffset+face].m_plane.y,
644 facesA[hullA->m_faceOffset+face].m_plane.z,
646 const float4 faceANormalWS = qtRotate(ornA,Normal);
648 float d = dot3F4(faceANormalWS,separatingNormal);
653 worldNormalsA1[pairIndex] = faceANormalWS;
658 int numVerticesA = facesA[hullA->m_faceOffset+closestFaceA].m_numIndices;
659 if (numVerticesA>capacityWorldVerts)
660 numVerticesA = capacityWorldVerts;
664 for(int e0=0;e0<numVerticesA;e0++)
666 if (e0<capacityWorldVerts)
668 const float4 a = verticesA[hullA->m_vertexOffset+indicesA[facesA[hullA->m_faceOffset+closestFaceA].m_indexOffset+e0]];
669 worldVertsA1[pairIndex*capacityWorldVerts+e0] = transform(&a, &posA,&ornA);
673 clippingFaces[pairIndex].x = closestFaceA;
674 clippingFaces[pairIndex].y = closestFaceB;
675 clippingFaces[pairIndex].z = numVerticesA;
676 clippingFaces[pairIndex].w = numWorldVertsB1;
679 return numContactsOut;
686 __kernel void findConcaveSeparatingAxisVertexFaceKernel( __global int4* concavePairs,
687 __global const BodyData* rigidBodies,
688 __global const btCollidableGpu* collidables,
689 __global const ConvexPolyhedronCL* convexShapes,
690 __global const float4* vertices,
691 __global const float4* uniqueEdges,
692 __global const btGpuFace* faces,
693 __global const int* indices,
694 __global const btGpuChildShape* gpuChildShapes,
695 __global btAabbCL* aabbs,
696 __global float4* concaveSeparatingNormalsOut,
697 __global int* concaveHasSeparatingNormals,
698 __global int4* clippingFacesOut,
699 __global float4* worldVertsA1GPU,
700 __global float4* worldNormalsAGPU,
701 __global float4* worldVertsB1GPU,
702 __global float* dmins,
703 int vertexFaceCapacity,
708 int i = get_global_id(0);
709 if (i>=numConcavePairs)
712 concaveHasSeparatingNormals[i] = 0;
716 int bodyIndexA = concavePairs[i].x;
717 int bodyIndexB = concavePairs[i].y;
719 int collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;
720 int collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx;
722 int shapeIndexA = collidables[collidableIndexA].m_shapeIndex;
723 int shapeIndexB = collidables[collidableIndexB].m_shapeIndex;
725 if (collidables[collidableIndexB].m_shapeType!=SHAPE_CONVEX_HULL&&
726 collidables[collidableIndexB].m_shapeType!=SHAPE_COMPOUND_OF_CONVEX_HULLS)
728 concavePairs[pairIdx].w = -1;
734 int numFacesA = convexShapes[shapeIndexA].m_numFaces;
735 int numActualConcaveConvexTests = 0;
737 int f = concavePairs[i].z;
739 bool overlap = false;
741 ConvexPolyhedronCL convexPolyhedronA;
743 //add 3 vertices of the triangle
744 convexPolyhedronA.m_numVertices = 3;
745 convexPolyhedronA.m_vertexOffset = 0;
746 float4 localCenter = make_float4(0.f,0.f,0.f,0.f);
748 btGpuFace face = faces[convexShapes[shapeIndexA].m_faceOffset+f];
749 float4 triMinAabb, triMaxAabb;
751 triAabb.m_min = make_float4(1e30f,1e30f,1e30f,0.f);
752 triAabb.m_max = make_float4(-1e30f,-1e30f,-1e30f,0.f);
755 for (int i=0;i<3;i++)
757 int index = indices[face.m_indexOffset+i];
758 float4 vert = vertices[convexShapes[shapeIndexA].m_vertexOffset+index];
762 triAabb.m_min = min(triAabb.m_min,vert);
763 triAabb.m_max = max(triAabb.m_max,vert);
768 overlap = (triAabb.m_min.x > aabbs[bodyIndexB].m_max.x || triAabb.m_max.x < aabbs[bodyIndexB].m_min.x) ? false : overlap;
769 overlap = (triAabb.m_min.z > aabbs[bodyIndexB].m_max.z || triAabb.m_max.z < aabbs[bodyIndexB].m_min.z) ? false : overlap;
770 overlap = (triAabb.m_min.y > aabbs[bodyIndexB].m_max.y || triAabb.m_max.y < aabbs[bodyIndexB].m_min.y) ? false : overlap;
774 float dmin = FLT_MAX;
775 int hasSeparatingAxis=5;
776 float4 sepAxis=make_float4(1,2,3,4);
779 numActualConcaveConvexTests++;
781 //a triangle has 3 unique edges
782 convexPolyhedronA.m_numUniqueEdges = 3;
783 convexPolyhedronA.m_uniqueEdgesOffset = 0;
784 float4 uniqueEdgesA[3];
786 uniqueEdgesA[0] = (verticesA[1]-verticesA[0]);
787 uniqueEdgesA[1] = (verticesA[2]-verticesA[1]);
788 uniqueEdgesA[2] = (verticesA[0]-verticesA[2]);
791 convexPolyhedronA.m_faceOffset = 0;
793 float4 normal = make_float4(face.m_plane.x,face.m_plane.y,face.m_plane.z,0.f);
795 btGpuFace facesA[TRIANGLE_NUM_CONVEX_FACES];
796 int indicesA[3+3+2+2+2];
797 int curUsedIndices=0;
800 //front size of triangle
802 facesA[fidx].m_indexOffset=curUsedIndices;
807 float c = face.m_plane.w;
808 facesA[fidx].m_plane.x = normal.x;
809 facesA[fidx].m_plane.y = normal.y;
810 facesA[fidx].m_plane.z = normal.z;
811 facesA[fidx].m_plane.w = c;
812 facesA[fidx].m_numIndices=3;
815 //back size of triangle
817 facesA[fidx].m_indexOffset=curUsedIndices;
822 float c = dot(normal,verticesA[0]);
823 float c1 = -face.m_plane.w;
824 facesA[fidx].m_plane.x = -normal.x;
825 facesA[fidx].m_plane.y = -normal.y;
826 facesA[fidx].m_plane.z = -normal.z;
827 facesA[fidx].m_plane.w = c;
828 facesA[fidx].m_numIndices=3;
832 bool addEdgePlanes = true;
836 int prevVertex = numVertices-1;
837 for (int i=0;i<numVertices;i++)
839 float4 v0 = verticesA[i];
840 float4 v1 = verticesA[prevVertex];
842 float4 edgeNormal = normalize(cross(normal,v1-v0));
843 float c = -dot(edgeNormal,v0);
845 facesA[fidx].m_numIndices = 2;
846 facesA[fidx].m_indexOffset=curUsedIndices;
847 indicesA[curUsedIndices++]=i;
848 indicesA[curUsedIndices++]=prevVertex;
850 facesA[fidx].m_plane.x = edgeNormal.x;
851 facesA[fidx].m_plane.y = edgeNormal.y;
852 facesA[fidx].m_plane.z = edgeNormal.z;
853 facesA[fidx].m_plane.w = c;
858 convexPolyhedronA.m_numFaces = TRIANGLE_NUM_CONVEX_FACES;
859 convexPolyhedronA.m_localCenter = localCenter*(1.f/3.f);
862 float4 posA = rigidBodies[bodyIndexA].m_pos;
864 float4 posB = rigidBodies[bodyIndexB].m_pos;
867 float4 ornA = rigidBodies[bodyIndexA].m_quat;
868 float4 ornB =rigidBodies[bodyIndexB].m_quat;
874 ///compound shape support
876 if (collidables[collidableIndexB].m_shapeType==SHAPE_COMPOUND_OF_CONVEX_HULLS)
878 int compoundChild = concavePairs[pairIdx].w;
879 int childShapeIndexB = compoundChild;//collidables[collidableIndexB].m_shapeIndex+compoundChild;
880 int childColIndexB = gpuChildShapes[childShapeIndexB].m_shapeIndex;
881 float4 childPosB = gpuChildShapes[childShapeIndexB].m_childPosition;
882 float4 childOrnB = gpuChildShapes[childShapeIndexB].m_childOrientation;
883 float4 newPosB = transform(&childPosB,&posB,&ornB);
884 float4 newOrnB = qtMul(ornB,childOrnB);
887 shapeIndexB = collidables[childColIndexB].m_shapeIndex;
891 float4 c0local = convexPolyhedronA.m_localCenter;
892 float4 c0 = transform(&c0local, &posA, &ornA);
893 float4 c1local = convexShapes[shapeIndexB].m_localCenter;
894 float4 c1 = transform(&c1local,&posB,&ornB);
895 const float4 DeltaC2 = c0 - c1;
898 bool sepA = findSeparatingAxisLocalA( &convexPolyhedronA, &convexShapes[shapeIndexB],
902 verticesA,uniqueEdgesA,facesA,indicesA,
903 vertices,uniqueEdges,faces,indices,
905 hasSeparatingAxis = 4;
908 hasSeparatingAxis = 0;
911 bool sepB = findSeparatingAxisLocalB( &convexShapes[shapeIndexB],&convexPolyhedronA,
915 vertices,uniqueEdges,faces,indices,
916 verticesA,uniqueEdgesA,facesA,indicesA,
921 hasSeparatingAxis = 0;
924 hasSeparatingAxis = 1;
928 if (hasSeparatingAxis)
931 concaveSeparatingNormalsOut[pairIdx]=sepAxis;
932 concaveHasSeparatingNormals[i]=1;
936 //mark this pair as in-active
937 concavePairs[pairIdx].w = -1;
942 //mark this pair as in-active
943 concavePairs[pairIdx].w = -1;
951 __kernel void findConcaveSeparatingAxisEdgeEdgeKernel( __global int4* concavePairs,
952 __global const BodyData* rigidBodies,
953 __global const btCollidableGpu* collidables,
954 __global const ConvexPolyhedronCL* convexShapes,
955 __global const float4* vertices,
956 __global const float4* uniqueEdges,
957 __global const btGpuFace* faces,
958 __global const int* indices,
959 __global const btGpuChildShape* gpuChildShapes,
960 __global btAabbCL* aabbs,
961 __global float4* concaveSeparatingNormalsOut,
962 __global int* concaveHasSeparatingNormals,
963 __global int4* clippingFacesOut,
964 __global float4* worldVertsA1GPU,
965 __global float4* worldNormalsAGPU,
966 __global float4* worldVertsB1GPU,
967 __global float* dmins,
968 int vertexFaceCapacity,
973 int i = get_global_id(0);
974 if (i>=numConcavePairs)
977 if (!concaveHasSeparatingNormals[i])
982 int bodyIndexA = concavePairs[i].x;
983 int bodyIndexB = concavePairs[i].y;
985 int collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;
986 int collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx;
988 int shapeIndexA = collidables[collidableIndexA].m_shapeIndex;
989 int shapeIndexB = collidables[collidableIndexB].m_shapeIndex;
992 int numFacesA = convexShapes[shapeIndexA].m_numFaces;
993 int numActualConcaveConvexTests = 0;
995 int f = concavePairs[i].z;
997 bool overlap = false;
999 ConvexPolyhedronCL convexPolyhedronA;
1001 //add 3 vertices of the triangle
1002 convexPolyhedronA.m_numVertices = 3;
1003 convexPolyhedronA.m_vertexOffset = 0;
1004 float4 localCenter = make_float4(0.f,0.f,0.f,0.f);
1006 btGpuFace face = faces[convexShapes[shapeIndexA].m_faceOffset+f];
1007 float4 triMinAabb, triMaxAabb;
1009 triAabb.m_min = make_float4(1e30f,1e30f,1e30f,0.f);
1010 triAabb.m_max = make_float4(-1e30f,-1e30f,-1e30f,0.f);
1012 float4 verticesA[3];
1013 for (int i=0;i<3;i++)
1015 int index = indices[face.m_indexOffset+i];
1016 float4 vert = vertices[convexShapes[shapeIndexA].m_vertexOffset+index];
1017 verticesA[i] = vert;
1018 localCenter += vert;
1020 triAabb.m_min = min(triAabb.m_min,vert);
1021 triAabb.m_max = max(triAabb.m_max,vert);
1026 overlap = (triAabb.m_min.x > aabbs[bodyIndexB].m_max.x || triAabb.m_max.x < aabbs[bodyIndexB].m_min.x) ? false : overlap;
1027 overlap = (triAabb.m_min.z > aabbs[bodyIndexB].m_max.z || triAabb.m_max.z < aabbs[bodyIndexB].m_min.z) ? false : overlap;
1028 overlap = (triAabb.m_min.y > aabbs[bodyIndexB].m_max.y || triAabb.m_max.y < aabbs[bodyIndexB].m_min.y) ? false : overlap;
1032 float dmin = dmins[i];
1033 int hasSeparatingAxis=5;
1034 float4 sepAxis=make_float4(1,2,3,4);
1035 sepAxis = concaveSeparatingNormalsOut[pairIdx];
1038 numActualConcaveConvexTests++;
1040 //a triangle has 3 unique edges
1041 convexPolyhedronA.m_numUniqueEdges = 3;
1042 convexPolyhedronA.m_uniqueEdgesOffset = 0;
1043 float4 uniqueEdgesA[3];
1045 uniqueEdgesA[0] = (verticesA[1]-verticesA[0]);
1046 uniqueEdgesA[1] = (verticesA[2]-verticesA[1]);
1047 uniqueEdgesA[2] = (verticesA[0]-verticesA[2]);
1050 convexPolyhedronA.m_faceOffset = 0;
1052 float4 normal = make_float4(face.m_plane.x,face.m_plane.y,face.m_plane.z,0.f);
1054 btGpuFace facesA[TRIANGLE_NUM_CONVEX_FACES];
1055 int indicesA[3+3+2+2+2];
1056 int curUsedIndices=0;
1059 //front size of triangle
1061 facesA[fidx].m_indexOffset=curUsedIndices;
1066 float c = face.m_plane.w;
1067 facesA[fidx].m_plane.x = normal.x;
1068 facesA[fidx].m_plane.y = normal.y;
1069 facesA[fidx].m_plane.z = normal.z;
1070 facesA[fidx].m_plane.w = c;
1071 facesA[fidx].m_numIndices=3;
1074 //back size of triangle
1076 facesA[fidx].m_indexOffset=curUsedIndices;
1081 float c = dot(normal,verticesA[0]);
1082 float c1 = -face.m_plane.w;
1083 facesA[fidx].m_plane.x = -normal.x;
1084 facesA[fidx].m_plane.y = -normal.y;
1085 facesA[fidx].m_plane.z = -normal.z;
1086 facesA[fidx].m_plane.w = c;
1087 facesA[fidx].m_numIndices=3;
1091 bool addEdgePlanes = true;
1095 int prevVertex = numVertices-1;
1096 for (int i=0;i<numVertices;i++)
1098 float4 v0 = verticesA[i];
1099 float4 v1 = verticesA[prevVertex];
1101 float4 edgeNormal = normalize(cross(normal,v1-v0));
1102 float c = -dot(edgeNormal,v0);
1104 facesA[fidx].m_numIndices = 2;
1105 facesA[fidx].m_indexOffset=curUsedIndices;
1106 indicesA[curUsedIndices++]=i;
1107 indicesA[curUsedIndices++]=prevVertex;
1109 facesA[fidx].m_plane.x = edgeNormal.x;
1110 facesA[fidx].m_plane.y = edgeNormal.y;
1111 facesA[fidx].m_plane.z = edgeNormal.z;
1112 facesA[fidx].m_plane.w = c;
1117 convexPolyhedronA.m_numFaces = TRIANGLE_NUM_CONVEX_FACES;
1118 convexPolyhedronA.m_localCenter = localCenter*(1.f/3.f);
1121 float4 posA = rigidBodies[bodyIndexA].m_pos;
1123 float4 posB = rigidBodies[bodyIndexB].m_pos;
1126 float4 ornA = rigidBodies[bodyIndexA].m_quat;
1127 float4 ornB =rigidBodies[bodyIndexB].m_quat;
1133 ///compound shape support
1135 if (collidables[collidableIndexB].m_shapeType==SHAPE_COMPOUND_OF_CONVEX_HULLS)
1137 int compoundChild = concavePairs[pairIdx].w;
1138 int childShapeIndexB = compoundChild;//collidables[collidableIndexB].m_shapeIndex+compoundChild;
1139 int childColIndexB = gpuChildShapes[childShapeIndexB].m_shapeIndex;
1140 float4 childPosB = gpuChildShapes[childShapeIndexB].m_childPosition;
1141 float4 childOrnB = gpuChildShapes[childShapeIndexB].m_childOrientation;
1142 float4 newPosB = transform(&childPosB,&posB,&ornB);
1143 float4 newOrnB = qtMul(ornB,childOrnB);
1146 shapeIndexB = collidables[childColIndexB].m_shapeIndex;
1150 float4 c0local = convexPolyhedronA.m_localCenter;
1151 float4 c0 = transform(&c0local, &posA, &ornA);
1152 float4 c1local = convexShapes[shapeIndexB].m_localCenter;
1153 float4 c1 = transform(&c1local,&posB,&ornB);
1154 const float4 DeltaC2 = c0 - c1;
1158 bool sepEE = findSeparatingAxisEdgeEdgeLocalA( &convexPolyhedronA, &convexShapes[shapeIndexB],
1162 verticesA,uniqueEdgesA,facesA,indicesA,
1163 vertices,uniqueEdges,faces,indices,
1168 hasSeparatingAxis = 0;
1171 hasSeparatingAxis = 1;
1176 if (hasSeparatingAxis)
1180 concaveSeparatingNormalsOut[pairIdx]=sepAxis;
1181 concaveHasSeparatingNormals[i]=1;
1183 float minDist = -1e30f;
1184 float maxDist = 0.02f;
1187 findClippingFaces(sepAxis,
1189 &convexShapes[shapeIndexB],
1203 clippingFacesOut, pairIdx);
1208 //mark this pair as in-active
1209 concavePairs[pairIdx].w = -1;
1214 //mark this pair as in-active
1215 concavePairs[pairIdx].w = -1;
1218 concavePairs[i].z = -1;//for the next stage, z is used to determine existing contact points