add gpu_sat

This commit is contained in:
erwin coumans
2013-03-12 21:11:46 -07:00
parent ecdb0e52ca
commit 9612c2cd3d
19 changed files with 8283 additions and 76 deletions

View File

@@ -92,6 +92,7 @@
include "../opencl/lds_bank_conflict"
include "../opencl/reduce"
include "../opencl/gpu_broadphase/test"
include "../opencl/gpu_sat/test"
end

View File

@@ -11,6 +11,9 @@ premake4 --file=stringifyKernel.lua --kernelfile="../opencl/parallel_primitives/
premake4 --file=stringifyKernel.lua --kernelfile="../opencl/gpu_broadphase/kernels/sap.cl" --headerfile="../opencl/gpu_broadphase/kernels/sapKernels.h" --stringname="sapCL" stringify
premake4 --file=stringifyKernel.lua --kernelfile="../opencl/gpu_broadphase/kernels/sapFast.cl" --headerfile="../opencl/gpu_broadphase/kernels/sapFastKernels.h" --stringname="sapFastCL" stringify
premake4 --file=stringifyKernel.lua --kernelfile="../opencl/gpu_sat/kernels/sat.cl" --headerfile="../opencl/gpu_sat/kernels/satKernels.h" --stringname="satKernelsCL" stringify
premake4 --file=stringifyKernel.lua --kernelfile="../opencl/gpu_sat/kernels/satClipHullContacts.cl" --headerfile="../opencl/gpu_sat/kernels/satClipHullContacts.h" --stringname="satClipKernelsCL" stringify
pause

View File

