more work towards GPU bvh traversal

This commit is contained in:
erwin coumans
2013-03-19 23:11:19 -07:00
parent 8bfbaf3ed1
commit 085d705645
4 changed files with 354 additions and 62 deletions

View File

@@ -8,6 +8,76 @@
typedef unsigned int u32;
#define MAX_NUM_PARTS_IN_BITS 10
///btQuantizedBvhNode is a compressed aabb node, 16 bytes.
///Node can be used for leafnode or internal node. Leafnodes can point to 32-bit triangle index (non-negative range).
typedef struct
{
//12 bytes
unsigned short int m_quantizedAabbMin[3];
unsigned short int m_quantizedAabbMax[3];
//4 bytes
int m_escapeIndexOrTriangleIndex;
} btQuantizedBvhNode;
/*
bool isLeafNode() const
{
//skipindex is negative (internal node), triangleindex >=0 (leafnode)
return (m_escapeIndexOrTriangleIndex >= 0);
}
int getEscapeIndex() const
{
btAssert(!isLeafNode());
return -m_escapeIndexOrTriangleIndex;
}
int getTriangleIndex() const
{
btAssert(isLeafNode());
unsigned int x=0;
unsigned int y = (~(x&0))<<(31-MAX_NUM_PARTS_IN_BITS);
// Get only the lower bits where the triangle index is stored
return (m_escapeIndexOrTriangleIndex&~(y));
}
int getPartId() const
{
btAssert(isLeafNode());
// Get only the highest bits where the part index is stored
return (m_escapeIndexOrTriangleIndex>>(31-MAX_NUM_PARTS_IN_BITS));
}
*/
int getTriangleIndex(__global const btQuantizedBvhNode* rootNode)
{
unsigned int x=0;
unsigned int y = (~(x&0))<<(31-MAX_NUM_PARTS_IN_BITS);
// Get only the lower bits where the triangle index is stored
return (rootNode->m_escapeIndexOrTriangleIndex&~(y));
}
bool isLeaf(__global const btQuantizedBvhNode* rootNode)
{
//skipindex is negative (internal node), triangleindex >=0 (leafnode)
return (rootNode->m_escapeIndexOrTriangleIndex >= 0);
}
int getEscapeIndex(__global const btQuantizedBvhNode* rootNode)
{
return -rootNode->m_escapeIndexOrTriangleIndex;
}
typedef struct
{
//12 bytes
unsigned short int m_quantizedAabbMin[3];
unsigned short int m_quantizedAabbMax[3];
//4 bytes, points to the root of the subtree
int m_rootNodeIndex;
//4 bytes
int m_subtreeSize;
int m_padding[3];
} btBvhSubtreeInfo;
///keep this in sync with btCollidable.h
typedef struct
{
@@ -58,16 +128,53 @@ typedef struct
};
} btAabbCL;
bool testQuantizedAabbAgainstQuantizedAabb(__private const unsigned short int* aabbMin1,__private const unsigned short int* aabbMax1,__global const unsigned short int* aabbMin2,__global const unsigned short int* aabbMax2)
{
bool overlap = true;
overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap;
overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap;
overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap;
return overlap;
}
void quantizeWithClamp(unsigned short* out, float4 point2,int isMax, float4 bvhAabbMin, float4 bvhAabbMax, float4 bvhQuantization)
{
float4 clampedPoint = max(point2,bvhAabbMin);
clampedPoint = min (clampedPoint, bvhAabbMax);
float4 v = (clampedPoint - bvhAabbMin) * bvhQuantization;
if (isMax)
{
out[0] = (unsigned short) (((unsigned short)(v.x+1.f) | 1));
out[1] = (unsigned short) (((unsigned short)(v.y+1.f) | 1));
out[2] = (unsigned short) (((unsigned short)(v.z+1.f) | 1));
} else
{
out[0] = (unsigned short) (((unsigned short)(v.x) & 0xfffe));
out[1] = (unsigned short) (((unsigned short)(v.y) & 0xfffe));
out[2] = (unsigned short) (((unsigned short)(v.z) & 0xfffe));
}
}
// work-in-progress
__kernel void bvhTraversalKernel( __global const int2* pairs,
__global const BodyData* rigidBodies,
__global const btCollidableGpu* collidables,
__global btAabbCL* aabbs,
__global int4* concavePairsOut,
__global volatile int* numConcavePairsOut,
int numPairs,
int maxNumConcavePairsCapacity
)
__global const BodyData* rigidBodies,
__global const btCollidableGpu* collidables,
__global btAabbCL* aabbs,
__global int4* concavePairsOut,
__global volatile int* numConcavePairsOut,
__global const btBvhSubtreeInfo* subtreeHeaders,
__global const btQuantizedBvhNode* quantizedNodes,
float4 bvhAabbMin,
float4 bvhAabbMax,
float4 bvhQuantization,
int numSubtreeHeaders,
int numPairs,
int maxNumConcavePairsCapacity)
{
int i = get_global_id(0);
@@ -94,16 +201,62 @@ __kernel void bvhTraversalKernel( __global const int2* pairs,
if ((collidables[collidableIndexA].m_shapeType==SHAPE_CONCAVE_TRIMESH))// && (collidables[collidableIndexB].m_shapeType==SHAPE_CONVEX_HULL))
{
int pairIdx = atomic_inc(numConcavePairsOut);
if (pairIdx<maxNumConcavePairsCapacity)
unsigned short int quantizedQueryAabbMin[3];
unsigned short int quantizedQueryAabbMax[3];
quantizeWithClamp(quantizedQueryAabbMin,aabbs[bodyIndexB].m_min,false,bvhAabbMin, bvhAabbMax,bvhQuantization);
quantizeWithClamp(quantizedQueryAabbMax,aabbs[bodyIndexB].m_max,true ,bvhAabbMin, bvhAabbMax,bvhQuantization);
int i;
for (i=0;i<numSubtreeHeaders;i++)
{
//int4 newPair;
concavePairsOut[pairIdx].x = bodyIndexA;
concavePairsOut[pairIdx].y = bodyIndexB;
concavePairsOut[pairIdx].z = 5;
concavePairsOut[pairIdx].w = 3;
const __global btBvhSubtreeInfo* subtree = &subtreeHeaders[i];
//PCK: unsigned instead of bool
unsigned overlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,subtree->m_quantizedAabbMin,subtree->m_quantizedAabbMax);
if (overlap != 0)
{
int startNodeIndex = subtree->m_rootNodeIndex;
int endNodeIndex = subtree->m_rootNodeIndex+subtree->m_subtreeSize;
int curIndex = startNodeIndex;
int subTreeSize = endNodeIndex - startNodeIndex;
__global const btQuantizedBvhNode* rootNode = &quantizedNodes[startNodeIndex];
int escapeIndex;
bool isLeafNode;
unsigned aabbOverlap;
while (curIndex < endNodeIndex)
{
aabbOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,rootNode->m_quantizedAabbMin,rootNode->m_quantizedAabbMax);
isLeafNode = isLeaf(rootNode);
if (isLeafNode && aabbOverlap)
{
//do your thing! nodeCallback->processNode(rootNode->getPartId(),rootNode->getTriangleIndex());
int triangleIndex = getTriangleIndex(rootNode);
int pairIdx = atomic_inc(numConcavePairsOut);
if (pairIdx<maxNumConcavePairsCapacity)
{
//int4 newPair;
concavePairsOut[pairIdx].x = bodyIndexA;
concavePairsOut[pairIdx].y = bodyIndexB;
concavePairsOut[pairIdx].z = triangleIndex;
concavePairsOut[pairIdx].w = 3;
}
}
if ((aabbOverlap != 0) || isLeafNode)
{
rootNode++;
curIndex++;
} else
{
escapeIndex = getEscapeIndex(rootNode);
rootNode += escapeIndex;
curIndex += escapeIndex;
}
}
}
}
}//SHAPE_CONCAVE_TRIMESH
}//i<numpairs
}