add support for BVH acceleration for concave trianglemesh collision against convex hulls

bugfix/improvement in batching
This commit is contained in:
erwin coumans
2013-03-20 23:37:34 -07:00
parent 9a693fb850
commit b4f9416cdf
20 changed files with 760 additions and 690 deletions

View File

@@ -109,7 +109,7 @@ struct InternalDataRenderer : public GLInstanceRendererInternalData
m_cameraTargetPosition(btVector3(15,2,-24)), m_cameraTargetPosition(btVector3(15,2,-24)),
m_cameraDistance(150), m_cameraDistance(150),
m_cameraUp(0,1,0), m_cameraUp(0,1,0),
m_azi(135.f), m_azi(100.f),//135.f),
m_ele(25.f), m_ele(25.f),
m_mouseInitialized(false) m_mouseInitialized(false)
{ {

12
data/plane100.obj Normal file
View File

@@ -0,0 +1,12 @@
# Blender v2.66 (sub 1) OBJ File: ''
# www.blender.org
mtllib plane.mtl
o Plane
v 100.000000 0.000000 -100.000000
v 100.000000 0.000000 100.000000
v -100.000000 0.000000 100.000000
v -100.000000 0.000000 -100.000000
usemtl Material
s off
f 1 2 3
f 1 3 4

View File

@@ -34,13 +34,13 @@ public:
:useOpenCL(true), :useOpenCL(true),
preferredOpenCLPlatformIndex(-1), preferredOpenCLPlatformIndex(-1),
preferredOpenCLDeviceIndex(-1), preferredOpenCLDeviceIndex(-1),
arraySizeX(5), arraySizeX(30),
arraySizeY(5 ), arraySizeY(10 ),
arraySizeZ(5), arraySizeZ(30),
m_useConcaveMesh(false), m_useConcaveMesh(false),
gapX(4.3), gapX(6.3),
gapY(2.0), gapY(12.0),
gapZ(4.3), gapZ(6.3),
m_instancingRenderer(0), m_instancingRenderer(0),
m_window(0) m_window(0)
{ {

View File

@@ -617,7 +617,7 @@ int main(int argc, char* argv[])
if (!gPause) if (!gPause)
{ {
BT_PROFILE("simulate"); BT_PROFILE("clientMoveAndDisplay");
demo->clientMoveAndDisplay(); demo->clientMoveAndDisplay();
} }

View File

@@ -166,9 +166,9 @@ GraphicsShape* createGraphicsShapeFromWavefrontObj(objLoader* obj)
void ConcaveScene::setupScene(const ConstructionInfo& ci) void ConcaveScene::setupScene(const ConstructionInfo& ci)
{ {
objLoader* objData = new objLoader(); objLoader* objData = new objLoader();
//char* fileName = "data/plane.obj"; //char* fileName = "data/plane100.obj";
char* fileName = "data/teddy.obj";//"plane.obj"; //char* fileName = "data/teddy.obj";//"plane.obj";
//char* fileName = "data/sponza_closed.obj";//"plane.obj"; char* fileName = "data/sponza_closed.obj";//"plane.obj";
FILE* f = 0; FILE* f = 0;
@@ -200,16 +200,16 @@ void ConcaveScene::setupScene(const ConstructionInfo& ci)
{ {
GraphicsShape* shape = createGraphicsShapeFromWavefrontObj(objData); GraphicsShape* shape = createGraphicsShapeFromWavefrontObj(objData);
btVector4 scaling(1,1,1,1); btVector4 scaling(4,4,4,1);
btAlignedObjectArray<btVector3> verts; btAlignedObjectArray<btVector3> verts;
for (int i=0;i<shape->m_numvertices;i++) for (int i=0;i<shape->m_numvertices;i++)
{ {
btVector3 vtx = (btVector3&)shape->m_vertices->at(i).xyzw; btVector3 vtx = (btVector3&)shape->m_vertices->at(i).xyzw;
verts.push_back(vtx); verts.push_back(vtx*scaling);
} }
int colIndex = m_data->m_np->registerConcaveMesh(&verts,shape->m_indices,scaling); int colIndex = m_data->m_np->registerConcaveMesh(&verts,shape->m_indices,btVector3(1,1,1));
{ {
int strideInBytes = 9*sizeof(float); int strideInBytes = 9*sizeof(float);
@@ -222,7 +222,7 @@ void ConcaveScene::setupScene(const ConstructionInfo& ci)
int shapeId = ci.m_instancingRenderer->registerShape(&shape->m_vertices->at(0).xyzw[0], shape->m_numvertices, &shape->m_indices->at(0), shape->m_numIndices); int shapeId = ci.m_instancingRenderer->registerShape(&shape->m_vertices->at(0).xyzw[0], shape->m_numvertices, &shape->m_indices->at(0), shape->m_numIndices);
btQuaternion orn(0,0,0,1); btQuaternion orn(0,0,0,1);
btVector4 color(0,1,0,1.f);//0.5); btVector4 color(0,0,1,1.f);//0.5);//1.f
{ {
@@ -262,7 +262,8 @@ void ConcaveScene::setupScene(const ConstructionInfo& ci)
{ {
float mass = 1; float mass = 1;
btVector3 position(-2*ci.gapX+i*ci.gapX,25+j*ci.gapY,-2*ci.gapZ+k*ci.gapZ); //btVector3 position(-2*ci.gapX+i*ci.gapX,25+j*ci.gapY,-2*ci.gapZ+k*ci.gapZ);
btVector3 position(-(ci.arraySizeX/2)*ci.gapX+i*ci.gapX,5+j*ci.gapY,-(ci.arraySizeZ/2)*ci.gapZ+k*ci.gapZ);
btQuaternion orn(1,0,0,0); btQuaternion orn(1,0,0,0);
btVector4 color(0,1,0,1); btVector4 color(0,1,0,1);
@@ -278,6 +279,6 @@ void ConcaveScene::setupScene(const ConstructionInfo& ci)
float camPos[4]={0,0,0,0};//65.5,4.5,65.5,0}; float camPos[4]={0,0,0,0};//65.5,4.5,65.5,0};
//float camPos[4]={1,12.5,1.5,0}; //float camPos[4]={1,12.5,1.5,0};
m_instancingRenderer->setCameraTargetPosition(camPos); m_instancingRenderer->setCameraTargetPosition(camPos);
m_instancingRenderer->setCameraDistance(50); m_instancingRenderer->setCameraDistance(120);
} }

View File

@@ -157,6 +157,7 @@ void GpuRigidBodyDemo::clientMoveAndDisplay()
btVector4* positions = 0; btVector4* positions = 0;
if (animate && numObjects) if (animate && numObjects)
{ {
BT_PROFILE("gl2cl");
GLuint vbo = m_instancingRenderer->getInternalData()->m_vbo; GLuint vbo = m_instancingRenderer->getInternalData()->m_vbo;
int arraySizeInBytes = numObjects * (3)*sizeof(btVector4); int arraySizeInBytes = numObjects * (3)*sizeof(btVector4);
glBindBuffer(GL_ARRAY_BUFFER, vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo);
@@ -172,10 +173,14 @@ void GpuRigidBodyDemo::clientMoveAndDisplay()
} }
} }
{
BT_PROFILE("stepSimulation");
m_data->m_rigidBodyPipeline->stepSimulation(1./60.f); m_data->m_rigidBodyPipeline->stepSimulation(1./60.f);
}
if (numObjects) if (numObjects)
{ {
BT_PROFILE("cl2gl_convert");
int ciErrNum = 0; int ciErrNum = 0;
cl_mem bodies = m_data->m_rigidBodyPipeline->getBodyBuffer(); cl_mem bodies = m_data->m_rigidBodyPipeline->getBodyBuffer();
btLauncherCL launch(m_clData->m_clQueue,m_data->m_copyTransformsToVBOKernel); btLauncherCL launch(m_clData->m_clQueue,m_data->m_copyTransformsToVBOKernel);
@@ -188,6 +193,7 @@ void GpuRigidBodyDemo::clientMoveAndDisplay()
if (animate && numObjects) if (animate && numObjects)
{ {
BT_PROFILE("cl2gl_upload");
GLint err = glGetError(); GLint err = glGetError();
assert(err==GL_NO_ERROR); assert(err==GL_NO_ERROR);
m_data->m_instancePosOrnColor->copyToHostPointer(positions,3*numObjects,0); m_data->m_instancePosOrnColor->copyToHostPointer(positions,3*numObjects,0);

View File

@@ -821,6 +821,7 @@ void Solver::sortContacts( const btOpenCLArray<btRigidBodyCL>* bodyBuf,
void Solver::batchContacts( btOpenCLArray<btContact4>* contacts, int nContacts, btOpenCLArray<unsigned int>* nNative, btOpenCLArray<unsigned int>* offsetsNative, int staticIdx ) void Solver::batchContacts( btOpenCLArray<btContact4>* contacts, int nContacts, btOpenCLArray<unsigned int>* nNative, btOpenCLArray<unsigned int>* offsetsNative, int staticIdx )
{ {
int numWorkItems = 64*N_SPLIT*N_SPLIT;
{ {
BT_PROFILE("batch generation"); BT_PROFILE("batch generation");
@@ -829,7 +830,7 @@ void Solver::batchContacts( btOpenCLArray<btContact4>* contacts, int nContacts,
cdata.y = 0; cdata.y = 0;
cdata.z = staticIdx; cdata.z = staticIdx;
int numWorkItems = 64*N_SPLIT*N_SPLIT;
#ifdef BATCH_DEBUG #ifdef BATCH_DEBUG
SolverDebugInfo* debugInfo = new SolverDebugInfo[numWorkItems]; SolverDebugInfo* debugInfo = new SolverDebugInfo[numWorkItems];
adl::btOpenCLArray<SolverDebugInfo> gpuDebugInfo(data->m_device,numWorkItems); adl::btOpenCLArray<SolverDebugInfo> gpuDebugInfo(data->m_device,numWorkItems);
@@ -838,11 +839,13 @@ void Solver::batchContacts( btOpenCLArray<btContact4>* contacts, int nContacts,
#endif #endif
btBufferInfoCL bInfo[] = { btBufferInfoCL bInfo[] = {
btBufferInfoCL( contacts->getBufferCL() ), btBufferInfoCL( contacts->getBufferCL() ),
btBufferInfoCL( m_contactBuffer->getBufferCL() ), btBufferInfoCL( m_contactBuffer->getBufferCL() ),
btBufferInfoCL( nNative->getBufferCL() ), btBufferInfoCL( nNative->getBufferCL() ),
btBufferInfoCL( offsetsNative->getBufferCL() ) btBufferInfoCL( offsetsNative->getBufferCL() ),
#ifdef BATCH_DEBUG #ifdef BATCH_DEBUG
, btBufferInfoCL(&gpuDebugInfo) , btBufferInfoCL(&gpuDebugInfo)
#endif #endif
@@ -901,5 +904,6 @@ void Solver::batchContacts( btOpenCLArray<btContact4>* contacts, int nContacts,
//clFinish(m_queue);//needed? //clFinish(m_queue);//needed?
} }

View File

@@ -15,6 +15,8 @@ struct btConfig
int m_maxCompoundChildShapes; int m_maxCompoundChildShapes;
int m_maxTriConvexPairCapacity;
btConfig() btConfig()
:m_maxConvexBodies(128*1024), :m_maxConvexBodies(128*1024),
m_maxConvexShapes(8192), m_maxConvexShapes(8192),
@@ -23,7 +25,8 @@ struct btConfig
m_maxConvexVertices(8192), m_maxConvexVertices(8192),
m_maxConvexIndices(8192), m_maxConvexIndices(8192),
m_maxConvexUniqueEdges(8192), m_maxConvexUniqueEdges(8192),
m_maxCompoundChildShapes(8192)//?? m_maxCompoundChildShapes(8192),
m_maxTriConvexPairCapacity(256*1024)
{ {
m_maxBroadphasePairs = 16*m_maxConvexBodies; m_maxBroadphasePairs = 16*m_maxConvexBodies;
} }

View File

@@ -202,7 +202,7 @@ btGpuBatchingPgsSolver::~btGpuBatchingPgsSolver()
struct btConstraintCfg struct btConstraintCfg
{ {
btConstraintCfg( float dt = 0.f ): m_positionDrift( 0.005f ), m_positionConstraintCoeff( 0.2f ), m_dt(dt), m_staticIdx(-1) {} btConstraintCfg( float dt = 0.f ): m_positionDrift( 0.005f ), m_positionConstraintCoeff( 0.2f ), m_dt(dt), m_staticIdx(0) {}
float m_positionDrift; float m_positionDrift;
float m_positionConstraintCoeff; float m_positionConstraintCoeff;
@@ -403,8 +403,8 @@ void btGpuBatchingPgsSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem
float dt=1./60.; float dt=1./60.;
btConstraintCfg csCfg( dt ); btConstraintCfg csCfg( dt );
csCfg.m_enableParallelSolve = true; csCfg.m_enableParallelSolve = true;
csCfg.m_averageExtent = 0.2f;//@TODO m_averageObjExtent; csCfg.m_averageExtent = .2f;//@TODO m_averageObjExtent;
csCfg.m_staticIdx = -1;//m_static0Index;//m_planeBodyIndex; csCfg.m_staticIdx = 0;//m_static0Index;//m_planeBodyIndex;
btOpenCLArray<btContact4>* contactsIn = m_data->m_pBufContactOutGPU; btOpenCLArray<btContact4>* contactsIn = m_data->m_pBufContactOutGPU;
btOpenCLArray<btRigidBodyCL>* bodyBuf = m_data->m_bodyBufferGPU; btOpenCLArray<btRigidBodyCL>* bodyBuf = m_data->m_bodyBufferGPU;
@@ -574,8 +574,8 @@ void btGpuBatchingPgsSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem
{ {
if (gpuBatchContacts) if (gpuBatchContacts)
{ {
maxNumBatches=250;//for now
BT_PROFILE("gpu batchContacts"); BT_PROFILE("gpu batchContacts");
maxNumBatches = 50;
m_data->m_solverGPU->batchContacts( (btOpenCLArray<btContact4>*)contactNative, nContacts, m_data->m_solverGPU->m_numConstraints, m_data->m_solverGPU->m_offsets, csCfg.m_staticIdx ); m_data->m_solverGPU->batchContacts( (btOpenCLArray<btContact4>*)contactNative, nContacts, m_data->m_solverGPU->m_numConstraints, m_data->m_solverGPU->m_offsets, csCfg.m_staticIdx );
} else } else
{ {
@@ -612,7 +612,7 @@ void btGpuBatchingPgsSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem
//printf("cpu batch\n"); //printf("cpu batch\n");
int simdWidth = -1; int simdWidth = -1;
int numBatches = sortConstraintByBatch( &cpuContacts[0]+offset, n, simdWidth,csCfg.m_staticIdx ); // on GPU int numBatches = sortConstraintByBatch( &cpuContacts[0]+offset, n, simdWidth,csCfg.m_staticIdx ,numBodies); // on GPU
maxNumBatches = btMax(numBatches,maxNumBatches); maxNumBatches = btMax(numBatches,maxNumBatches);
clFinish(m_data->m_queue); clFinish(m_data->m_queue);
@@ -624,12 +624,13 @@ void btGpuBatchingPgsSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem
BT_PROFILE("m_contactBuffer->copyFromHost"); BT_PROFILE("m_contactBuffer->copyFromHost");
m_data->m_solverGPU->m_contactBuffer->copyFromHost((btAlignedObjectArray<btContact4>&)cpuContacts); m_data->m_solverGPU->m_contactBuffer->copyFromHost((btAlignedObjectArray<btContact4>&)cpuContacts);
} }
}
}
//printf("maxNumBatches = %d\n", maxNumBatches); //printf("maxNumBatches = %d\n", maxNumBatches);
}
}
if (nContacts) if (nContacts)
{ {
@@ -704,8 +705,14 @@ btAlignedObjectArray<btSortData> sortData;
btAlignedObjectArray<btContact4> old; btAlignedObjectArray<btContact4> old;
inline int btGpuBatchingPgsSolver::sortConstraintByBatch( btContact4* cs, int n, int simdWidth , int staticIdx) inline int btGpuBatchingPgsSolver::sortConstraintByBatch( btContact4* cs, int n, int simdWidth , int staticIdx, int numBodies)
{ {
btAlignedObjectArray<int> bodyUsed;
bodyUsed.resize(numBodies);
for (int q=0;q<numBodies;q++)
bodyUsed[q]=0;
BT_PROFILE("sortConstraintByBatch");
int numIter = 0; int numIter = 0;
sortData.resize(n); sortData.resize(n);
@@ -747,12 +754,7 @@ inline int btGpuBatchingPgsSolver::sortConstraintByBatch( btContact4* cs, int n,
int bodyAS = cs[idx].m_bodyAPtrAndSignBit; int bodyAS = cs[idx].m_bodyAPtrAndSignBit;
int bodyBS = cs[idx].m_bodyBPtrAndSignBit; int bodyBS = cs[idx].m_bodyBPtrAndSignBit;
/*if (bodyAS<0)
printf("A static\n");
if (bodyBS<0)
printf("B static\n");
*/
int bodyA = abs(bodyAS); int bodyA = abs(bodyAS);
int bodyB = abs(bodyBS); int bodyB = abs(bodyBS);
@@ -763,14 +765,20 @@ inline int btGpuBatchingPgsSolver::sortConstraintByBatch( btContact4* cs, int n,
unsigned int aUnavailable = flg[ aIdx/32 ] & (1<<(aIdx&31)); unsigned int aUnavailable = flg[ aIdx/32 ] & (1<<(aIdx&31));
unsigned int bUnavailable = flg[ bIdx/32 ] & (1<<(bIdx&31)); unsigned int bUnavailable = flg[ bIdx/32 ] & (1<<(bIdx&31));
bool aIsStatic = (bodyAS<0) || bodyAS==staticIdx;
bool bIsStatic = (bodyBS<0) || bodyBS==staticIdx;
//use inv_mass! //use inv_mass!
aUnavailable = (bodyAS>=0)&&bodyAS!=staticIdx? aUnavailable:0;// aUnavailable = !aIsStatic? aUnavailable:0;//
bUnavailable = (bodyBS>=0)&&bodyBS!=staticIdx? bUnavailable:0; bUnavailable = !bIsStatic? bUnavailable:0;
if( aUnavailable==0 && bUnavailable==0 ) // ok if( aUnavailable==0 && bUnavailable==0 ) // ok
{ {
if (!!aIsStatic)
flg[ aIdx/32 ] |= (1<<(aIdx&31)); flg[ aIdx/32 ] |= (1<<(aIdx&31));
if (!bIsStatic)
flg[ bIdx/32 ] |= (1<<(bIdx&31)); flg[ bIdx/32 ] |= (1<<(bIdx&31));
cs[idx].getBatchIdx() = batchIdx; cs[idx].getBatchIdx() = batchIdx;
sortData[idx].m_key = batchIdx; sortData[idx].m_key = batchIdx;
sortData[idx].m_value = idx; sortData[idx].m_value = idx;

View File

@@ -15,7 +15,7 @@ protected:
struct btGpuBatchingPgsSolverInternalData* m_data; struct btGpuBatchingPgsSolverInternalData* m_data;
void batchContacts( btOpenCLArray<btContact4>* contacts, int nContacts, btOpenCLArray<unsigned int>* n, btOpenCLArray<unsigned int>* offsets, int staticIdx ); void batchContacts( btOpenCLArray<btContact4>* contacts, int nContacts, btOpenCLArray<unsigned int>* n, btOpenCLArray<unsigned int>* offsets, int staticIdx );
inline int sortConstraintByBatch( btContact4* cs, int n, int simdWidth , int staticIdx); inline int sortConstraintByBatch( btContact4* cs, int n, int simdWidth , int staticIdx, int numBodies);
void solveContactConstraint( const btOpenCLArray<btRigidBodyCL>* bodyBuf, const btOpenCLArray<btInertiaCL>* shapeBuf, void solveContactConstraint( const btOpenCLArray<btRigidBodyCL>* bodyBuf, const btOpenCLArray<btInertiaCL>* shapeBuf,
btOpenCLArray<btGpuConstraint4>* constraint, void* additionalData, int n ,int maxNumBatches, int numIterations); btOpenCLArray<btGpuConstraint4>* constraint, void* additionalData, int n ,int maxNumBatches, int numIterations);

View File

@@ -63,6 +63,10 @@ struct btGpuNarrowPhaseInternalData
btAlignedObjectArray<btSapAabb>* m_localShapeAABBCPU; btAlignedObjectArray<btSapAabb>* m_localShapeAABBCPU;
btAlignedObjectArray<class btOptimizedBvh*> m_bvhData; btAlignedObjectArray<class btOptimizedBvh*> m_bvhData;
btOpenCLArray<btQuantizedBvhNode>* m_treeNodesGPU;
btOpenCLArray<btBvhSubtreeInfo>* m_subTreesGPU;
btConfig m_config; btConfig m_config;
}; };
@@ -137,6 +141,10 @@ m_queue(queue)
m_data->m_numAcceleratedShapes = 0; m_data->m_numAcceleratedShapes = 0;
m_data->m_numAcceleratedRigidBodies = 0; m_data->m_numAcceleratedRigidBodies = 0;
m_data->m_treeNodesGPU = 0;
m_data->m_subTreesGPU = 0;
//m_data->m_contactCGPU = new btOpenCLArray<Constraint4>(ctx,queue,config.m_maxBroadphasePairs,false); //m_data->m_contactCGPU = new btOpenCLArray<Constraint4>(ctx,queue,config.m_maxBroadphasePairs,false);
//m_data->m_frictionCGPU = new btOpenCLArray<adl::Solver<adl::TYPE_CL>::allocateFrictionConstraint( m_data->m_deviceCL, config.m_maxBroadphasePairs); //m_data->m_frictionCGPU = new btOpenCLArray<adl::Solver<adl::TYPE_CL>::allocateFrictionConstraint( m_data->m_deviceCL, config.m_maxBroadphasePairs);
@@ -170,6 +178,8 @@ btGpuNarrowPhase::~btGpuNarrowPhase()
delete m_data->m_worldVertsA1GPU; delete m_data->m_worldVertsA1GPU;
delete m_data->m_worldVertsB2GPU; delete m_data->m_worldVertsB2GPU;
delete m_data->m_treeNodesGPU;
delete m_data->m_subTreesGPU;
delete m_data->m_convexData; delete m_data->m_convexData;
delete m_data; delete m_data;
@@ -328,6 +338,15 @@ int btGpuNarrowPhase::registerConvexHullShape(btConvexUtility* utilPtr)
int btGpuNarrowPhase::registerConcaveMesh(btAlignedObjectArray<btVector3>* vertices, btAlignedObjectArray<int>* indices,const float* scaling1) int btGpuNarrowPhase::registerConcaveMesh(btAlignedObjectArray<btVector3>* vertices, btAlignedObjectArray<int>* indices,const float* scaling1)
{ {
//right now we only support one single mesh, it is on the todo to merge all mesh data etc
btAssert(m_data->m_treeNodesGPU ==0);
btAssert(m_data->m_subTreesGPU ==0);
if (m_data->m_treeNodesGPU)
{
printf("error, only 1 single concave mesh supported at the moment\n");
exit (0);
}
btVector3 scaling(scaling1[0],scaling1[1],scaling1[2]); btVector3 scaling(scaling1[0],scaling1[1],scaling1[2]);
int collidableIndex = allocateCollidable(); int collidableIndex = allocateCollidable();
@@ -377,6 +396,17 @@ int btGpuNarrowPhase::registerConcaveMesh(btAlignedObjectArray<btVector3>* vert
meshInterface->addIndexedMesh(mesh); meshInterface->addIndexedMesh(mesh);
bvh->build(meshInterface, useQuantizedAabbCompression, (btVector3&)aabb.m_min, (btVector3&)aabb.m_max); bvh->build(meshInterface, useQuantizedAabbCompression, (btVector3&)aabb.m_min, (btVector3&)aabb.m_max);
m_data->m_bvhData.push_back(bvh); m_data->m_bvhData.push_back(bvh);
int numNodes = bvh->getQuantizedNodeArray().size();
btOpenCLArray<btQuantizedBvhNode>* treeNodesGPU = new btOpenCLArray<btQuantizedBvhNode>(this->m_context,this->m_queue,numNodes);
treeNodesGPU->copyFromHost(bvh->getQuantizedNodeArray());
int numSubTrees = bvh->getSubtreeInfoArray().size();
btOpenCLArray<btBvhSubtreeInfo>* subTreesGPU = new btOpenCLArray<btBvhSubtreeInfo>(this->m_context,this->m_queue,numSubTrees);
subTreesGPU->copyFromHost(bvh->getSubtreeInfoArray());
m_data->m_treeNodesGPU = treeNodesGPU;
m_data->m_subTreesGPU = subTreesGPU;
return collidableIndex; return collidableIndex;
} }
@@ -412,7 +442,7 @@ int btGpuNarrowPhase::registerConcaveMeshShape(btAlignedObjectArray<btVector3>*
{ {
if (i%256==0) if (i%256==0)
{ {
printf("i=%d out of %d", i,convex.m_numFaces); //printf("i=%d out of %d", i,convex.m_numFaces);
} }
btVector3 vert0(vertices->at(indices->at(i*3))*scaling); btVector3 vert0(vertices->at(indices->at(i*3))*scaling);
btVector3 vert1(vertices->at(indices->at(i*3+1))*scaling); btVector3 vert1(vertices->at(indices->at(i*3+1))*scaling);
@@ -524,7 +554,7 @@ void btGpuNarrowPhase::computeContacts(cl_mem broadphasePairs, int numBroadphase
{ {
int nContactOut = 0; int nContactOut = 0;
int maxTriConvexPairCapacity = 8192; int maxTriConvexPairCapacity = m_data->m_config.m_maxTriConvexPairCapacity;
btOpenCLArray<btInt4> triangleConvexPairs(m_context,m_queue, maxTriConvexPairCapacity); btOpenCLArray<btInt4> triangleConvexPairs(m_context,m_queue, maxTriConvexPairCapacity);
int numTriConvexPairsOut=0; int numTriConvexPairsOut=0;
@@ -552,6 +582,8 @@ void btGpuNarrowPhase::computeContacts(cl_mem broadphasePairs, int numBroadphase
*m_data->m_worldVertsA1GPU, *m_data->m_worldVertsA1GPU,
*m_data->m_worldVertsB2GPU, *m_data->m_worldVertsB2GPU,
m_data->m_bvhData, m_data->m_bvhData,
m_data->m_treeNodesGPU,
m_data->m_subTreesGPU,
numObjects, numObjects,
maxTriConvexPairCapacity, maxTriConvexPairCapacity,
triangleConvexPairs, triangleConvexPairs,

View File

@@ -224,16 +224,19 @@ __kernel void CreateBatches( __global const Contact4* gConstraints, __global Con
aAvailable = tryWrite( ldsCheckBuffer, ea ); aAvailable = tryWrite( ldsCheckBuffer, ea );
bAvailable = tryWrite( ldsCheckBuffer, eb ); bAvailable = tryWrite( ldsCheckBuffer, eb );
aAvailable = (e.m_a<0)? 1: aAvailable; bool aStatic = (e.m_a<0) ||(ea==m_staticIdx);
bAvailable = (e.m_b<0)? 1: bAvailable; bool bStatic = (e.m_b<0) ||(eb==m_staticIdx);
aAvailable = (e.m_a==m_staticIdx)? 1: aAvailable; aAvailable = aStatic? 1: aAvailable;
bAvailable = (e.m_b==m_staticIdx)? 1: bAvailable; bAvailable = bStatic? 1: bAvailable;
bool success = (aAvailable && bAvailable); bool success = (aAvailable && bAvailable);
if(success) if(success)
{ {
if (!aStatic)
writeBuf( ldsFixedBuffer, ea ); writeBuf( ldsFixedBuffer, ea );
if (!bStatic)
writeBuf( ldsFixedBuffer, eb ); writeBuf( ldsFixedBuffer, eb );
} }
done = success; done = success;

View File

@@ -226,16 +226,19 @@ static const char* batchingKernelsCL= \
" aAvailable = tryWrite( ldsCheckBuffer, ea );\n" " aAvailable = tryWrite( ldsCheckBuffer, ea );\n"
" bAvailable = tryWrite( ldsCheckBuffer, eb );\n" " bAvailable = tryWrite( ldsCheckBuffer, eb );\n"
"\n" "\n"
" aAvailable = (e.m_a<0)? 1: aAvailable;\n" " bool aStatic = (e.m_a<0) ||(ea==m_staticIdx);\n"
" bAvailable = (e.m_b<0)? 1: bAvailable;\n" " bool bStatic = (e.m_b<0) ||(eb==m_staticIdx);\n"
" \n" " \n"
" aAvailable = (e.m_a==m_staticIdx)? 1: aAvailable;\n" " aAvailable = aStatic? 1: aAvailable;\n"
" bAvailable = (e.m_b==m_staticIdx)? 1: bAvailable;\n" " bAvailable = bStatic? 1: bAvailable;\n"
"\n" "\n"
" bool success = (aAvailable && bAvailable);\n" " bool success = (aAvailable && bAvailable);\n"
" if(success)\n" " if(success)\n"
" {\n" " {\n"
" \n"
" if (!aStatic)\n"
" writeBuf( ldsFixedBuffer, ea );\n" " writeBuf( ldsFixedBuffer, ea );\n"
" if (!bStatic)\n"
" writeBuf( ldsFixedBuffer, eb );\n" " writeBuf( ldsFixedBuffer, eb );\n"
" }\n" " }\n"
" done = success;\n" " done = success;\n"

View File

@@ -23,7 +23,7 @@ subject to the following restrictions:
#include "ConvexHullContact.h" #include "ConvexHullContact.h"
#include <string.h>//memcpy #include <string.h>//memcpy
#include "btConvexPolyhedronCL.h" #include "btConvexPolyhedronCL.h"
#include "btOptimizedBvh.h"
typedef btAlignedObjectArray<btVector3> btVertexArray; typedef btAlignedObjectArray<btVector3> btVertexArray;
#include "BulletCommon/btQuickprof.h" #include "BulletCommon/btQuickprof.h"
@@ -61,6 +61,8 @@ m_totalContactsOut(m_context, m_queue)
m_findSeparatingAxisKernel = btOpenCLUtils::compileCLKernelFromString(m_context, m_device,src, "findSeparatingAxisKernel",&errNum,satProg ); m_findSeparatingAxisKernel = btOpenCLUtils::compileCLKernelFromString(m_context, m_device,src, "findSeparatingAxisKernel",&errNum,satProg );
m_findConcaveSeparatingAxisKernel = btOpenCLUtils::compileCLKernelFromString(m_context, m_device,src, "findConcaveSeparatingAxisKernel",&errNum,satProg );
m_findCompoundPairsKernel = btOpenCLUtils::compileCLKernelFromString(m_context, m_device,src, "findCompoundPairsKernel",&errNum,satProg ); m_findCompoundPairsKernel = btOpenCLUtils::compileCLKernelFromString(m_context, m_device,src, "findCompoundPairsKernel",&errNum,satProg );
@@ -130,6 +132,9 @@ GpuSatCollision::~GpuSatCollision()
if (m_findSeparatingAxisKernel) if (m_findSeparatingAxisKernel)
clReleaseKernel(m_findSeparatingAxisKernel); clReleaseKernel(m_findSeparatingAxisKernel);
if (m_findConcaveSeparatingAxisKernel)
clReleaseKernel(m_findConcaveSeparatingAxisKernel);
if (m_findCompoundPairsKernel) if (m_findCompoundPairsKernel)
clReleaseKernel(m_findCompoundPairsKernel); clReleaseKernel(m_findCompoundPairsKernel);
@@ -190,6 +195,8 @@ void GpuSatCollision::computeConvexConvexContactsGPUSAT( const btOpenCLArray<btI
btOpenCLArray<btVector3>& worldVertsA1GPU, btOpenCLArray<btVector3>& worldVertsA1GPU,
btOpenCLArray<btVector3>& worldVertsB2GPU, btOpenCLArray<btVector3>& worldVertsB2GPU,
btAlignedObjectArray<class btOptimizedBvh*>& bvhData, btAlignedObjectArray<class btOptimizedBvh*>& bvhData,
btOpenCLArray<btQuantizedBvhNode>* treeNodesGPU,
btOpenCLArray<btBvhSubtreeInfo>* subTreesGPU,
int numObjects, int numObjects,
int maxTriConvexPairCapacity, int maxTriConvexPairCapacity,
btOpenCLArray<btInt4>& triangleConvexPairsOut, btOpenCLArray<btInt4>& triangleConvexPairsOut,
@@ -231,14 +238,14 @@ void GpuSatCollision::computeConvexConvexContactsGPUSAT( const btOpenCLArray<btI
int numCompoundPairs = 0; int numCompoundPairs = 0;
bool findSeparatingAxisOnGpu = true;//false; bool findSeparatingAxisOnGpu = true;//false;
int numConcave =0; int numConcavePairs =0;
{ {
clFinish(m_queue); clFinish(m_queue);
if (findSeparatingAxisOnGpu) if (findSeparatingAxisOnGpu)
{ {
{
BT_PROFILE("findSeparatingAxisKernel"); BT_PROFILE("findSeparatingAxisKernel");
btBufferInfoCL bInfo[] = { btBufferInfoCL bInfo[] = {
btBufferInfoCL( pairs->getBufferCL(), true ), btBufferInfoCL( pairs->getBufferCL(), true ),
@@ -251,93 +258,31 @@ void GpuSatCollision::computeConvexConvexContactsGPUSAT( const btOpenCLArray<btI
btBufferInfoCL( gpuIndices.getBufferCL(),true), btBufferInfoCL( gpuIndices.getBufferCL(),true),
btBufferInfoCL( clAabbsWS.getBufferCL(),true), btBufferInfoCL( clAabbsWS.getBufferCL(),true),
btBufferInfoCL( sepNormals.getBufferCL()), btBufferInfoCL( sepNormals.getBufferCL()),
btBufferInfoCL( hasSeparatingNormals.getBufferCL()), btBufferInfoCL( hasSeparatingNormals.getBufferCL())
btBufferInfoCL( triangleConvexPairsOut.getBufferCL()),
btBufferInfoCL( concaveSepNormals.getBufferCL()),
btBufferInfoCL( numConcavePairsOut.getBufferCL())
}; };
btLauncherCL launcher(m_queue, m_findSeparatingAxisKernel); btLauncherCL launcher(m_queue, m_findSeparatingAxisKernel);
launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) ); launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) );
launcher.setConst( nPairs ); launcher.setConst( nPairs );
launcher.setConst( maxTriConvexPairCapacity);
int num = nPairs; int num = nPairs;
launcher.launch1D( num); launcher.launch1D( num);
clFinish(m_queue); clFinish(m_queue);
numConcave = numConcavePairsOut.at(0);
if (numConcave)
{
if (numConcave > maxTriConvexPairCapacity)
numConcave = maxTriConvexPairCapacity;
triangleConvexPairsOut.resize(numConcave);
btAlignedObjectArray<btInt4> triangleConvexPairsOutCPU;
triangleConvexPairsOut.copyToHost(triangleConvexPairsOutCPU);
printf("-----------------------\n", numConcave);
printf("got %d concave pairs\n", numConcave);
btAssert(numConcave = triangleConvexPairsOutCPU.size());
for (int i=0;i<triangleConvexPairsOutCPU.size();i++)
{
printf("bodyIndexA = %d, bodyIndexB = %d\n", triangleConvexPairsOutCPU[i].x,triangleConvexPairsOutCPU[i].y);
printf("triangleIndex = %d\n", triangleConvexPairsOutCPU[i].z);
}
printf("-----------------------\n", numConcave);
printf("Now using BVH query\n" );
btAlignedObjectArray<btCollidable> collidablesCPU;
gpuCollidables.copyToHost(collidablesCPU);
btAlignedObjectArray<btRigidBodyCL> bodiesCPU;
bodyBuf->copyToHost(bodiesCPU);
btAlignedObjectArray<btInt2> pairsCPU;
btAlignedObjectArray<btYetAnotherAabb> aabbsWSCPU;
clAabbsWS.copyToHost(aabbsWSCPU);
pairs->copyToHost(pairsCPU);
MyTriangleCallback triCallback;
for (int i=0;i<pairsCPU.size();i++)
{
int bodyIndexA = pairsCPU[i].x;
int bodyIndexB = pairsCPU[i].y;
triCallback.m_bodyIndexA = bodyIndexA;
triCallback.m_bodyIndexB = bodyIndexB;
int collidableIndexA = bodiesCPU[bodyIndexA].m_collidableIdx;
int collidableIndexB = bodiesCPU[bodyIndexB].m_collidableIdx;
if (collidablesCPU[collidableIndexA].m_shapeType==SHAPE_CONCAVE_TRIMESH)
{
//check aabbWS for bodyB against optimized BVH
btVector3 aabbMin = (const btVector3&)aabbsWSCPU[bodyIndexB].m_min[0];
aabbMin[3] = 0.f;
btVector3 aabbMax = (const btVector3&)aabbsWSCPU[bodyIndexB].m_max[0];
aabbMax[3] = 0.f;
bvhData[0]->reportAabbOverlappingNodex(&triCallback, aabbMin,aabbMax);
}
} }
//now perform the tree query on GPU //now perform the tree query on GPU
{
int numNodes = bvhData[0]->getLeafNodeArray().size(); int numNodes = bvhData.size()? bvhData[0]->getQuantizedNodeArray().size() : 0;
btOpenCLArray<btQuantizedBvhNode> treeNodesGPU(this->m_context,this->m_queue,numNodes); if (numNodes)
treeNodesGPU.copyFromHost(bvhData[0]->getQuantizedNodeArray()); {
int numSubTrees = bvhData[0]->getSubtreeInfoArray().size(); int numSubTrees = subTreesGPU->size();
btOpenCLArray<btBvhSubtreeInfo> subTreesGPU(this->m_context,this->m_queue,numSubTrees);
subTreesGPU.copyFromHost(bvhData[0]->getSubtreeInfoArray());
btVector3 bvhAabbMin = bvhData[0]->m_bvhAabbMin; btVector3 bvhAabbMin = bvhData[0]->m_bvhAabbMin;
btVector3 bvhAabbMax = bvhData[0]->m_bvhAabbMax; btVector3 bvhAabbMax = bvhData[0]->m_bvhAabbMax;
btVector3 bvhQuantization = bvhData[0]->m_bvhQuantization; btVector3 bvhQuantization = bvhData[0]->m_bvhQuantization;
{ {
int np = numConcavePairsOut.at(0); BT_PROFILE("m_bvhTraversalKernel");
printf("np=%d\n", np); numConcavePairs = numConcavePairsOut.at(0);
btLauncherCL launcher(m_queue, m_bvhTraversalKernel); btLauncherCL launcher(m_queue, m_bvhTraversalKernel);
launcher.setBuffer( pairs->getBufferCL()); launcher.setBuffer( pairs->getBufferCL());
launcher.setBuffer( bodyBuf->getBufferCL()); launcher.setBuffer( bodyBuf->getBufferCL());
@@ -345,8 +290,8 @@ void GpuSatCollision::computeConvexConvexContactsGPUSAT( const btOpenCLArray<btI
launcher.setBuffer( clAabbsWS.getBufferCL()); launcher.setBuffer( clAabbsWS.getBufferCL());
launcher.setBuffer( triangleConvexPairsOut.getBufferCL()); launcher.setBuffer( triangleConvexPairsOut.getBufferCL());
launcher.setBuffer( numConcavePairsOut.getBufferCL()); launcher.setBuffer( numConcavePairsOut.getBufferCL());
launcher.setBuffer( subTreesGPU.getBufferCL()); launcher.setBuffer( subTreesGPU->getBufferCL());
launcher.setBuffer( treeNodesGPU.getBufferCL()); launcher.setBuffer( treeNodesGPU->getBufferCL());
launcher.setConst( bvhAabbMin); launcher.setConst( bvhAabbMin);
launcher.setConst( bvhAabbMax); launcher.setConst( bvhAabbMax);
launcher.setConst( bvhQuantization); launcher.setConst( bvhQuantization);
@@ -356,19 +301,47 @@ void GpuSatCollision::computeConvexConvexContactsGPUSAT( const btOpenCLArray<btI
int num = nPairs; int num = nPairs;
launcher.launch1D( num); launcher.launch1D( num);
clFinish(m_queue); clFinish(m_queue);
np = numConcavePairsOut.at(0); numConcavePairs = numConcavePairsOut.at(0);
triangleConvexPairsOut.resize(np);
btAlignedObjectArray<btInt4> pairsOutCPU; if (numConcavePairs > maxTriConvexPairCapacity)
triangleConvexPairsOut.copyToHost(pairsOutCPU); {
static int exceeded_maxTriConvexPairCapacity_count = 0;
printf("Rxceeded %d times the maxTriConvexPairCapacity (found %d but max is %d)\n", exceeded_maxTriConvexPairCapacity_count++,
numConcavePairs,maxTriConvexPairCapacity);
numConcavePairs = maxTriConvexPairCapacity;
}
triangleConvexPairsOut.resize(numConcavePairs);
if (numConcavePairs)
{
//now perform a SAT test for each triangle-convex element (stored in triangleConvexPairsOut)
BT_PROFILE("findConcaveSeparatingAxisKernel");
btBufferInfoCL bInfo[] = {
btBufferInfoCL( triangleConvexPairsOut.getBufferCL() ),
btBufferInfoCL( bodyBuf->getBufferCL(),true),
btBufferInfoCL( gpuCollidables.getBufferCL(),true),
btBufferInfoCL( convexData.getBufferCL(),true),
btBufferInfoCL( gpuVertices.getBufferCL(),true),
btBufferInfoCL( gpuUniqueEdges.getBufferCL(),true),
btBufferInfoCL( gpuFaces.getBufferCL(),true),
btBufferInfoCL( gpuIndices.getBufferCL(),true),
btBufferInfoCL( clAabbsWS.getBufferCL(),true),
btBufferInfoCL( sepNormals.getBufferCL()),
btBufferInfoCL( hasSeparatingNormals.getBufferCL()),
btBufferInfoCL( concaveSepNormals.getBufferCL())
};
btLauncherCL launcher(m_queue, m_findConcaveSeparatingAxisKernel);
launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) );
launcher.setConst( numConcavePairs );
int num = numConcavePairs;
launcher.launch1D( num);
clFinish(m_queue); clFinish(m_queue);
printf("np=%d\n", np);
} }
printf("-----------------------\n", numConcave);
} }
}
}
{ {
@@ -467,7 +440,7 @@ void GpuSatCollision::computeConvexConvexContactsGPUSAT( const btOpenCLArray<btI
//concave-convex contact clipping //concave-convex contact clipping
if (numConcave) if (numConcavePairs)
{ {
BT_PROFILE("clipHullHullConcaveConvexKernel"); BT_PROFILE("clipHullHullConcaveConvexKernel");
nContacts = m_totalContactsOut.at(0); nContacts = m_totalContactsOut.at(0);
@@ -486,8 +459,8 @@ void GpuSatCollision::computeConvexConvexContactsGPUSAT( const btOpenCLArray<btI
}; };
btLauncherCL launcher(m_queue, m_clipHullHullConcaveConvexKernel); btLauncherCL launcher(m_queue, m_clipHullHullConcaveConvexKernel);
launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) ); launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) );
launcher.setConst( numConcave ); launcher.setConst( numConcavePairs );
int num = numConcave; int num = numConcavePairs;
launcher.launch1D( num); launcher.launch1D( num);
clFinish(m_queue); clFinish(m_queue);
nContacts = m_totalContactsOut.at(0); nContacts = m_totalContactsOut.at(0);

View File

@@ -11,6 +11,7 @@
#include "btContact4.h" #include "btContact4.h"
#include "parallel_primitives/host/btInt2.h" #include "parallel_primitives/host/btInt2.h"
#include "parallel_primitives/host/btInt4.h" #include "parallel_primitives/host/btInt4.h"
#include "btOptimizedBvh.h"
//#include "../../dynamics/basic_demo/Stubs/ChNarrowPhase.h" //#include "../../dynamics/basic_demo/Stubs/ChNarrowPhase.h"
@@ -36,6 +37,7 @@ struct GpuSatCollision
cl_device_id m_device; cl_device_id m_device;
cl_command_queue m_queue; cl_command_queue m_queue;
cl_kernel m_findSeparatingAxisKernel; cl_kernel m_findSeparatingAxisKernel;
cl_kernel m_findConcaveSeparatingAxisKernel;
cl_kernel m_findCompoundPairsKernel; cl_kernel m_findCompoundPairsKernel;
cl_kernel m_processCompoundPairsKernel; cl_kernel m_processCompoundPairsKernel;
@@ -76,6 +78,8 @@ struct GpuSatCollision
btOpenCLArray<btVector3>& worldVertsA1GPU, btOpenCLArray<btVector3>& worldVertsA1GPU,
btOpenCLArray<btVector3>& worldVertsB2GPU, btOpenCLArray<btVector3>& worldVertsB2GPU,
btAlignedObjectArray<class btOptimizedBvh*>& bvhData, btAlignedObjectArray<class btOptimizedBvh*>& bvhData,
btOpenCLArray<btQuantizedBvhNode>* treeNodesGPU,
btOpenCLArray<btBvhSubtreeInfo>* subTreesGPU,
int numObjects, int numObjects,
int maxTriConvexPairCapacity, int maxTriConvexPairCapacity,
btOpenCLArray<btInt4>& triangleConvexPairs, btOpenCLArray<btInt4>& triangleConvexPairs,

View File

@@ -939,11 +939,7 @@ __kernel void findSeparatingAxisKernel( __global const int2* pairs,
__global btAabbCL* aabbs, __global btAabbCL* aabbs,
__global volatile float4* separatingNormals, __global volatile float4* separatingNormals,
__global volatile int* hasSeparatingAxis, __global volatile int* hasSeparatingAxis,
__global int4* concavePairsOut, int numPairs
__global float4* concaveSeparatingNormalsOut,
__global volatile int* numConcavePairsOut,
int numPairs,
int maxNumConcavePairsCapacity
) )
{ {
@@ -970,14 +966,117 @@ __kernel void findSeparatingAxisKernel( __global const int2* pairs,
return; return;
} }
if ((collidables[collidableIndexA].m_shapeType==SHAPE_CONCAVE_TRIMESH))// && (collidables[collidableIndexB].m_shapeType==SHAPE_CONVEX_HULL))
if ((collidables[collidableIndexA].m_shapeType!=SHAPE_CONVEX_HULL) ||(collidables[collidableIndexB].m_shapeType!=SHAPE_CONVEX_HULL))
{ {
hasSeparatingAxis[i] = 0;
return;
}
if ((collidables[collidableIndexA].m_shapeType==SHAPE_CONCAVE_TRIMESH))
{
hasSeparatingAxis[i] = 0;
return;
}
int numFacesA = convexShapes[shapeIndexA].m_numFaces;
float dmin = FLT_MAX;
float4 posA = rigidBodies[bodyIndexA].m_pos;
posA.w = 0.f;
float4 posB = rigidBodies[bodyIndexB].m_pos;
posB.w = 0.f;
float4 c0local = convexShapes[shapeIndexA].m_localCenter;
float4 ornA = rigidBodies[bodyIndexA].m_quat;
float4 c0 = transform(&c0local, &posA, &ornA);
float4 c1local = convexShapes[shapeIndexB].m_localCenter;
float4 ornB =rigidBodies[bodyIndexB].m_quat;
float4 c1 = transform(&c1local,&posB,&ornB);
const float4 DeltaC2 = c0 - c1;
float4 sepNormal;
bool sepA = findSeparatingAxis( &convexShapes[shapeIndexA], &convexShapes[shapeIndexB],posA,ornA,
posB,ornB,
DeltaC2,
vertices,uniqueEdges,faces,
indices,&sepNormal,&dmin);
hasSeparatingAxis[i] = 4;
if (!sepA)
{
hasSeparatingAxis[i] = 0;
} else
{
bool sepB = findSeparatingAxis( &convexShapes[shapeIndexB],&convexShapes[shapeIndexA],posB,ornB,
posA,ornA,
DeltaC2,
vertices,uniqueEdges,faces,
indices,&sepNormal,&dmin);
if (!sepB)
{
hasSeparatingAxis[i] = 0;
} else
{
bool sepEE = findSeparatingAxisEdgeEdge( &convexShapes[shapeIndexA], &convexShapes[shapeIndexB],posA,ornA,
posB,ornB,
DeltaC2,
vertices,uniqueEdges,faces,
indices,&sepNormal,&dmin);
if (!sepEE)
{
hasSeparatingAxis[i] = 0;
} else
{
hasSeparatingAxis[i] = 1;
separatingNormals[i] = sepNormal;
}
}
}
}
}
// work-in-progress
__kernel void findConcaveSeparatingAxisKernel( __global int4* concavePairs,
__global const BodyData* rigidBodies,
__global const btCollidableGpu* collidables,
__global const ConvexPolyhedronCL* convexShapes,
__global const float4* vertices,
__global const float4* uniqueEdges,
__global const btGpuFace* faces,
__global const int* indices,
__global btAabbCL* aabbs,
__global volatile float4* separatingNormals,
__global volatile int* hasSeparatingAxis,
__global float4* concaveSeparatingNormalsOut,
int numConcavePairs
)
{
int i = get_global_id(0);
if (i>=numConcavePairs)
return;
int pairIdx = i;
int bodyIndexA = concavePairs[i].x;
int bodyIndexB = concavePairs[i].y;
int collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;
int collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx;
int shapeIndexA = collidables[collidableIndexA].m_shapeIndex;
int shapeIndexB = collidables[collidableIndexB].m_shapeIndex;
int numFacesA = convexShapes[shapeIndexA].m_numFaces; int numFacesA = convexShapes[shapeIndexA].m_numFaces;
int numActualConcaveConvexTests = 0; int numActualConcaveConvexTests = 0;
for (int f=0;f<numFacesA;f++) int f = concavePairs[i].z;
{
bool overlap = false; bool overlap = false;
@@ -1001,25 +1100,10 @@ __kernel void findSeparatingAxisKernel( __global const int2* pairs,
float4 vert = vertices[convexShapes[shapeIndexA].m_vertexOffset+index]; float4 vert = vertices[convexShapes[shapeIndexA].m_vertexOffset+index];
verticesA[i] = vert; verticesA[i] = vert;
localCenter += vert; localCenter += vert;
#if 0
//just in case some implementation doesn't support component-wise min and max for float4
if (triAabb.m_min.x > vert.x)
triAabb.m_min.x = vert.x;
if (triAabb.m_min.y > vert.y)
triAabb.m_min.y = vert.y;
if (triAabb.m_min.z > vert.z)
triAabb.m_min.z = vert.z;
if (triAabb.m_max.x < vert.x)
triAabb.m_max.x = vert.x;
if (triAabb.m_max.y < vert.y)
triAabb.m_max.y = vert.y;
if (triAabb.m_max.z < vert.z)
triAabb.m_max.z = vert.z;
#else
triAabb.m_min = min(triAabb.m_min,vert); triAabb.m_min = min(triAabb.m_min,vert);
triAabb.m_max = max(triAabb.m_max,vert); triAabb.m_max = max(triAabb.m_max,vert);
#endif
} }
overlap = true; overlap = true;
@@ -1033,8 +1117,6 @@ __kernel void findSeparatingAxisKernel( __global const int2* pairs,
int hasSeparatingAxis=5; int hasSeparatingAxis=5;
float4 sepAxis=make_float4(1,2,3,4); float4 sepAxis=make_float4(1,2,3,4);
#if 1
int localCC=0; int localCC=0;
numActualConcaveConvexTests++; numActualConcaveConvexTests++;
@@ -1171,95 +1253,20 @@ __kernel void findSeparatingAxisKernel( __global const int2* pairs,
} }
} }
} }
#endif
if (hasSeparatingAxis) if (hasSeparatingAxis)
{ {
int pairIdx = atomic_inc(numConcavePairsOut);
if (pairIdx<maxNumConcavePairsCapacity)
{
concavePairsOut[pairIdx].x = bodyIndexA;
concavePairsOut[pairIdx].y = bodyIndexB;
concavePairsOut[pairIdx].z = f;
concavePairsOut[pairIdx].w = 3;
sepAxis.w = dmin; sepAxis.w = dmin;
concaveSeparatingNormalsOut[pairIdx]=sepAxis; concaveSeparatingNormalsOut[pairIdx]=sepAxis;
}
}
}
}
//todo//??
hasSeparatingAxis[i] = 0;
return;
}
if ((collidables[collidableIndexA].m_shapeType!=SHAPE_CONVEX_HULL) ||(collidables[collidableIndexB].m_shapeType!=SHAPE_CONVEX_HULL))
{
hasSeparatingAxis[i] = 0;
return;
}
int numFacesA = convexShapes[shapeIndexA].m_numFaces;
float dmin = FLT_MAX;
float4 posA = rigidBodies[bodyIndexA].m_pos;
posA.w = 0.f;
float4 posB = rigidBodies[bodyIndexB].m_pos;
posB.w = 0.f;
float4 c0local = convexShapes[shapeIndexA].m_localCenter;
float4 ornA = rigidBodies[bodyIndexA].m_quat;
float4 c0 = transform(&c0local, &posA, &ornA);
float4 c1local = convexShapes[shapeIndexB].m_localCenter;
float4 ornB =rigidBodies[bodyIndexB].m_quat;
float4 c1 = transform(&c1local,&posB,&ornB);
const float4 DeltaC2 = c0 - c1;
float4 sepNormal;
bool sepA = findSeparatingAxis( &convexShapes[shapeIndexA], &convexShapes[shapeIndexB],posA,ornA,
posB,ornB,
DeltaC2,
vertices,uniqueEdges,faces,
indices,&sepNormal,&dmin);
hasSeparatingAxis[i] = 4;
if (!sepA)
{
hasSeparatingAxis[i] = 0;
} else } else
{ {
bool sepB = findSeparatingAxis( &convexShapes[shapeIndexB],&convexShapes[shapeIndexA],posB,ornB, //mark this pair as in-active
posA,ornA, concavePairs[pairIdx].w = 0;
DeltaC2, }
vertices,uniqueEdges,faces, }
indices,&sepNormal,&dmin); else
if (!sepB)
{ {
hasSeparatingAxis[i] = 0; //mark this pair as in-active
} else concavePairs[pairIdx].w = 0;
{
bool sepEE = findSeparatingAxisEdgeEdge( &convexShapes[shapeIndexA], &convexShapes[shapeIndexB],posA,ornA,
posB,ornB,
DeltaC2,
vertices,uniqueEdges,faces,
indices,&sepNormal,&dmin);
if (!sepEE)
{
hasSeparatingAxis[i] = 0;
} else
{
hasSeparatingAxis[i] = 1;
separatingNormals[i] = sepNormal;
} }
} }
}
}
}

View File

@@ -1413,6 +1413,9 @@ __kernel void clipHullHullConcaveConvexKernel( __global int4* concavePairsIn,
if (i<numConcavePairs) if (i<numConcavePairs)
{ {
//magic value to detect that pair is invalid
if (concavePairsIn[i].w!=3)
return;
int bodyIndexA = concavePairsIn[i].x; int bodyIndexA = concavePairsIn[i].x;
int bodyIndexB = concavePairsIn[i].y; int bodyIndexB = concavePairsIn[i].y;

View File

@@ -1415,6 +1415,9 @@ static const char* satClipKernelsCL= \
"\n" "\n"
" if (i<numConcavePairs)\n" " if (i<numConcavePairs)\n"
" {\n" " {\n"
" //magic value to detect that pair is invalid\n"
" if (concavePairsIn[i].w!=3)\n"
" return;\n"
"\n" "\n"
" int bodyIndexA = concavePairsIn[i].x;\n" " int bodyIndexA = concavePairsIn[i].x;\n"
" int bodyIndexB = concavePairsIn[i].y;\n" " int bodyIndexB = concavePairsIn[i].y;\n"

View File

@@ -941,11 +941,7 @@ static const char* satKernelsCL= \
" __global btAabbCL* aabbs,\n" " __global btAabbCL* aabbs,\n"
" __global volatile float4* separatingNormals,\n" " __global volatile float4* separatingNormals,\n"
" __global volatile int* hasSeparatingAxis,\n" " __global volatile int* hasSeparatingAxis,\n"
" __global int4* concavePairsOut,\n" " int numPairs\n"
" __global float4* concaveSeparatingNormalsOut,\n"
" __global volatile int* numConcavePairsOut,\n"
" int numPairs,\n"
" int maxNumConcavePairsCapacity\n"
" )\n" " )\n"
"{\n" "{\n"
"\n" "\n"
@@ -972,14 +968,117 @@ static const char* satKernelsCL= \
" return;\n" " return;\n"
" }\n" " }\n"
" \n" " \n"
" if ((collidables[collidableIndexA].m_shapeType==SHAPE_CONCAVE_TRIMESH))// && (collidables[collidableIndexB].m_shapeType==SHAPE_CONVEX_HULL))\n" "\n"
" if ((collidables[collidableIndexA].m_shapeType!=SHAPE_CONVEX_HULL) ||(collidables[collidableIndexB].m_shapeType!=SHAPE_CONVEX_HULL))\n"
" {\n" " {\n"
" hasSeparatingAxis[i] = 0;\n"
" return;\n"
" }\n"
" \n"
" if ((collidables[collidableIndexA].m_shapeType==SHAPE_CONCAVE_TRIMESH))\n"
" {\n"
" hasSeparatingAxis[i] = 0;\n"
" return;\n"
" }\n"
"\n"
" int numFacesA = convexShapes[shapeIndexA].m_numFaces;\n"
"\n"
" float dmin = FLT_MAX;\n"
"\n"
" float4 posA = rigidBodies[bodyIndexA].m_pos;\n"
" posA.w = 0.f;\n"
" float4 posB = rigidBodies[bodyIndexB].m_pos;\n"
" posB.w = 0.f;\n"
" float4 c0local = convexShapes[shapeIndexA].m_localCenter;\n"
" float4 ornA = rigidBodies[bodyIndexA].m_quat;\n"
" float4 c0 = transform(&c0local, &posA, &ornA);\n"
" float4 c1local = convexShapes[shapeIndexB].m_localCenter;\n"
" float4 ornB =rigidBodies[bodyIndexB].m_quat;\n"
" float4 c1 = transform(&c1local,&posB,&ornB);\n"
" const float4 DeltaC2 = c0 - c1;\n"
" float4 sepNormal;\n"
" \n"
" bool sepA = findSeparatingAxis( &convexShapes[shapeIndexA], &convexShapes[shapeIndexB],posA,ornA,\n"
" posB,ornB,\n"
" DeltaC2,\n"
" vertices,uniqueEdges,faces,\n"
" indices,&sepNormal,&dmin);\n"
" hasSeparatingAxis[i] = 4;\n"
" if (!sepA)\n"
" {\n"
" hasSeparatingAxis[i] = 0;\n"
" } else\n"
" {\n"
" bool sepB = findSeparatingAxis( &convexShapes[shapeIndexB],&convexShapes[shapeIndexA],posB,ornB,\n"
" posA,ornA,\n"
" DeltaC2,\n"
" vertices,uniqueEdges,faces,\n"
" indices,&sepNormal,&dmin);\n"
"\n"
" if (!sepB)\n"
" {\n"
" hasSeparatingAxis[i] = 0;\n"
" } else\n"
" {\n"
" bool sepEE = findSeparatingAxisEdgeEdge( &convexShapes[shapeIndexA], &convexShapes[shapeIndexB],posA,ornA,\n"
" posB,ornB,\n"
" DeltaC2,\n"
" vertices,uniqueEdges,faces,\n"
" indices,&sepNormal,&dmin);\n"
" if (!sepEE)\n"
" {\n"
" hasSeparatingAxis[i] = 0;\n"
" } else\n"
" {\n"
" hasSeparatingAxis[i] = 1;\n"
" separatingNormals[i] = sepNormal;\n"
" }\n"
" }\n"
" }\n"
" \n"
" }\n"
"\n"
"}\n"
"\n"
"\n"
"\n"
"\n"
"// work-in-progress\n"
"__kernel void findConcaveSeparatingAxisKernel( __global int4* concavePairs,\n"
" __global const BodyData* rigidBodies,\n"
" __global const btCollidableGpu* collidables,\n"
" __global const ConvexPolyhedronCL* convexShapes, \n"
" __global const float4* vertices,\n"
" __global const float4* uniqueEdges,\n"
" __global const btGpuFace* faces,\n"
" __global const int* indices,\n"
" __global btAabbCL* aabbs,\n"
" __global volatile float4* separatingNormals,\n"
" __global volatile int* hasSeparatingAxis,\n"
" __global float4* concaveSeparatingNormalsOut,\n"
" int numConcavePairs\n"
" )\n"
"{\n"
"\n"
" int i = get_global_id(0);\n"
" if (i>=numConcavePairs)\n"
" return;\n"
" int pairIdx = i;\n"
"\n"
" int bodyIndexA = concavePairs[i].x;\n"
" int bodyIndexB = concavePairs[i].y;\n"
"\n"
" int collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;\n"
" int collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx;\n"
"\n"
" int shapeIndexA = collidables[collidableIndexA].m_shapeIndex;\n"
" int shapeIndexB = collidables[collidableIndexB].m_shapeIndex;\n"
"\n"
"\n" "\n"
" int numFacesA = convexShapes[shapeIndexA].m_numFaces;\n" " int numFacesA = convexShapes[shapeIndexA].m_numFaces;\n"
" int numActualConcaveConvexTests = 0;\n" " int numActualConcaveConvexTests = 0;\n"
" \n" " \n"
" for (int f=0;f<numFacesA;f++)\n" " int f = concavePairs[i].z;\n"
" {\n"
" \n" " \n"
" bool overlap = false;\n" " bool overlap = false;\n"
" \n" " \n"
@@ -1003,25 +1102,10 @@ static const char* satKernelsCL= \
" float4 vert = vertices[convexShapes[shapeIndexA].m_vertexOffset+index];\n" " float4 vert = vertices[convexShapes[shapeIndexA].m_vertexOffset+index];\n"
" verticesA[i] = vert;\n" " verticesA[i] = vert;\n"
" localCenter += vert;\n" " localCenter += vert;\n"
"#if 0\n"
"//just in case some implementation doesn't support component-wise min and max for float4\n"
" if (triAabb.m_min.x > vert.x)\n"
" triAabb.m_min.x = vert.x;\n"
" if (triAabb.m_min.y > vert.y)\n"
" triAabb.m_min.y = vert.y;\n"
" if (triAabb.m_min.z > vert.z)\n"
" triAabb.m_min.z = vert.z;\n"
" \n" " \n"
" if (triAabb.m_max.x < vert.x)\n"
" triAabb.m_max.x = vert.x;\n"
" if (triAabb.m_max.y < vert.y)\n"
" triAabb.m_max.y = vert.y;\n"
" if (triAabb.m_max.z < vert.z)\n"
" triAabb.m_max.z = vert.z;\n"
"#else \n"
" triAabb.m_min = min(triAabb.m_min,vert); \n" " triAabb.m_min = min(triAabb.m_min,vert); \n"
" triAabb.m_max = max(triAabb.m_max,vert); \n" " triAabb.m_max = max(triAabb.m_max,vert); \n"
"#endif \n" "\n"
" }\n" " }\n"
"\n" "\n"
" overlap = true;\n" " overlap = true;\n"
@@ -1035,8 +1119,6 @@ static const char* satKernelsCL= \
" int hasSeparatingAxis=5;\n" " int hasSeparatingAxis=5;\n"
" float4 sepAxis=make_float4(1,2,3,4);\n" " float4 sepAxis=make_float4(1,2,3,4);\n"
"\n" "\n"
"#if 1\n"
" \n"
" int localCC=0;\n" " int localCC=0;\n"
" numActualConcaveConvexTests++;\n" " numActualConcaveConvexTests++;\n"
"\n" "\n"
@@ -1173,96 +1255,22 @@ static const char* satKernelsCL= \
" }\n" " }\n"
" }\n" " }\n"
" } \n" " } \n"
"#endif\n"
" \n" " \n"
" if (hasSeparatingAxis)\n" " if (hasSeparatingAxis)\n"
" {\n" " {\n"
" int pairIdx = atomic_inc(numConcavePairsOut);\n"
" if (pairIdx<maxNumConcavePairsCapacity)\n"
" {\n"
" concavePairsOut[pairIdx].x = bodyIndexA;\n"
" concavePairsOut[pairIdx].y = bodyIndexB;\n"
" concavePairsOut[pairIdx].z = f;\n"
" concavePairsOut[pairIdx].w = 3;\n"
" sepAxis.w = dmin;\n" " sepAxis.w = dmin;\n"
" concaveSeparatingNormalsOut[pairIdx]=sepAxis;\n" " concaveSeparatingNormalsOut[pairIdx]=sepAxis;\n"
" }\n"
" }\n"
" }\n"
" }\n"
" //todo//??\n"
" hasSeparatingAxis[i] = 0;\n"
" return;\n"
" } \n"
"\n"
" \n"
"\n"
" if ((collidables[collidableIndexA].m_shapeType!=SHAPE_CONVEX_HULL) ||(collidables[collidableIndexB].m_shapeType!=SHAPE_CONVEX_HULL))\n"
" {\n"
" hasSeparatingAxis[i] = 0;\n"
" return;\n"
" }\n"
" \n"
"\n"
"\n"
"\n"
" \n"
" int numFacesA = convexShapes[shapeIndexA].m_numFaces;\n"
"\n"
" float dmin = FLT_MAX;\n"
"\n"
" float4 posA = rigidBodies[bodyIndexA].m_pos;\n"
" posA.w = 0.f;\n"
" float4 posB = rigidBodies[bodyIndexB].m_pos;\n"
" posB.w = 0.f;\n"
" float4 c0local = convexShapes[shapeIndexA].m_localCenter;\n"
" float4 ornA = rigidBodies[bodyIndexA].m_quat;\n"
" float4 c0 = transform(&c0local, &posA, &ornA);\n"
" float4 c1local = convexShapes[shapeIndexB].m_localCenter;\n"
" float4 ornB =rigidBodies[bodyIndexB].m_quat;\n"
" float4 c1 = transform(&c1local,&posB,&ornB);\n"
" const float4 DeltaC2 = c0 - c1;\n"
" float4 sepNormal;\n"
" \n"
" bool sepA = findSeparatingAxis( &convexShapes[shapeIndexA], &convexShapes[shapeIndexB],posA,ornA,\n"
" posB,ornB,\n"
" DeltaC2,\n"
" vertices,uniqueEdges,faces,\n"
" indices,&sepNormal,&dmin);\n"
" hasSeparatingAxis[i] = 4;\n"
" if (!sepA)\n"
" {\n"
" hasSeparatingAxis[i] = 0;\n"
" } else\n" " } else\n"
" { \n" " { \n"
" bool sepB = findSeparatingAxis( &convexShapes[shapeIndexB],&convexShapes[shapeIndexA],posB,ornB,\n" " //mark this pair as in-active\n"
" posA,ornA,\n" " concavePairs[pairIdx].w = 0;\n"
" DeltaC2,\n"
" vertices,uniqueEdges,faces,\n"
" indices,&sepNormal,&dmin);\n"
"\n"
" if (!sepB)\n"
" {\n"
" hasSeparatingAxis[i] = 0;\n"
" } else\n"
" {\n"
" bool sepEE = findSeparatingAxisEdgeEdge( &convexShapes[shapeIndexA], &convexShapes[shapeIndexB],posA,ornA,\n"
" posB,ornB,\n"
" DeltaC2,\n"
" vertices,uniqueEdges,faces,\n"
" indices,&sepNormal,&dmin);\n"
" if (!sepEE)\n"
" {\n"
" hasSeparatingAxis[i] = 0;\n"
" } else\n"
" {\n"
" hasSeparatingAxis[i] = 1;\n"
" separatingNormals[i] = sepNormal;\n"
" }\n" " }\n"
" }\n" " }\n"
" else\n"
" { \n"
" //mark this pair as in-active\n"
" concavePairs[pairIdx].w = 0;\n"
" }\n"
"}\n" "}\n"
"\n" "\n"
" }\n"
"\n"
"}\n"
; ;