@@ -0,0 +1,581 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2011 Advanced Micro Devices, Inc. http://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
///This file was written by Erwin Coumans
///Separating axis rest based on work from Pierre Terdiman, see
///And contact clipping based on work from Simon Hobbs
//#define BT_DEBUG_SAT_FACE
#include "ConvexHullContact.h"
#include <string.h>//memcpy
#include "btConvexPolyhedronCL.h"
typedef btAlignedObjectArray<btVector3> btVertexArray;
#include "parallel_primitives/host/btQuickprof.h"
#include <float.h> //for FLT_MAX
#include "../basic_initialize/btOpenCLUtils.h"
#include "parallel_primitives/host/btLauncherCL.h"
//#include "AdlQuaternion.h"
#include "../kernels/satKernels.h"
#include "../kernels/satClipHullContacts.h"
#include "parallel_primitives/host/btAabbUtil2.h"
#define dot3F4 btDot
GpuSatCollision::GpuSatCollision(cl_context ctx,cl_device_id device, cl_command_queue q )
:m_context(ctx),
m_device(device),
m_queue(q),
m_findSeparatingAxisKernel(0),
m_totalContactsOut(m_context, m_queue)
{
m_totalContactsOut.push_back(0);
cl_int errNum=0;
if (1)
{
const char* src = satKernelsCL;
cl_program satProg = btOpenCLUtils::compileCLProgramFromString(m_context,m_device,src,&errNum,"","opencl/gpu_rigidbody_pipeline2/sat.cl");
btAssert(errNum==CL_SUCCESS);
m_findSeparatingAxisKernel = btOpenCLUtils::compileCLKernelFromString(m_context, m_device,src, "findSeparatingAxisKernel",&errNum,satProg );
m_findCompoundPairsKernel = btOpenCLUtils::compileCLKernelFromString(m_context, m_device,src, "findCompoundPairsKernel",&errNum,satProg );
m_processCompoundPairsKernel = btOpenCLUtils::compileCLKernelFromString(m_context, m_device,src, "processCompoundPairsKernel",&errNum,satProg );
btAssert(errNum==CL_SUCCESS);
}
if (1)
{
const char* srcClip = satClipKernelsCL;
cl_program satClipContactsProg = btOpenCLUtils::compileCLProgramFromString(m_context,m_device,srcClip,&errNum,"","opencl/gpu_rigidbody_pipeline2/satClipHullContacts.cl");
btAssert(errNum==CL_SUCCESS);
m_clipHullHullKernel = btOpenCLUtils::compileCLKernelFromString(m_context, m_device,srcClip, "clipHullHullKernel",&errNum,satClipContactsProg);
btAssert(errNum==CL_SUCCESS);
m_clipCompoundsHullHullKernel = btOpenCLUtils::compileCLKernelFromString(m_context, m_device,srcClip, "clipCompoundsHullHullKernel",&errNum,satClipContactsProg);
btAssert(errNum==CL_SUCCESS);
m_findClippingFacesKernel = btOpenCLUtils::compileCLKernelFromString(m_context, m_device,srcClip, "findClippingFacesKernel",&errNum,satClipContactsProg);
btAssert(errNum==CL_SUCCESS);
m_clipFacesAndContactReductionKernel = btOpenCLUtils::compileCLKernelFromString(m_context, m_device,srcClip, "clipFacesAndContactReductionKernel",&errNum,satClipContactsProg);
btAssert(errNum==CL_SUCCESS);
m_clipHullHullConcaveConvexKernel = btOpenCLUtils::compileCLKernelFromString(m_context, m_device,srcClip, "clipHullHullConcaveConvexKernel",&errNum,satClipContactsProg);
btAssert(errNum==CL_SUCCESS);
m_extractManifoldAndAddContactKernel = btOpenCLUtils::compileCLKernelFromString(m_context, m_device,srcClip, "extractManifoldAndAddContactKernel",&errNum,satClipContactsProg);
btAssert(errNum==CL_SUCCESS);
m_newContactReductionKernel = btOpenCLUtils::compileCLKernelFromString(m_context, m_device,srcClip,
"newContactReductionKernel",&errNum,satClipContactsProg);
btAssert(errNum==CL_SUCCESS);
} else
{
m_clipHullHullKernel=0;
m_clipCompoundsHullHullKernel = 0;
m_findClippingFacesKernel = 0;
m_newContactReductionKernel=0;
m_clipFacesAndContactReductionKernel = 0;
m_clipHullHullConcaveConvexKernel = 0;
m_extractManifoldAndAddContactKernel = 0;
}
}
GpuSatCollision::~GpuSatCollision()
{
if (m_findSeparatingAxisKernel)
clReleaseKernel(m_findSeparatingAxisKernel);
if (m_findCompoundPairsKernel)
clReleaseKernel(m_findCompoundPairsKernel);
if (m_processCompoundPairsKernel)
clReleaseKernel(m_processCompoundPairsKernel);
if (m_findClippingFacesKernel)
clReleaseKernel(m_findClippingFacesKernel);
if (m_clipFacesAndContactReductionKernel)
clReleaseKernel(m_clipFacesAndContactReductionKernel);
if (m_newContactReductionKernel)
clReleaseKernel(m_newContactReductionKernel);
if (m_clipHullHullKernel)
clReleaseKernel(m_clipHullHullKernel);
if (m_clipCompoundsHullHullKernel)
clReleaseKernel(m_clipCompoundsHullHullKernel);
if (m_clipHullHullConcaveConvexKernel)
clReleaseKernel(m_clipHullHullConcaveConvexKernel);
if (m_extractManifoldAndAddContactKernel)
clReleaseKernel(m_extractManifoldAndAddContactKernel);
}
void GpuSatCollision::computeConvexConvexContactsGPUSAT( const btOpenCLArray<btInt2>* pairs, int nPairs,
const btOpenCLArray<btRigidBodyCL>* bodyBuf,
btOpenCLArray<btContact4>* contactOut, int& nContacts,
const btOpenCLArray<btConvexPolyhedronCL>& convexData,
const btOpenCLArray<btVector3>& gpuVertices,
const btOpenCLArray<btVector3>& gpuUniqueEdges,
const btOpenCLArray<btGpuFace>& gpuFaces,
const btOpenCLArray<int>& gpuIndices,
const btOpenCLArray<btCollidable>& gpuCollidables,
const btOpenCLArray<btGpuChildShape>& gpuChildShapes,
const btOpenCLArray<btYetAnotherAabb>& clAabbs,
btOpenCLArray<btVector3>& worldVertsB1GPU,
btOpenCLArray<btInt4>& clippingFacesOutGPU,
btOpenCLArray<btVector3>& worldNormalsAGPU,
btOpenCLArray<btVector3>& worldVertsA1GPU,
btOpenCLArray<btVector3>& worldVertsB2GPU,
int numObjects,
int maxTriConvexPairCapacity,
btOpenCLArray<btInt4>& triangleConvexPairsOut,
int& numTriConvexPairsOut
)
{
if (!nPairs)
return;
BT_PROFILE("computeConvexConvexContactsGPUSAT");
// printf("nContacts = %d\n",nContacts);
btOpenCLArray<btVector3> sepNormals(m_context,m_queue);
sepNormals.resize(nPairs);
btOpenCLArray<int> hasSeparatingNormals(m_context,m_queue);
hasSeparatingNormals.resize(nPairs);
int concaveCapacity=maxTriConvexPairCapacity;
btOpenCLArray<btVector3> concaveSepNormals(m_context,m_queue);
concaveSepNormals.resize(concaveCapacity);
btOpenCLArray<int> numConcavePairsOut(m_context,m_queue);
numConcavePairsOut.push_back(0);
int compoundPairCapacity=65536*10;
btOpenCLArray<btCompoundOverlappingPair> gpuCompoundPairs(m_context,m_queue);
gpuCompoundPairs.resize(compoundPairCapacity);
btOpenCLArray<btVector3> gpuCompoundSepNormals(m_context,m_queue);
gpuCompoundSepNormals.resize(compoundPairCapacity);
btOpenCLArray<int> gpuHasCompoundSepNormals(m_context,m_queue);
gpuHasCompoundSepNormals.resize(compoundPairCapacity);
btOpenCLArray<int> numCompoundPairsOut(m_context,m_queue);
numCompoundPairsOut.push_back(0);
int numCompoundPairs = 0;
bool findSeparatingAxisOnGpu = true;//false;
int numConcave =0;
{
clFinish(m_queue);
if (findSeparatingAxisOnGpu)
{
BT_PROFILE("findSeparatingAxisKernel");
btBufferInfoCL bInfo[] = {
btBufferInfoCL( pairs->getBufferCL(), true ),
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( clAabbs.getBufferCL(),true),
btBufferInfoCL( sepNormals.getBufferCL()),
btBufferInfoCL( hasSeparatingNormals.getBufferCL()),
btBufferInfoCL( triangleConvexPairsOut.getBufferCL()),
btBufferInfoCL( concaveSepNormals.getBufferCL()),
btBufferInfoCL( numConcavePairsOut.getBufferCL())
};
btLauncherCL launcher(m_queue, m_findSeparatingAxisKernel);
launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) );
launcher.setConst( nPairs );
launcher.setConst( maxTriConvexPairCapacity);
int num = nPairs;
launcher.launch1D( num);
clFinish(m_queue);
numConcave = numConcavePairsOut.at(0);
if (numConcave > maxTriConvexPairCapacity)
numConcave = maxTriConvexPairCapacity;
triangleConvexPairsOut.resize(numConcave);
{
BT_PROFILE("findCompoundPairsKernel");
btBufferInfoCL bInfo[] =
{
btBufferInfoCL( pairs->getBufferCL(), true ),
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( clAabbs.getBufferCL(),true),
btBufferInfoCL( gpuChildShapes.getBufferCL(),true),
btBufferInfoCL( gpuCompoundPairs.getBufferCL()),
btBufferInfoCL( numCompoundPairsOut.getBufferCL())
};
btLauncherCL launcher(m_queue, m_findCompoundPairsKernel);
launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) );
launcher.setConst( nPairs );
launcher.setConst( compoundPairCapacity);
int num = nPairs;
launcher.launch1D( num);
clFinish(m_queue);
}
numCompoundPairs = numCompoundPairsOut.at(0);
//printf("numCompoundPairs =%d\n",numCompoundPairs );
if (numCompoundPairs > compoundPairCapacity)
numCompoundPairs = compoundPairCapacity;
gpuCompoundPairs.resize(numCompoundPairs);
gpuHasCompoundSepNormals.resize(numCompoundPairs);
gpuCompoundSepNormals.resize(numCompoundPairs);
if (numCompoundPairs)
{
BT_PROFILE("processCompoundPairsKernel");
btBufferInfoCL bInfo[] =
{
btBufferInfoCL( gpuCompoundPairs.getBufferCL(), true ),
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( clAabbs.getBufferCL(),true),
btBufferInfoCL( gpuChildShapes.getBufferCL(),true),
btBufferInfoCL( gpuCompoundSepNormals.getBufferCL()),
btBufferInfoCL( gpuHasCompoundSepNormals.getBufferCL())
};
btLauncherCL launcher(m_queue, m_processCompoundPairsKernel);
launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) );
launcher.setConst( numCompoundPairs );
int num = numCompoundPairs;
launcher.launch1D( num);
clFinish(m_queue);
}
//printf("numConcave = %d\n",numConcave);
}//if (findSeparatingAxisOnGpu)
// printf("hostNormals.size()=%d\n",hostNormals.size());
//int numPairs = pairCount.at(0);
}
#ifdef __APPLE__
bool contactClippingOnGpu = true;
#else
bool contactClippingOnGpu = true;
#endif
if (contactClippingOnGpu)
{
//BT_PROFILE("clipHullHullKernel");
m_totalContactsOut.copyFromHostPointer(&nContacts,1,0,true);
//concave-convex contact clipping
if (numConcave)
{
BT_PROFILE("clipHullHullConcaveConvexKernel");
nContacts = m_totalContactsOut.at(0);
btBufferInfoCL bInfo[] = {
btBufferInfoCL( triangleConvexPairsOut.getBufferCL(), true ),
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( concaveSepNormals.getBufferCL()),
btBufferInfoCL( contactOut->getBufferCL()),
btBufferInfoCL( m_totalContactsOut.getBufferCL())
};
btLauncherCL launcher(m_queue, m_clipHullHullConcaveConvexKernel);
launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) );
launcher.setConst( numConcave );
int num = numConcave;
launcher.launch1D( num);
clFinish(m_queue);
nContacts = m_totalContactsOut.at(0);
}
//convex-convex contact clipping
if (1)
{
BT_PROFILE("clipHullHullKernel");
bool breakupKernel = false;
#ifdef __APPLE__
breakupKernel = true;
#endif
if (breakupKernel)
{
int vertexFaceCapacity = 64;
worldVertsB1GPU.resize(vertexFaceCapacity*nPairs);
clippingFacesOutGPU.resize(nPairs);
worldNormalsAGPU.resize(nPairs);
worldVertsA1GPU.resize(vertexFaceCapacity*nPairs);
worldVertsB2GPU.resize(vertexFaceCapacity*nPairs);
{
BT_PROFILE("findClippingFacesKernel");
btBufferInfoCL bInfo[] = {
btBufferInfoCL( pairs->getBufferCL(), true ),
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( sepNormals.getBufferCL()),
btBufferInfoCL( hasSeparatingNormals.getBufferCL()),
btBufferInfoCL( clippingFacesOutGPU.getBufferCL()),
btBufferInfoCL( worldVertsA1GPU.getBufferCL()),
btBufferInfoCL( worldNormalsAGPU.getBufferCL()),
btBufferInfoCL( worldVertsB1GPU.getBufferCL())
};
btLauncherCL launcher(m_queue, m_findClippingFacesKernel);
launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) );
launcher.setConst( vertexFaceCapacity);
launcher.setConst( nPairs );
int num = nPairs;
launcher.launch1D( num);
clFinish(m_queue);
}
///clip face B against face A, reduce contacts and append them to a global contact array
if (1)
{
BT_PROFILE("clipFacesAndContactReductionKernel");
//nContacts = m_totalContactsOut.at(0);
//int h = hasSeparatingNormals.at(0);
//int4 p = clippingFacesOutGPU.at(0);
btBufferInfoCL bInfo[] = {
btBufferInfoCL( pairs->getBufferCL(), true ),
btBufferInfoCL( bodyBuf->getBufferCL(),true),
btBufferInfoCL( sepNormals.getBufferCL()),
btBufferInfoCL( hasSeparatingNormals.getBufferCL()),
btBufferInfoCL( contactOut->getBufferCL()),
btBufferInfoCL( clippingFacesOutGPU.getBufferCL()),
btBufferInfoCL( worldVertsA1GPU.getBufferCL()),
btBufferInfoCL( worldNormalsAGPU.getBufferCL()),
btBufferInfoCL( worldVertsB1GPU.getBufferCL()),
btBufferInfoCL( worldVertsB2GPU.getBufferCL()),
btBufferInfoCL( m_totalContactsOut.getBufferCL())
};
btLauncherCL launcher(m_queue, m_clipFacesAndContactReductionKernel);
launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) );
launcher.setConst(vertexFaceCapacity);
launcher.setConst( nPairs );
int debugMode = 0;
launcher.setConst( debugMode);
/*
int serializationBytes = launcher.getSerializationBufferSize();
unsigned char* buf = (unsigned char*)malloc(serializationBytes+1);
int actualWritten = launcher.serializeArguments(buf,serializationBytes+1);
FILE* f = fopen("clipFacesAndContactReductionKernel.bin","wb");
fwrite(buf,actualWritten,1,f);
fclose(f);
free(buf);
printf("serializationBytes=%d, actualWritten=%d\n",serializationBytes,actualWritten);
*/
int num = nPairs;
launcher.launch1D( num);
clFinish(m_queue);
{
// nContacts = m_totalContactsOut.at(0);
// printf("nContacts = %d\n",nContacts);
contactOut->reserve(nContacts+nPairs);
{
BT_PROFILE("newContactReductionKernel");
btBufferInfoCL bInfo[] =
{
btBufferInfoCL( pairs->getBufferCL(), true ),
btBufferInfoCL( bodyBuf->getBufferCL(),true),
btBufferInfoCL( sepNormals.getBufferCL()),
btBufferInfoCL( hasSeparatingNormals.getBufferCL()),
btBufferInfoCL( contactOut->getBufferCL()),
btBufferInfoCL( clippingFacesOutGPU.getBufferCL()),
btBufferInfoCL( worldVertsB2GPU.getBufferCL()),
btBufferInfoCL( m_totalContactsOut.getBufferCL())
};
btLauncherCL launcher(m_queue, m_newContactReductionKernel);
launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) );
launcher.setConst(vertexFaceCapacity);
launcher.setConst( nPairs );
int num = nPairs;
launcher.launch1D( num);
}
nContacts = m_totalContactsOut.at(0);
contactOut->resize(nContacts);
// Contact4 pt = contactOut->at(0);
// printf("nContacts = %d\n",nContacts);
}
}
}
else
{
if (nPairs)
{
btBufferInfoCL bInfo[] = {
btBufferInfoCL( pairs->getBufferCL(), true ),
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( sepNormals.getBufferCL()),
btBufferInfoCL( hasSeparatingNormals.getBufferCL()),
btBufferInfoCL( contactOut->getBufferCL()),
btBufferInfoCL( m_totalContactsOut.getBufferCL())
};
btLauncherCL launcher(m_queue, m_clipHullHullKernel);
launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) );
launcher.setConst( nPairs );
int num = nPairs;
launcher.launch1D( num);
clFinish(m_queue);
nContacts = m_totalContactsOut.at(0);
contactOut->resize(nContacts);
}
int nCompoundsPairs = gpuCompoundPairs.size();
if (nCompoundsPairs)
{
btBufferInfoCL bInfo[] = {
btBufferInfoCL( gpuCompoundPairs.getBufferCL(), true ),
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( gpuChildShapes.getBufferCL(),true),
btBufferInfoCL( gpuCompoundSepNormals.getBufferCL(),true),
btBufferInfoCL( gpuHasCompoundSepNormals.getBufferCL(),true),
btBufferInfoCL( contactOut->getBufferCL()),
btBufferInfoCL( m_totalContactsOut.getBufferCL())
};
btLauncherCL launcher(m_queue, m_clipCompoundsHullHullKernel);
launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) );
launcher.setConst( nCompoundsPairs );
int num = nCompoundsPairs;
launcher.launch1D( num);
clFinish(m_queue);
nContacts = m_totalContactsOut.at(0);
contactOut->resize(nContacts);
}
}
}
}
}

