1 //keep this enum in sync with the CPU version (in btCollidable.h)
2 //written by Erwin Coumans
4 #define SHAPE_CONVEX_HULL 3
5 #define SHAPE_CONCAVE_TRIMESH 5
6 #define TRIANGLE_NUM_CONVEX_FACES 5
7 #define SHAPE_COMPOUND_OF_CONVEX_HULLS 6
10 typedef unsigned int u32;
12 #define MAX_NUM_PARTS_IN_BITS 10
14 ///btQuantizedBvhNode is a compressed aabb node, 16 bytes.
15 ///Node can be used for leafnode or internal node. Leafnodes can point to 32-bit triangle index (non-negative range).
19 unsigned short int m_quantizedAabbMin[3];
20 unsigned short int m_quantizedAabbMax[3];
22 int m_escapeIndexOrTriangleIndex;
29 float4 m_quantization;
37 int getTriangleIndex(const btQuantizedBvhNode* rootNode)
40 unsigned int y = (~(x&0))<<(31-MAX_NUM_PARTS_IN_BITS);
41 // Get only the lower bits where the triangle index is stored
42 return (rootNode->m_escapeIndexOrTriangleIndex&~(y));
45 int isLeaf(const btQuantizedBvhNode* rootNode)
47 //skipindex is negative (internal node), triangleindex >=0 (leafnode)
48 return (rootNode->m_escapeIndexOrTriangleIndex >= 0)? 1 : 0;
51 int getEscapeIndex(const btQuantizedBvhNode* rootNode)
53 return -rootNode->m_escapeIndexOrTriangleIndex;
59 unsigned short int m_quantizedAabbMin[3];
60 unsigned short int m_quantizedAabbMax[3];
61 //4 bytes, points to the root of the subtree
68 ///keep this in sync with btCollidable.h
80 float4 m_childPosition;
81 float4 m_childOrientation;
98 float m_restituitionCoeff;
99 float m_frictionCoeff;
119 int testQuantizedAabbAgainstQuantizedAabb(
120 const unsigned short int* aabbMin1,
121 const unsigned short int* aabbMax1,
122 const unsigned short int* aabbMin2,
123 const unsigned short int* aabbMax2)
126 if (aabbMin1[0] > aabbMax2[0])
128 if (aabbMax1[0] < aabbMin2[0])
130 if (aabbMin1[1] > aabbMax2[1])
132 if (aabbMax1[1] < aabbMin2[1])
134 if (aabbMin1[2] > aabbMax2[2])
136 if (aabbMax1[2] < aabbMin2[2])
139 //overlap = ((aabbMin1[0] > aabbMax2[0]) || (aabbMax1[0] < aabbMin2[0])) ? 0 : overlap;
140 //overlap = ((aabbMin1[2] > aabbMax2[2]) || (aabbMax1[2] < aabbMin2[2])) ? 0 : overlap;
141 //overlap = ((aabbMin1[1] > aabbMax2[1]) || (aabbMax1[1] < aabbMin2[1])) ? 0 : overlap;
146 void quantizeWithClamp(unsigned short* out, float4 point2,int isMax, float4 bvhAabbMin, float4 bvhAabbMax, float4 bvhQuantization)
148 float4 clampedPoint = max(point2,bvhAabbMin);
149 clampedPoint = min (clampedPoint, bvhAabbMax);
151 float4 v = (clampedPoint - bvhAabbMin) * bvhQuantization;
154 out[0] = (unsigned short) (((unsigned short)(v.x+1.f) | 1));
155 out[1] = (unsigned short) (((unsigned short)(v.y+1.f) | 1));
156 out[2] = (unsigned short) (((unsigned short)(v.z+1.f) | 1));
159 out[0] = (unsigned short) (((unsigned short)(v.x) & 0xfffe));
160 out[1] = (unsigned short) (((unsigned short)(v.y) & 0xfffe));
161 out[2] = (unsigned short) (((unsigned short)(v.z) & 0xfffe));
168 __kernel void bvhTraversalKernel( __global const int4* pairs,
169 __global const BodyData* rigidBodies,
170 __global const btCollidableGpu* collidables,
171 __global btAabbCL* aabbs,
172 __global int4* concavePairsOut,
173 __global volatile int* numConcavePairsOut,
174 __global const btBvhSubtreeInfo* subtreeHeadersRoot,
175 __global const btQuantizedBvhNode* quantizedNodesRoot,
176 __global const b3BvhInfo* bvhInfos,
178 int maxNumConcavePairsCapacity)
180 int id = get_global_id(0);
184 int bodyIndexA = pairs[id].x;
185 int bodyIndexB = pairs[id].y;
186 int collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;
187 int collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx;
189 //once the broadphase avoids static-static pairs, we can remove this test
190 if ((rigidBodies[bodyIndexA].m_invMass==0) &&(rigidBodies[bodyIndexB].m_invMass==0))
195 if (collidables[collidableIndexA].m_shapeType!=SHAPE_CONCAVE_TRIMESH)
198 int shapeTypeB = collidables[collidableIndexB].m_shapeType;
200 if (shapeTypeB!=SHAPE_CONVEX_HULL &&
201 shapeTypeB!=SHAPE_SPHERE &&
202 shapeTypeB!=SHAPE_COMPOUND_OF_CONVEX_HULLS
206 b3BvhInfo bvhInfo = bvhInfos[collidables[collidableIndexA].m_numChildShapes];
208 float4 bvhAabbMin = bvhInfo.m_aabbMin;
209 float4 bvhAabbMax = bvhInfo.m_aabbMax;
210 float4 bvhQuantization = bvhInfo.m_quantization;
211 int numSubtreeHeaders = bvhInfo.m_numSubTrees;
212 __global const btBvhSubtreeInfo* subtreeHeaders = &subtreeHeadersRoot[bvhInfo.m_subTreeOffset];
213 __global const btQuantizedBvhNode* quantizedNodes = &quantizedNodesRoot[bvhInfo.m_nodeOffset];
216 unsigned short int quantizedQueryAabbMin[3];
217 unsigned short int quantizedQueryAabbMax[3];
218 quantizeWithClamp(quantizedQueryAabbMin,aabbs[bodyIndexB].m_min,false,bvhAabbMin, bvhAabbMax,bvhQuantization);
219 quantizeWithClamp(quantizedQueryAabbMax,aabbs[bodyIndexB].m_max,true ,bvhAabbMin, bvhAabbMax,bvhQuantization);
221 for (int i=0;i<numSubtreeHeaders;i++)
223 btBvhSubtreeInfo subtree = subtreeHeaders[i];
225 int overlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,subtree.m_quantizedAabbMin,subtree.m_quantizedAabbMax);
228 int startNodeIndex = subtree.m_rootNodeIndex;
229 int endNodeIndex = subtree.m_rootNodeIndex+subtree.m_subtreeSize;
230 int curIndex = startNodeIndex;
234 while (curIndex < endNodeIndex)
236 btQuantizedBvhNode rootNode = quantizedNodes[curIndex];
237 aabbOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,rootNode.m_quantizedAabbMin,rootNode.m_quantizedAabbMax);
238 isLeafNode = isLeaf(&rootNode);
243 int triangleIndex = getTriangleIndex(&rootNode);
244 if (shapeTypeB==SHAPE_COMPOUND_OF_CONVEX_HULLS)
246 int numChildrenB = collidables[collidableIndexB].m_numChildShapes;
247 int pairIdx = atomic_add(numConcavePairsOut,numChildrenB);
248 for (int b=0;b<numChildrenB;b++)
250 if ((pairIdx+b)<maxNumConcavePairsCapacity)
252 int childShapeIndexB = collidables[collidableIndexB].m_shapeIndex+b;
253 int4 newPair = (int4)(bodyIndexA,bodyIndexB,triangleIndex,childShapeIndexB);
254 concavePairsOut[pairIdx+b] = newPair;
259 int pairIdx = atomic_inc(numConcavePairsOut);
260 if (pairIdx<maxNumConcavePairsCapacity)
262 int4 newPair = (int4)(bodyIndexA,bodyIndexB,triangleIndex,0);
263 concavePairsOut[pairIdx] = newPair;
275 escapeIndex = getEscapeIndex(&rootNode);
276 curIndex += escapeIndex;