View File

@@ -0,0 +1,85 @@
#ifndef _CONVEX_HULL_CONTACT_H
#define _CONVEX_HULL_CONTACT_H
#include "parallel_primitives/host/btOpenCLArray.h"
#include "btRigidBodyCL.h"
#include "parallel_primitives/host/btAlignedObjectArray.h"
#include "btConvexUtility.h"
#include "btConvexPolyhedronCL.h"
#include "btCollidable.h"
#include "btContact4.h"
#include "parallel_primitives/host/btInt2.h"
#include "parallel_primitives/host/btInt4.h"
//#include "../../dynamics/basic_demo/Stubs/ChNarrowPhase.h"
struct btYetAnotherAabb
{
union
{
float m_min[4];
int m_minIndices[4];
};
union
{
float m_max[4];
//int m_signedMaxIndices[4];
//unsigned int m_unsignedMaxIndices[4];
};
};
struct GpuSatCollision
{
cl_context m_context;
cl_device_id m_device;
cl_command_queue m_queue;
cl_kernel m_findSeparatingAxisKernel;
cl_kernel m_findCompoundPairsKernel;
cl_kernel m_processCompoundPairsKernel;
cl_kernel m_clipHullHullKernel;
cl_kernel m_clipCompoundsHullHullKernel;
cl_kernel m_clipFacesAndContactReductionKernel;
cl_kernel m_findClippingFacesKernel;
cl_kernel m_clipHullHullConcaveConvexKernel;
cl_kernel m_extractManifoldAndAddContactKernel;
cl_kernel m_newContactReductionKernel;
btOpenCLArray<int> m_totalContactsOut;
GpuSatCollision(cl_context ctx,cl_device_id device, cl_command_queue q );
virtual ~GpuSatCollision();
void computeConvexConvexContactsGPUSAT( const btOpenCLArray<btInt2>* pairs, int nPairs,
const btOpenCLArray<btRigidBodyCL>* bodyBuf,
btOpenCLArray<btContact4>* contactOut, int& nContacts,
const btOpenCLArray<btConvexPolyhedronCL>& hostConvexData,
const btOpenCLArray<btVector3>& vertices,
const btOpenCLArray<btVector3>& uniqueEdges,
const btOpenCLArray<btGpuFace>& faces,
const btOpenCLArray<int>& indices,
const btOpenCLArray<btCollidable>& gpuCollidables,
const btOpenCLArray<btGpuChildShape>& gpuChildShapes,
const btOpenCLArray<btYetAnotherAabb>& clAabbs,
btOpenCLArray<btVector3>& worldVertsB1GPU,
btOpenCLArray<btInt4>& clippingFacesOutGPU,
btOpenCLArray<btVector3>& worldNormalsAGPU,
btOpenCLArray<btVector3>& worldVertsA1GPU,
btOpenCLArray<btVector3>& worldVertsB2GPU,
int numObjects,
int maxTriConvexPairCapacity,
btOpenCLArray<btInt4>& triangleConvexPairs,
int& numTriConvexPairsOut
);
};
#endif //_CONVEX_HULL_CONTACT_H

View File

@@ -0,0 +1,38 @@
#ifndef BT_COLLIDABLE_H
#define BT_COLLIDABLE_H
struct btCollidable
{
int m_numChildShapes;
float m_radius;
int m_shapeType;
int m_shapeIndex;
};
struct btCollidableNew
{
short int m_shapeType;
short int m_numShapes;
int m_shapeIndex;
};
struct btGpuChildShape
{
float m_childPosition[4];
float m_childOrientation[4];
int m_shapeIndex;
int m_unused0;
int m_unused1;
int m_unused2;
};
struct btCompoundOverlappingPair
{
int m_bodyIndexA;
int m_bodyIndexB;
// int m_pairType;
int m_childShapeIndexA;
int m_childShapeIndexB;
};
#endif //BT_COLLIDABLE_H

View File

@@ -0,0 +1,42 @@
#ifndef BT_CONTACT4_H
#define BT_CONTACT4_H
#include "parallel_primitives/host/btVector3.h"
ATTRIBUTE_ALIGNED16(struct) btContact4
{
BT_DECLARE_ALIGNED_ALLOCATOR();
btVector3 m_worldPos[4];
btVector3 m_worldNormal;
// float m_restituitionCoeff;
// float m_frictionCoeff;
unsigned short m_restituitionCoeffCmp;
unsigned short m_frictionCoeffCmp;
int m_batchIdx;
int m_bodyAPtrAndSignBit;
int m_bodyBPtrAndSignBit;
int getBodyA()const {return abs(m_bodyAPtrAndSignBit);}
int getBodyB()const {return abs(m_bodyBPtrAndSignBit);}
bool isBodyAFixed()const { return m_bodyAPtrAndSignBit<0;}
bool isBodyBFixed()const { return m_bodyBPtrAndSignBit<0;}
// todo. make it safer
int& getBatchIdx() { return m_batchIdx; }
const int& getBatchIdx() const { return m_batchIdx; }
float getRestituitionCoeff() const { return ((float)m_restituitionCoeffCmp/(float)0xffff); }
void setRestituitionCoeff( float c ) { btAssert( c >= 0.f && c <= 1.f ); m_restituitionCoeffCmp = (unsigned short)(c*0xffff); }
float getFrictionCoeff() const { return ((float)m_frictionCoeffCmp/(float)0xffff); }
void setFrictionCoeff( float c ) { btAssert( c >= 0.f && c <= 1.f ); m_frictionCoeffCmp = (unsigned short)(c*0xffff); }
float& getNPoints() { return m_worldNormal[3]; }
float getNPoints() const { return m_worldNormal[3]; }
float getPenetration(int idx) const { return m_worldPos[idx][3]; }
bool isInvalid() const { return (getBodyA()==0 || getBodyB()==0); }
};
#endif //BT_CONTACT4_H

View File

@@ -0,0 +1,64 @@
#ifndef CONVEX_POLYHEDRON_CL
#define CONVEX_POLYHEDRON_CL
#include "parallel_primitives/host/btTransform.h"
struct btGpuFace
{
btVector4 m_plane;
int m_indexOffset;
int m_numIndices;
};
ATTRIBUTE_ALIGNED16(struct) btConvexPolyhedronCL
{
btVector3 m_localCenter;
btVector3 m_extents;
btVector3 mC;
btVector3 mE;
btScalar m_radius;
int m_faceOffset;
int m_numFaces;
int m_numVertices;
int m_vertexOffset;
int m_uniqueEdgesOffset;
int m_numUniqueEdges;
int m_unused;
inline void project(const btTransform& trans, const btVector3& dir, const btAlignedObjectArray<btVector3>& vertices, btScalar& min, btScalar& max) const
{
min = FLT_MAX;
max = -FLT_MAX;
int numVerts = m_numVertices;
const btVector3 localDir = trans.getBasis().transpose()*dir;
const btVector3 localDi2 = quatRotate(trans.getRotation().inverse(),dir);
btScalar offset = trans.getOrigin().dot(dir);
for(int i=0;i<numVerts;i++)
{
//btVector3 pt = trans * vertices[m_vertexOffset+i];
//btScalar dp = pt.dot(dir);
btScalar dp = vertices[m_vertexOffset+i].dot(localDir);
//btAssert(dp==dpL);
if(dp < min) min = dp;
if(dp > max) max = dp;
}
if(min>max)
{
btScalar tmp = min;
min = max;
max = tmp;
}
min += offset;
max += offset;
}
};
#endif //CONVEX_POLYHEDRON_CL

View File

@@ -0,0 +1,513 @@
/*
Copyright (c) 2012 Advanced Micro Devices, Inc.
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
//Originally written by Erwin Coumans
#include "btConvexUtility.h"
#include "LinearMath/btConvexHullComputer.h"
#include "LinearMath/btGrahamScan2dConvexHull.h"
#include "LinearMath/btQuaternion.h"
#include "LinearMath/btHashMap.h"
#include "../gpu_rigidbody_pipeline2/ConvexPolyhedronCL.h"
btConvexUtility::~btConvexUtility()
{
}
bool btConvexUtility::initializePolyhedralFeatures(const btVector3* orgVertices, int numPoints, bool mergeCoplanarTriangles)
{
btConvexHullComputer conv;
conv.compute(&orgVertices[0].getX(), sizeof(btVector3),numPoints,0.f,0.f);
btAlignedObjectArray<btVector3> faceNormals;
int numFaces = conv.faces.size();
faceNormals.resize(numFaces);
btConvexHullComputer* convexUtil = &conv;
btAlignedObjectArray<btMyFace> tmpFaces;
tmpFaces.resize(numFaces);
int numVertices = convexUtil->vertices.size();
m_vertices.resize(numVertices);
for (int p=0;p<numVertices;p++)
{
m_vertices[p] = convexUtil->vertices[p];
}
for (int i=0;i<numFaces;i++)
{
int face = convexUtil->faces[i];
//printf("face=%d\n",face);
const btConvexHullComputer::Edge* firstEdge = &convexUtil->edges[face];
const btConvexHullComputer::Edge* edge = firstEdge;
btVector3 edges[3];
int numEdges = 0;
//compute face normals
do
{
int src = edge->getSourceVertex();
tmpFaces[i].m_indices.push_back(src);
int targ = edge->getTargetVertex();
btVector3 wa = convexUtil->vertices[src];
btVector3 wb = convexUtil->vertices[targ];
btVector3 newEdge = wb-wa;
newEdge.normalize();
if (numEdges<2)
edges[numEdges++] = newEdge;
edge = edge->getNextEdgeOfFace();
} while (edge!=firstEdge);
btScalar planeEq = 1e30f;
if (numEdges==2)
{
faceNormals[i] = edges[0].cross(edges[1]);
faceNormals[i].normalize();
tmpFaces[i].m_plane[0] = faceNormals[i].getX();
tmpFaces[i].m_plane[1] = faceNormals[i].getY();
tmpFaces[i].m_plane[2] = faceNormals[i].getZ();
tmpFaces[i].m_plane[3] = planeEq;
}
else
{
btAssert(0);//degenerate?
faceNormals[i].setZero();
}
for (int v=0;v<tmpFaces[i].m_indices.size();v++)
{
btScalar eq = m_vertices[tmpFaces[i].m_indices[v]].dot(faceNormals[i]);
if (planeEq>eq)
{
planeEq=eq;
}
}
tmpFaces[i].m_plane[3] = -planeEq;
}
//merge coplanar faces and copy them to m_polyhedron
btScalar faceWeldThreshold= 0.999f;
btAlignedObjectArray<int> todoFaces;
for (int i=0;i<tmpFaces.size();i++)
todoFaces.push_back(i);
while (todoFaces.size())
{
btAlignedObjectArray<int> coplanarFaceGroup;
int refFace = todoFaces[todoFaces.size()-1];
coplanarFaceGroup.push_back(refFace);
btMyFace& faceA = tmpFaces[refFace];
todoFaces.pop_back();
btVector3 faceNormalA(faceA.m_plane[0],faceA.m_plane[1],faceA.m_plane[2]);
for (int j=todoFaces.size()-1;j>=0;j--)
{
int i = todoFaces[j];
btMyFace& faceB = tmpFaces[i];
btVector3 faceNormalB(faceB.m_plane[0],faceB.m_plane[1],faceB.m_plane[2]);
if (faceNormalA.dot(faceNormalB)>faceWeldThreshold)
{
coplanarFaceGroup.push_back(i);
todoFaces.remove(i);
}
}
bool did_merge = false;
if (coplanarFaceGroup.size()>1)
{
//do the merge: use Graham Scan 2d convex hull
btAlignedObjectArray<GrahamVector3> orgpoints;
btVector3 averageFaceNormal(0,0,0);
for (int i=0;i<coplanarFaceGroup.size();i++)
{
// m_polyhedron->m_faces.push_back(tmpFaces[coplanarFaceGroup[i]]);
btMyFace& face = tmpFaces[coplanarFaceGroup[i]];
btVector3 faceNormal(face.m_plane[0],face.m_plane[1],face.m_plane[2]);
averageFaceNormal+=faceNormal;
for (int f=0;f<face.m_indices.size();f++)
{
int orgIndex = face.m_indices[f];
btVector3 pt = m_vertices[orgIndex];
bool found = false;
for (int i=0;i<orgpoints.size();i++)
{
//if ((orgpoints[i].m_orgIndex == orgIndex) || ((rotatedPt-orgpoints[i]).length2()<0.0001))
if (orgpoints[i].m_orgIndex == orgIndex)
{
found=true;
break;
}
}
if (!found)
orgpoints.push_back(GrahamVector3(pt,orgIndex));
}
}
btMyFace combinedFace;
for (int i=0;i<4;i++)
combinedFace.m_plane[i] = tmpFaces[coplanarFaceGroup[0]].m_plane[i];
btAlignedObjectArray<GrahamVector3> hull;
averageFaceNormal.normalize();
GrahamScanConvexHull2D(orgpoints,hull,averageFaceNormal);
for (int i=0;i<hull.size();i++)
{
combinedFace.m_indices.push_back(hull[i].m_orgIndex);
for(int k = 0; k < orgpoints.size(); k++)
{
if(orgpoints[k].m_orgIndex == hull[i].m_orgIndex)
{
orgpoints[k].m_orgIndex = -1; // invalidate...
break;
}
}
}
// are there rejected vertices?
bool reject_merge = false;
for(int i = 0; i < orgpoints.size(); i++) {
if(orgpoints[i].m_orgIndex == -1)
continue; // this is in the hull...
// this vertex is rejected -- is anybody else using this vertex?
for(int j = 0; j < tmpFaces.size(); j++) {
btMyFace& face = tmpFaces[j];
// is this a face of the current coplanar group?
bool is_in_current_group = false;
for(int k = 0; k < coplanarFaceGroup.size(); k++) {
if(coplanarFaceGroup[k] == j) {
is_in_current_group = true;
break;
}
}
if(is_in_current_group) // ignore this face...
continue;
// does this face use this rejected vertex?
for(int v = 0; v < face.m_indices.size(); v++) {
if(face.m_indices[v] == orgpoints[i].m_orgIndex) {
// this rejected vertex is used in another face -- reject merge
reject_merge = true;
break;
}
}
if(reject_merge)
break;
}
if(reject_merge)
break;
}
if (!reject_merge)
{
// do this merge!
did_merge = true;
m_faces.push_back(combinedFace);
}
}
if(!did_merge)
{
for (int i=0;i<coplanarFaceGroup.size();i++)
{
btMyFace face = tmpFaces[coplanarFaceGroup[i]];
m_faces.push_back(face);
}
}
}
initialize();
return true;
}
inline bool IsAlmostZero(const btVector3& v)
{
if(fabsf(v.x())>1e-6 || fabsf(v.y())>1e-6 || fabsf(v.z())>1e-6) return false;
return true;
}
struct btInternalVertexPair
{
btInternalVertexPair(short int v0,short int v1)
:m_v0(v0),
m_v1(v1)
{
if (m_v1>m_v0)
btSwap(m_v0,m_v1);
}
short int m_v0;
short int m_v1;
int getHash() const
{
return m_v0+(m_v1<<16);
}
bool equals(const btInternalVertexPair& other) const
{
return m_v0==other.m_v0 && m_v1==other.m_v1;
}
};
struct btInternalEdge
{
btInternalEdge()
:m_face0(-1),
m_face1(-1)
{
}
short int m_face0;
short int m_face1;
};
//
#ifdef TEST_INTERNAL_OBJECTS
bool btConvexUtility::testContainment() const
{
for(int p=0;p<8;p++)
{
btVector3 LocalPt;
if(p==0) LocalPt = m_localCenter + btVector3(m_extents[0], m_extents[1], m_extents[2]);
else if(p==1) LocalPt = m_localCenter + btVector3(m_extents[0], m_extents[1], -m_extents[2]);
else if(p==2) LocalPt = m_localCenter + btVector3(m_extents[0], -m_extents[1], m_extents[2]);
else if(p==3) LocalPt = m_localCenter + btVector3(m_extents[0], -m_extents[1], -m_extents[2]);
else if(p==4) LocalPt = m_localCenter + btVector3(-m_extents[0], m_extents[1], m_extents[2]);
else if(p==5) LocalPt = m_localCenter + btVector3(-m_extents[0], m_extents[1], -m_extents[2]);
else if(p==6) LocalPt = m_localCenter + btVector3(-m_extents[0], -m_extents[1], m_extents[2]);
else if(p==7) LocalPt = m_localCenter + btVector3(-m_extents[0], -m_extents[1], -m_extents[2]);
for(int i=0;i<m_faces.size();i++)
{
const btVector3 Normal(m_faces[i].m_plane[0], m_faces[i].m_plane[1], m_faces[i].m_plane[2]);
const btScalar d = LocalPt.dot(Normal) + m_faces[i].m_plane[3];
if(d>0.0f)
return false;
}
}
return true;
}
#endif
void btConvexUtility::initialize()
{
btHashMap<btInternalVertexPair,btInternalEdge> edges;
btScalar TotalArea = 0.0f;
m_localCenter.setValue(0, 0, 0);
for(int i=0;i<m_faces.size();i++)
{
int numVertices = m_faces[i].m_indices.size();
int NbTris = numVertices;
for(int j=0;j<NbTris;j++)
{
int k = (j+1)%numVertices;
btInternalVertexPair vp(m_faces[i].m_indices[j],m_faces[i].m_indices[k]);
btInternalEdge* edptr = edges.find(vp);
btVector3 edge = m_vertices[vp.m_v1]-m_vertices[vp.m_v0];
edge.normalize();
bool found = false;
for (int p=0;p<m_uniqueEdges.size();p++)
{
if (IsAlmostZero(m_uniqueEdges[p]-edge) ||
IsAlmostZero(m_uniqueEdges[p]+edge))
{
found = true;
break;
}
}
if (!found)
{
m_uniqueEdges.push_back(edge);
}
if (edptr)
{
btAssert(edptr->m_face0>=0);
btAssert(edptr->m_face1<0);
edptr->m_face1 = i;
} else
{
btInternalEdge ed;
ed.m_face0 = i;
edges.insert(vp,ed);
}
}
}
#ifdef USE_CONNECTED_FACES
for(int i=0;i<m_faces.size();i++)
{
int numVertices = m_faces[i].m_indices.size();
m_faces[i].m_connectedFaces.resize(numVertices);
for(int j=0;j<numVertices;j++)
{
int k = (j+1)%numVertices;
btInternalVertexPair vp(m_faces[i].m_indices[j],m_faces[i].m_indices[k]);
btInternalEdge* edptr = edges.find(vp);
btAssert(edptr);
btAssert(edptr->m_face0>=0);
btAssert(edptr->m_face1>=0);
int connectedFace = (edptr->m_face0==i)?edptr->m_face1:edptr->m_face0;
m_faces[i].m_connectedFaces[j] = connectedFace;
}
}
#endif//USE_CONNECTED_FACES
for(int i=0;i<m_faces.size();i++)
{
int numVertices = m_faces[i].m_indices.size();
int NbTris = numVertices-2;
const btVector3& p0 = m_vertices[m_faces[i].m_indices[0]];
for(int j=1;j<=NbTris;j++)
{
int k = (j+1)%numVertices;
const btVector3& p1 = m_vertices[m_faces[i].m_indices[j]];
const btVector3& p2 = m_vertices[m_faces[i].m_indices[k]];
btScalar Area = ((p0 - p1).cross(p0 - p2)).length() * 0.5f;
btVector3 Center = (p0+p1+p2)/3.0f;
m_localCenter += Area * Center;
TotalArea += Area;
}
}
m_localCenter /= TotalArea;
#ifdef TEST_INTERNAL_OBJECTS
if(1)
{
m_radius = FLT_MAX;
for(int i=0;i<m_faces.size();i++)
{
const btVector3 Normal(m_faces[i].m_plane[0], m_faces[i].m_plane[1], m_faces[i].m_plane[2]);
const btScalar dist = btFabs(m_localCenter.dot(Normal) + m_faces[i].m_plane[3]);
if(dist<m_radius)
m_radius = dist;
}
btScalar MinX = FLT_MAX;
btScalar MinY = FLT_MAX;
btScalar MinZ = FLT_MAX;
btScalar MaxX = -FLT_MAX;
btScalar MaxY = -FLT_MAX;
btScalar MaxZ = -FLT_MAX;
for(int i=0; i<m_vertices.size(); i++)
{
const btVector3& pt = m_vertices[i];
if(pt.x()<MinX) MinX = pt.x();
if(pt.x()>MaxX) MaxX = pt.x();
if(pt.y()<MinY) MinY = pt.y();
if(pt.y()>MaxY) MaxY = pt.y();
if(pt.z()<MinZ) MinZ = pt.z();
if(pt.z()>MaxZ) MaxZ = pt.z();
}
mC.setValue(MaxX+MinX, MaxY+MinY, MaxZ+MinZ);
mE.setValue(MaxX-MinX, MaxY-MinY, MaxZ-MinZ);
// const btScalar r = m_radius / sqrtf(2.0f);
const btScalar r = m_radius / sqrtf(3.0f);
const int LargestExtent = mE.maxAxis();
const btScalar Step = (mE[LargestExtent]*0.5f - r)/1024.0f;
m_extents[0] = m_extents[1] = m_extents[2] = r;
m_extents[LargestExtent] = mE[LargestExtent]*0.5f;
bool FoundBox = false;
for(int j=0;j<1024;j++)
{
if(testContainment())
{
FoundBox = true;
break;
}
m_extents[LargestExtent] -= Step;
}
if(!FoundBox)
{
m_extents[0] = m_extents[1] = m_extents[2] = r;
}
else
{
// Refine the box
const btScalar Step = (m_radius - r)/1024.0f;
const int e0 = (1<<LargestExtent) & 3;
const int e1 = (1<<e0) & 3;
for(int j=0;j<1024;j++)
{
const btScalar Saved0 = m_extents[e0];
const btScalar Saved1 = m_extents[e1];
m_extents[e0] += Step;
m_extents[e1] += Step;
if(!testContainment())
{
m_extents[e0] = Saved0;
m_extents[e1] = Saved1;
break;
}
}
}
}
#endif
}

View File

@@ -0,0 +1,62 @@
/*
Copyright (c) 2012 Advanced Micro Devices, Inc.
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
//Originally written by Erwin Coumans
#ifndef _BT_CONVEX_UTILITY_H
#define _BT_CONVEX_UTILITY_H
#include "parallel_primitives/host/btAlignedObjectArray.h"
#include "parallel_primitives/host/btTransform.h"
#include "btConvexPolyhedronCL.h"
struct btMyFace
{
btAlignedObjectArray<int> m_indices;
btScalar m_plane[4];
};
ATTRIBUTE_ALIGNED16(class) btConvexUtility
{
public:
BT_DECLARE_ALIGNED_ALLOCATOR();
btVector3 m_localCenter;
btVector3 m_extents;
btVector3 mC;
btVector3 mE;
btScalar m_radius;
btAlignedObjectArray<btVector3> m_vertices;
btAlignedObjectArray<btMyFace> m_faces;
btAlignedObjectArray<btVector3> m_uniqueEdges;
btConvexUtility()
{
}
virtual ~btConvexUtility();
bool initializePolyhedralFeatures(const btVector3* orgVertices, int numVertices, bool mergeCoplanarTriangles=true);
void initialize();
bool testContainment() const;
};
#endif

View File

@@ -0,0 +1,35 @@
#ifndef BT_RIGID_BODY_CL
#define BT_RIGID_BODY_CL
#include "parallel_primitives/host/btScalar.h"
#include "parallel_primitives/host/btMatrix3x3.h"
ATTRIBUTE_ALIGNED16(struct) btRigidBodyCL
{
BT_DECLARE_ALIGNED_ALLOCATOR();
btVector3 m_pos;
btQuaternion m_quat;
btVector3 m_linVel;
btVector3 m_angVel;
int m_collidableIdx;
float m_invMass;
float m_restituitionCoeff;
float m_frictionCoeff;
float getInvMass() const
{
return m_invMass;
}
};
struct Inertia
{
btMatrix3x3 m_invInertiaWorld;
btMatrix3x3 m_initInvInertia;
};
#endif//BT_RIGID_BODY_CL

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,112 @@
/*
Copyright (c) 2012 Advanced Micro Devices, Inc.
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include <stdio.h>
#include "../basic_initialize/btOpenCLUtils.h"
#include "../host/ConvexHullContact.h"
#include "parallel_primitives/host/btVector3.h"
#include "parallel_primitives/host/btFillCL.h"
#include "parallel_primitives/host/btBoundSearchCL.h"
#include "parallel_primitives/host/btRadixSort32CL.h"
#include "parallel_primitives/host/btPrefixScanCL.h"
#include "parallel_primitives/host/CommandLineArgs.h"
#include "../host/ConvexHullContact.h"
#include "parallel_primitives/host/btMinMax.h"
int g_nPassed = 0;
int g_nFailed = 0;
bool g_testFailed = 0;
#define TEST_INIT g_testFailed = 0;
#define TEST_ASSERT(x) if( !(x) ){g_testFailed = 1;}
#define TEST_REPORT(testName) printf("[%s] %s\n",(g_testFailed)?"X":"O", testName); if(g_testFailed) g_nFailed++; else g_nPassed++;
#define NEXTMULTIPLEOF(num, alignment) (((num)/(alignment) + (((num)%(alignment)==0)?0:1))*(alignment))
cl_context g_context=0;
cl_device_id g_device=0;
cl_command_queue g_queue =0;
const char* g_deviceName = 0;
void initCL(int preferredDeviceIndex, int preferredPlatformIndex)
{
void* glCtx=0;
void* glDC = 0;
int ciErrNum = 0;
//bound search and radix sort only work on GPU right now (assume 32 or 64 width workgroup without barriers)
cl_device_type deviceType = CL_DEVICE_TYPE_ALL;
g_context = btOpenCLUtils::createContextFromType(deviceType, &ciErrNum, 0,0,preferredDeviceIndex, preferredPlatformIndex);
oclCHECKERROR(ciErrNum, CL_SUCCESS);
int numDev = btOpenCLUtils::getNumDevices(g_context);
if (numDev>0)
{
btOpenCLDeviceInfo info;
g_device= btOpenCLUtils::getDevice(g_context,0);
g_queue = clCreateCommandQueue(g_context, g_device, 0, &ciErrNum);
oclCHECKERROR(ciErrNum, CL_SUCCESS);
btOpenCLUtils::printDeviceInfo(g_device);
btOpenCLUtils::getDeviceInfo(g_device,&info);
g_deviceName = info.m_deviceName;
}
}
void exitCL()
{
clReleaseCommandQueue(g_queue);
clReleaseContext(g_context);
}
inline void gpuConvexHullContactTest()
{
TEST_INIT;
TEST_ASSERT(1);
GpuSatCollision* sat = new GpuSatCollision(g_context,g_device,g_queue);
delete sat;
TEST_REPORT( "gpuConvexHullContactTest" );
}
int main(int argc, char** argv)
{
int preferredDeviceIndex = -1;
int preferredPlatformIndex = -1;
CommandLineArgs args(argc, argv);
args.GetCmdLineArgument("deviceId", preferredDeviceIndex);
args.GetCmdLineArgument("platformId", preferredPlatformIndex);
initCL(preferredDeviceIndex,preferredPlatformIndex);
gpuConvexHullContactTest();
printf("%d tests passed\n",g_nPassed, g_nFailed);
if (g_nFailed)
{
printf("%d tests failed\n",g_nFailed);
}
printf("End, press <enter>\n");
getchar();
exitCL();
}

View File

@@ -0,0 +1,46 @@
function createProject(vendor)
hasCL = findOpenCL(vendor)
if (hasCL) then
project ("OpenCL_sat_test_" .. vendor)
initOpenCL(vendor)
language "C++"
kind "ConsoleApp"
targetdir "../../../bin"
includedirs {"..","../.."}
files {
"main.cpp",
"../../basic_initialize/btOpenCLInclude.h",
"../../basic_initialize/btOpenCLUtils.cpp",
"../../basic_initialize/btOpenCLUtils.h",
"../host/ConvexHullContact.cpp",
"../host/ConvexHullContact.h",
"../../parallel_primitives/host/btFillCL.cpp",
"../../parallel_primitives/host/btFillCL.h",
"../../parallel_primitives/host/btBoundSearchCL.cpp",
"../../parallel_primitives/host/btBoundSearchCL.h",
"../../parallel_primitives/host/btPrefixScanCL.cpp",
"../../parallel_primitives/host/btPrefixScanCL.h",
"../../parallel_primitives/host/btRadixSort32CL.cpp",
"../../parallel_primitives/host/btRadixSort32CL.h",
"../../parallel_primitives/host/btAlignedAllocator.cpp",
"../../parallel_primitives/host/btAlignedAllocator.h",
"../../parallel_primitives/host/btAlignedObjectArray.h",
"../../parallel_primitives/host/btQuickprof.cpp",
"../../parallel_primitives/host/btQuickprof.h",
}
end
end
createProject("AMD")
createProject("Intel")
createProject("NVIDIA")
createProject("Apple")

View File

@@ -4,83 +4,9 @@
#include "btOpenCLArray.h"
#include "btScalar.h"
ATTRIBUTE_ALIGNED16(struct) btUnsignedInt4
{
BT_DECLARE_ALIGNED_ALLOCATOR();
#include "btInt2.h"
#include "btInt4.h"
union
{
struct
{
unsigned int x,y,z,w;
};
struct
{
unsigned int s[4];
};
};
};
ATTRIBUTE_ALIGNED16(struct) btInt4
{
BT_DECLARE_ALIGNED_ALLOCATOR();
union
{
struct
{
int x,y,z,w;
};
struct
{
int s[4];
};
};
};
struct btUnsignedInt2
{
union
{
struct
{
unsigned int x,y;
};
struct
{
unsigned int s[2];
};
};
};
struct btInt2
{
union
{
struct
{
int x,y;
};
struct
{
int s[2];
};
};
};
SIMD_FORCE_INLINE btInt4 btMakeInt4(int x, int y, int z, int w = 0)
{
btInt4 v;
v.s[0] = x; v.s[1] = y; v.s[2] = z; v.s[3] = w;
return v;
}
SIMD_FORCE_INLINE btUnsignedInt4 btMakeUnsignedInt4(unsigned int x, unsigned int y, unsigned int z, unsigned int w = 0)
{
btUnsignedInt4 v;
v.s[0] = x; v.s[1] = y; v.s[2] = z; v.s[3] = w;
return v;
}
class btFillCL
{

View File

@@ -0,0 +1,35 @@
#ifndef BT_INT2_H
#define BT_INT2_H
struct btUnsignedInt2
{
union
{
struct
{
unsigned int x,y;
};
struct
{
unsigned int s[2];
};
};
};
struct btInt2
{
union
{
struct
{
int x,y;
};
struct
{
int s[2];
};
};
};
#endif

View File

@@ -0,0 +1,55 @@
#ifndef BT_INT4_H
#define BT_INT4_H
#include "btScalar.h"
ATTRIBUTE_ALIGNED16(struct) btUnsignedInt4
{
BT_DECLARE_ALIGNED_ALLOCATOR();
union
{
struct
{
unsigned int x,y,z,w;
};
struct
{
unsigned int s[4];
};
};
};
ATTRIBUTE_ALIGNED16(struct) btInt4
{
BT_DECLARE_ALIGNED_ALLOCATOR();
union
{
struct
{
int x,y,z,w;
};
struct
{
int s[4];
};
};
};
SIMD_FORCE_INLINE btInt4 btMakeInt4(int x, int y, int z, int w = 0)
{
btInt4 v;
v.s[0] = x; v.s[1] = y; v.s[2] = z; v.s[3] = w;
return v;
}
SIMD_FORCE_INLINE btUnsignedInt4 btMakeUnsignedInt4(unsigned int x, unsigned int y, unsigned int z, unsigned int w = 0)
{
btUnsignedInt4 v;
v.s[0] = x; v.s[1] = y; v.s[2] = z; v.s[3] = w;
return v;
}
#endif //BT_INT4_H