PairBench.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792
  1. //those header files need to be at the top, because of conflict __global and STL
  2. #include "PairBench.h"
  3. #include "Bullet3Common/b3Quaternion.h"
  4. #include "Bullet3OpenCL/BroadphaseCollision/b3GpuSapBroadphase.h"
  5. #include "Bullet3OpenCL/BroadphaseCollision/b3GpuGridBroadphase.h"
  6. #include "Bullet3OpenCL/BroadphaseCollision/b3GpuParallelLinearBvhBroadphase.h"
  7. #include "../Utils/b3Clock.h"
  8. //#include "../GpuDemoInternalData.h"
  9. #include "Bullet3OpenCL/Initialize/b3OpenCLUtils.h"
  10. #include "Bullet3OpenCL/ParallelPrimitives/b3LauncherCL.h"
  11. #include "../OpenGLWindow/OpenGLInclude.h"
  12. #include "../OpenGLWindow/ShapeData.h"
  13. #include <string.h>
  14. #include "pairsKernel.h"
  15. extern int gPreferredOpenCLDeviceIndex;
  16. extern int gPreferredOpenCLPlatformIndex;
  17. #include "../CommonInterfaces/CommonExampleInterface.h"
  18. #include "../CommonInterfaces/CommonGUIHelperInterface.h"
  19. #include "../CommonInterfaces/CommonRenderInterface.h"
  20. #include "../CommonInterfaces/CommonCameraInterface.h"
  21. #include "../CommonInterfaces/CommonGraphicsAppInterface.h"
  22. #include "../CommonInterfaces/CommonWindowInterface.h"
  23. #include "../CommonOpenCL/CommonOpenCLBase.h"
  24. #include "../OpenGLWindow/GLInstancingRenderer.h"
  25. #include "../OpenGLWindow/GLInstanceRendererInternalData.h"
  26. char* gPairBenchFileName = 0;
  27. class PairBench : public CommonOpenCLBase
  28. {
  29. struct PairBenchInternalData* m_data;
  30. public:
  31. PairBench(GUIHelperInterface* helper);
  32. virtual ~PairBench();
  33. virtual void initPhysics();
  34. virtual void exitPhysics();
  35. void createBroadphase(int xdim, int ydim, int zdim);
  36. void deleteBroadphase();
  37. virtual void stepSimulation(float deltaTime);
  38. virtual void renderScene();
  39. virtual void resetCamera()
  40. {
  41. float dist = 10;
  42. if (gPairBenchFileName)
  43. {
  44. dist = 830;
  45. } else
  46. {
  47. dist = 130;
  48. }
  49. float pitch = 62;
  50. float yaw = 33;
  51. float targetPos[4]={15.5,12.5,15.5,0};
  52. m_guiHelper->resetCamera(dist,pitch,yaw,targetPos[0],targetPos[1],targetPos[2]);
  53. }
  54. };
  55. //we use an offset, just for testing to make sure there is no assumption in the broadphase that 'index' starts at 0
  56. #define TEST_INDEX_OFFSET 1024
  57. extern bool useShadowMap;
  58. float maxExtents = -1e30f;
  59. int largeCount = 0;
  60. float timeStepPos = 0.000166666;
  61. float mAmplitude = 251.f;
  62. int dimensions[3]={10,10,10};//initialized with x_dim/y_dim/z_dim
  63. const char* axisNames[3] = {"# x-axis","# y-axis","# z-axis"};
  64. extern bool gReset;
  65. static int curUseLargeAabbOption=0;
  66. const char* useLargeAabbOptions[] =
  67. {
  68. "NoLargeAabb",
  69. "UseLargeAabb",
  70. };
  71. struct BroadphaseEntry
  72. {
  73. const char* m_name;
  74. b3GpuBroadphaseInterface::CreateFunc* m_createFunc;
  75. };
  76. static PairBench* sPairDemo = 0;
  77. #define BP_COMBO_INDEX 123
  78. static int curSelectedBroadphase = 0;
  79. static BroadphaseEntry allBroadphases[]=
  80. {
  81. {"Gpu Grid",b3GpuGridBroadphase::CreateFunc},
  82. {"Parallel Linear BVH",b3GpuParallelLinearBvhBroadphase::CreateFunc},
  83. {"CPU Brute Force",b3GpuSapBroadphase::CreateFuncBruteForceCpu},
  84. {"GPU Brute Force",b3GpuSapBroadphase::CreateFuncBruteForceGpu},
  85. {"GPU 1-SAP Original",b3GpuSapBroadphase::CreateFuncOriginal},
  86. {"GPU 1-SAP Barrier",b3GpuSapBroadphase::CreateFuncBarrier},
  87. {"GPU 1-SAP LDS",b3GpuSapBroadphase::CreateFuncLocalMemory}
  88. };
  89. struct PairBenchInternalData
  90. {
  91. b3GpuBroadphaseInterface* m_broadphaseGPU;
  92. b3GpuBroadphaseInterface* m_validationBroadphase;
  93. cl_kernel m_moveObjectsKernel;
  94. cl_kernel m_sineWaveKernel;
  95. cl_kernel m_colorPairsKernel;
  96. cl_kernel m_updateAabbSimple;
  97. b3OpenCLArray<b3Vector4>* m_instancePosOrnColor;
  98. b3OpenCLArray<float>* m_bodyTimes;
  99. PairBenchInternalData()
  100. :m_broadphaseGPU(0),
  101. m_moveObjectsKernel(0),
  102. m_sineWaveKernel(0),
  103. m_colorPairsKernel(0),
  104. m_instancePosOrnColor(0),
  105. m_bodyTimes(0),
  106. m_updateAabbSimple(0)
  107. {
  108. }
  109. int m_oldYposition;
  110. };
  111. PairBench::PairBench(GUIHelperInterface* helper)
  112. :CommonOpenCLBase(helper)
  113. {
  114. m_data = new PairBenchInternalData;
  115. m_data->m_validationBroadphase = 0;
  116. }
  117. PairBench::~PairBench()
  118. {
  119. delete m_data;
  120. }
  121. static inline float parseFloat(const char*& token)
  122. {
  123. token += strspn(token, " \t");
  124. float f = (float)atof(token);
  125. token += strcspn(token, " \t\r");
  126. return f;
  127. }
  128. enum PairToggleButtons
  129. {
  130. MY_RESET = 1024,
  131. };
  132. #define PAIRS_CL_PROGRAM_PATH "Demos3/GpuDemos/broadphase/pairsKernel.cl"
  133. void PairBench::initPhysics()
  134. {
  135. dimensions[0] = 10;
  136. dimensions[1] = 10;
  137. dimensions[2] = 10;
  138. //m_guiHelper->getRenderInterface() = ci.m_guiHelper->getRenderInterface();
  139. sPairDemo = this;
  140. useShadowMap = false;
  141. int startItem = 0;
  142. initCL(gPreferredOpenCLDeviceIndex,gPreferredOpenCLPlatformIndex);
  143. if (m_clData->m_clContext)
  144. {
  145. cl_int err;
  146. cl_program pairBenchProg=b3OpenCLUtils::compileCLProgramFromString(m_clData->m_clContext,m_clData->m_clDevice,pairsKernelsCL,&err,"",PAIRS_CL_PROGRAM_PATH);
  147. int errNum=0;
  148. m_data->m_moveObjectsKernel = b3OpenCLUtils::compileCLKernelFromString(m_clData->m_clContext,m_clData->m_clDevice,pairsKernelsCL,"moveObjectsKernel",&errNum,pairBenchProg);
  149. m_data->m_sineWaveKernel = b3OpenCLUtils::compileCLKernelFromString(m_clData->m_clContext,m_clData->m_clDevice,pairsKernelsCL,"sineWaveKernel",&errNum,pairBenchProg);
  150. m_data->m_colorPairsKernel = b3OpenCLUtils::compileCLKernelFromString(m_clData->m_clContext,m_clData->m_clDevice,pairsKernelsCL,"colorPairsKernel2",&errNum,pairBenchProg);
  151. m_data->m_updateAabbSimple = b3OpenCLUtils::compileCLKernelFromString(m_clData->m_clContext,m_clData->m_clDevice,pairsKernelsCL,"updateAabbSimple",&errNum,pairBenchProg);
  152. //Method for validating the overlapping pairs requires that the
  153. //reference broadphase does not maintain internal state aside from AABB data.
  154. //That is, overwriting the AABB state in the broadphase using
  155. // b3GpuBroadphaseInterface::getAllAabbsGPU(),
  156. // b3GpuBroadphaseInterface::getSmallAabbIndicesGPU(), and
  157. // b3GpuBroadphaseInterface::getLargeAabbIndicesGPU()
  158. //and then calling b3GpuBroadphaseInterface::calculateOverlappingPairs() should
  159. //always produce the same result regardless of the current state of the broadphase.
  160. m_data->m_validationBroadphase = b3GpuParallelLinearBvhBroadphase::CreateFunc(m_clData->m_clContext,m_clData->m_clDevice,m_clData->m_clQueue);
  161. }
  162. createBroadphase(dimensions[0],dimensions[1],dimensions[2]);
  163. }
  164. void PairBench::createBroadphase(int arraySizeX, int arraySizeY, int arraySizeZ)
  165. {
  166. m_data->m_broadphaseGPU = (allBroadphases[curSelectedBroadphase].m_createFunc)(m_clData->m_clContext,m_clData->m_clDevice,m_clData->m_clQueue);
  167. int strideInBytes = 9*sizeof(float);
  168. int numVertices = sizeof(cube_vertices)/strideInBytes;
  169. int numIndices = sizeof(cube_vertices)/sizeof(int);
  170. int shapeId = m_guiHelper->getRenderInterface()->registerShape(&cube_vertices[0],numVertices,cube_indices,numIndices);
  171. int group=1;
  172. int mask=1;
  173. int index=TEST_INDEX_OFFSET;
  174. if (gPairBenchFileName)
  175. {
  176. //char* fileName = "32006GPUAABBs.txt";
  177. char relativeFileName[1024];
  178. const char* prefix[]={"./data/","../data/","../../data/","../../../data/","../../../../data/"};
  179. int prefixIndex=-1;
  180. {
  181. int numPrefixes = sizeof(prefix)/sizeof(char*);
  182. for (int i=0;i<numPrefixes;i++)
  183. {
  184. FILE* f = 0;
  185. sprintf(relativeFileName,"%s%s",prefix[i],gPairBenchFileName);
  186. f = fopen(relativeFileName,"rb");
  187. if (f)
  188. {
  189. fseek( f, 0L, SEEK_END );
  190. int size = ftell( f);
  191. rewind( f);
  192. char* buf = (char*)malloc(size);
  193. int actualReadBytes =0;
  194. while (actualReadBytes<size)
  195. { int left = size-actualReadBytes;
  196. int chunk = 8192;
  197. int numPlannedRead= left < chunk? left : chunk;
  198. actualReadBytes += fread(&buf[actualReadBytes],1,numPlannedRead,f);
  199. }
  200. fclose(f);
  201. char pattern[1024];
  202. pattern[0] = 0x0a;
  203. pattern[1] = 0;
  204. size_t const patlen = strlen(pattern);
  205. size_t patcnt = 0;
  206. char * oriptr;
  207. char * patloc;
  208. for (oriptr = buf; patloc = strstr(oriptr, pattern); oriptr = patloc + patlen)
  209. {
  210. if (patloc)
  211. {
  212. *patloc=0;
  213. const char* token = oriptr;
  214. b3Vector3 aabbMin;
  215. b3Vector3 aabbMax;
  216. aabbMin.x = parseFloat(token);
  217. aabbMin.y = parseFloat(token);
  218. aabbMin.z = parseFloat(token);
  219. aabbMin.w = 0.f;
  220. aabbMax.x = parseFloat(token);
  221. aabbMax.y = parseFloat(token);
  222. aabbMax.z = parseFloat(token);
  223. aabbMax.w = 0.f;
  224. aabbMin*=0.1;
  225. aabbMax*=0.1;
  226. b3Vector3 extents = aabbMax-aabbMin;
  227. //printf("%s\n", oriptr);
  228. b3Vector3 position=0.5*(aabbMax+aabbMin);
  229. b3Quaternion orn(0,0,0,1);
  230. b3Vector4 scaling = b3MakeVector4(0.5*extents.x,0.5*extents.y,0.5*extents.z,1);//b3MakeVector4(1,1,1,1);
  231. float l = extents.length();
  232. if (l>500)
  233. {
  234. b3Vector4 color=b3MakeVector4(0,1,0,0.1);
  235. int id = m_guiHelper->getRenderInterface()->registerGraphicsInstance(shapeId,position,orn,color,scaling);
  236. m_data->m_broadphaseGPU->createLargeProxy(aabbMin,aabbMax,index,group,mask);
  237. } else
  238. {
  239. b3Vector4 color=b3MakeVector4(1,0,0,1);
  240. int id = m_guiHelper->getRenderInterface()->registerGraphicsInstance(shapeId,position,orn,color,scaling);
  241. m_data->m_broadphaseGPU->createProxy(aabbMin,aabbMax,index,group,mask);
  242. index++;
  243. }
  244. patcnt++;
  245. }
  246. }
  247. prefixIndex = i;
  248. break;
  249. }
  250. }
  251. if (prefixIndex<0)
  252. {
  253. b3Printf("Cannot find %s\n",gPairBenchFileName);
  254. }
  255. }
  256. }
  257. else
  258. {
  259. for (int i=0;i<arraySizeX;i++)
  260. {
  261. for (int j=0;j<arraySizeY;j++)
  262. {
  263. for (int k=0;k<arraySizeZ;k++)
  264. {
  265. b3Vector3 position=b3MakeVector3(k*3,i*3,j*3);
  266. b3Quaternion orn(0,0,0,1);
  267. b3Vector4 color=b3MakeVector4(0,1,0,1);
  268. b3Vector4 scaling=b3MakeVector4(1,1,1,1);
  269. bool large = false;
  270. if (curUseLargeAabbOption)
  271. {
  272. if (i==0 && j==0 && k==0)
  273. {
  274. large = true;
  275. scaling[0] = 1000;
  276. scaling[1] = 1000;
  277. scaling[2] = 1000;
  278. }
  279. }
  280. /*if (j==0)
  281. {
  282. large=true;
  283. scaling[1] = 10000;
  284. }
  285. if (k==0)
  286. {
  287. large=true;
  288. scaling[2] = 10000;
  289. }*/
  290. int id = m_guiHelper->getRenderInterface()->registerGraphicsInstance(shapeId,position,orn,color,scaling);
  291. b3Vector3 aabbMin = position-scaling;
  292. b3Vector3 aabbMax = position+scaling;
  293. if (large)
  294. {
  295. m_data->m_broadphaseGPU->createLargeProxy(aabbMin,aabbMax,index,group,mask);
  296. } else
  297. {
  298. m_data->m_broadphaseGPU->createProxy(aabbMin,aabbMax,index,group,mask);
  299. }
  300. index++;
  301. }
  302. }
  303. }
  304. }
  305. m_guiHelper->getRenderInterface()->writeTransforms();
  306. m_data->m_broadphaseGPU->writeAabbsToGpu();
  307. }
  308. void PairBench::deleteBroadphase()
  309. {
  310. delete m_data->m_broadphaseGPU;
  311. m_data->m_broadphaseGPU = 0;
  312. delete m_data->m_instancePosOrnColor;
  313. m_data->m_instancePosOrnColor = 0;
  314. delete m_data->m_bodyTimes;
  315. m_data->m_bodyTimes = 0;
  316. m_data->m_broadphaseGPU = 0;
  317. m_guiHelper->getRenderInterface()->removeAllInstances();
  318. }
  319. void PairBench::exitPhysics()
  320. {
  321. //reset the state to 'on'
  322. useShadowMap = true;
  323. if(m_data->m_validationBroadphase)
  324. {
  325. delete m_data->m_validationBroadphase;
  326. m_data->m_validationBroadphase = 0;
  327. }
  328. sPairDemo = 0;
  329. exitCL();
  330. }
  331. void PairBench::renderScene()
  332. {
  333. m_guiHelper->getRenderInterface()->renderScene();
  334. }
  335. struct OverlappingPairSortPredicate
  336. {
  337. inline bool operator() (const b3Int4& a, const b3Int4& b) const
  338. {
  339. if(a.x != b.x) return (a.x < b.x);
  340. if(a.y != b.y) return (a.y < b.y);
  341. if(a.z != b.z) return (a.z < b.z);
  342. return (a.w < b.w);
  343. }
  344. };
  345. void PairBench::stepSimulation(float deltaTime)
  346. {
  347. //color all objects blue
  348. GLInstanceRendererInternalData* internalData = m_guiHelper->getRenderInterface()->getInternalData();
  349. if (internalData==0)
  350. return;
  351. bool animate=true;
  352. int numObjects= 0;
  353. {
  354. B3_PROFILE("Num Objects");
  355. numObjects = internalData->m_totalNumInstances;
  356. }
  357. b3Vector4* positions = 0;
  358. if (numObjects)
  359. {
  360. B3_PROFILE("Sync");
  361. GLuint vbo = internalData->m_vbo;
  362. int arraySizeInBytes = numObjects * (3)*sizeof(b3Vector4);
  363. glBindBuffer(GL_ARRAY_BUFFER, vbo);
  364. cl_bool blocking= CL_TRUE;
  365. char* hostPtr= 0;
  366. {
  367. B3_PROFILE("glMapBufferRange");
  368. hostPtr = (char*)glMapBufferRange( GL_ARRAY_BUFFER,internalData->m_maxShapeCapacityInBytes,arraySizeInBytes, GL_MAP_WRITE_BIT|GL_MAP_READ_BIT );//GL_READ_WRITE);//GL_WRITE_ONLY
  369. }
  370. GLint err = glGetError();
  371. assert(err==GL_NO_ERROR);
  372. positions = (b3Vector4*)hostPtr;
  373. if (m_data->m_instancePosOrnColor && m_data->m_instancePosOrnColor->size() != 3*numObjects)
  374. {
  375. delete m_data->m_instancePosOrnColor;
  376. m_data->m_instancePosOrnColor=0;
  377. }
  378. if (!m_data->m_instancePosOrnColor)
  379. {
  380. m_data->m_instancePosOrnColor = new b3OpenCLArray<b3Vector4>(m_clData->m_clContext,m_clData->m_clQueue);
  381. m_data->m_instancePosOrnColor->resize(3*numObjects);
  382. m_data->m_instancePosOrnColor->copyFromHostPointer(positions,3*numObjects,0);
  383. m_data->m_bodyTimes = new b3OpenCLArray<float>(m_clData->m_clContext,m_clData->m_clQueue);
  384. m_data->m_bodyTimes ->resize(numObjects);
  385. b3AlignedObjectArray<float> tmp;
  386. tmp.resize(numObjects);
  387. for (int i=0;i<numObjects;i++)
  388. {
  389. tmp[i] = float(i)*(1024.f/numObjects);
  390. }
  391. m_data->m_bodyTimes->copyFromHost(tmp);
  392. }
  393. if (!gPairBenchFileName)
  394. {
  395. if (1)
  396. {
  397. if (1)
  398. {
  399. b3LauncherCL launcher(m_clData->m_clQueue, m_data->m_sineWaveKernel,"m_sineWaveKernel");
  400. launcher.setBuffer(m_data->m_instancePosOrnColor->getBufferCL() );
  401. launcher.setBuffer(m_data->m_bodyTimes->getBufferCL() );
  402. launcher.setConst(timeStepPos);
  403. launcher.setConst(mAmplitude);
  404. launcher.setConst( numObjects);
  405. launcher.launch1D( numObjects);
  406. clFinish(m_clData->m_clQueue);
  407. }
  408. else
  409. {
  410. b3LauncherCL launcher(m_clData->m_clQueue, m_data->m_moveObjectsKernel,"m_moveObjectsKernel");
  411. launcher.setBuffer(m_data->m_instancePosOrnColor->getBufferCL() );
  412. launcher.setConst( numObjects);
  413. launcher.launch1D( numObjects);
  414. clFinish(m_clData->m_clQueue);
  415. }
  416. }
  417. }
  418. }
  419. bool updateOnGpu=true;
  420. if (1)
  421. {
  422. if (updateOnGpu)
  423. {
  424. B3_PROFILE("updateOnGpu");
  425. b3LauncherCL launcher(m_clData->m_clQueue, m_data->m_updateAabbSimple,"m_updateAabbSimple");
  426. launcher.setBuffer(m_data->m_instancePosOrnColor->getBufferCL() );
  427. launcher.setConst( numObjects);
  428. launcher.setBuffer(m_data->m_broadphaseGPU->getAabbBufferWS());
  429. launcher.launch1D( numObjects);
  430. clFinish(m_clData->m_clQueue);
  431. } else
  432. {
  433. B3_PROFILE("updateOnCpu");
  434. if (!gPairBenchFileName)
  435. {
  436. int allAabbs = m_data->m_broadphaseGPU->getAllAabbsCPU().size();
  437. b3AlignedObjectArray<b3Vector4> posOrnColorsCpu;
  438. if (m_data->m_instancePosOrnColor)
  439. m_data->m_instancePosOrnColor->copyToHost(posOrnColorsCpu);
  440. for (int nodeId=0;nodeId<numObjects;nodeId++)
  441. {
  442. {
  443. b3Vector3 position = posOrnColorsCpu[nodeId];
  444. b3SapAabb orgAabb = m_data->m_broadphaseGPU->getAllAabbsCPU()[nodeId];
  445. b3Vector3 halfExtents = 0.5f*(orgAabb.m_maxVec-orgAabb.m_minVec);
  446. int orgNodeIndex = orgAabb.m_minIndices[3];
  447. int orgBroadphaseIndex = orgAabb.m_signedMaxIndices[3];
  448. m_data->m_broadphaseGPU->getAllAabbsCPU()[nodeId].m_minVec = position-halfExtents;
  449. m_data->m_broadphaseGPU->getAllAabbsCPU()[nodeId].m_minIndices[3] = orgNodeIndex;
  450. m_data->m_broadphaseGPU->getAllAabbsCPU()[nodeId].m_maxVec = position+halfExtents;
  451. m_data->m_broadphaseGPU->getAllAabbsCPU()[nodeId].m_signedMaxIndices[3]= orgBroadphaseIndex;
  452. }
  453. }
  454. m_data->m_broadphaseGPU->writeAabbsToGpu();
  455. }
  456. }
  457. }
  458. int prealloc = 3*1024*1024;
  459. int maxOverlap = b3Min(prealloc,16*numObjects);
  460. unsigned long dt = 0;
  461. if (numObjects)
  462. {
  463. b3Clock cl;
  464. dt = cl.getTimeMicroseconds();
  465. B3_PROFILE("calculateOverlappingPairs");
  466. int sz = sizeof(b3Int4)*64*numObjects;
  467. m_data->m_broadphaseGPU->calculateOverlappingPairs(maxOverlap);
  468. int numPairs = m_data->m_broadphaseGPU->getNumOverlap();
  469. //printf("numPairs = %d\n", numPairs);
  470. dt = cl.getTimeMicroseconds()-dt;
  471. }
  472. const bool VALIDATE_BROADPHASE = false; //Check that overlapping pairs of 2 broadphases are the same
  473. if(numObjects && VALIDATE_BROADPHASE)
  474. {
  475. B3_PROFILE("validate broadphases");
  476. {
  477. B3_PROFILE("calculateOverlappingPairs m_validationBroadphase");
  478. //m_data->m_validationBroadphase->getAllAabbsCPU() = m_data->m_broadphaseGPU->getAllAabbsCPU();
  479. m_data->m_validationBroadphase->getAllAabbsGPU().copyFromOpenCLArray( m_data->m_broadphaseGPU->getAllAabbsGPU() );
  480. m_data->m_validationBroadphase->getSmallAabbIndicesGPU().copyFromOpenCLArray( m_data->m_broadphaseGPU->getSmallAabbIndicesGPU() );
  481. m_data->m_validationBroadphase->getLargeAabbIndicesGPU().copyFromOpenCLArray( m_data->m_broadphaseGPU->getLargeAabbIndicesGPU() );
  482. m_data->m_validationBroadphase->calculateOverlappingPairs(maxOverlap);
  483. }
  484. static b3AlignedObjectArray<b3Int4> overlappingPairs;
  485. static b3AlignedObjectArray<b3Int4> overlappingPairsReference;
  486. m_data->m_broadphaseGPU->getOverlappingPairsGPU().copyToHost(overlappingPairs);
  487. m_data->m_validationBroadphase->getOverlappingPairsGPU().copyToHost(overlappingPairsReference);
  488. //Reorder pairs so that (pair.x < pair.y) is always true
  489. {
  490. B3_PROFILE("reorder pairs");
  491. for(int i = 0; i < overlappingPairs.size(); ++i)
  492. {
  493. b3Int4 pair = overlappingPairs[i];
  494. if(pair.x > pair.y)
  495. {
  496. b3Swap(pair.x, pair.y);
  497. b3Swap(pair.z, pair.w);
  498. overlappingPairs[i] = pair;
  499. }
  500. }
  501. for(int i = 0; i < overlappingPairsReference.size(); ++i)
  502. {
  503. b3Int4 pair = overlappingPairsReference[i];
  504. if(pair.x > pair.y)
  505. {
  506. b3Swap(pair.x, pair.y);
  507. b3Swap(pair.z, pair.w);
  508. overlappingPairsReference[i] = pair;
  509. }
  510. }
  511. }
  512. //
  513. {
  514. B3_PROFILE("Sort overlapping pairs from most to least significant bit");
  515. overlappingPairs.quickSort( OverlappingPairSortPredicate() );
  516. overlappingPairsReference.quickSort( OverlappingPairSortPredicate() );
  517. }
  518. //Compare
  519. {
  520. B3_PROFILE("compare pairs");
  521. int numPairs = overlappingPairs.size();
  522. int numPairsReference = overlappingPairsReference.size();
  523. bool success = true;
  524. if(numPairs == numPairsReference)
  525. {
  526. for(int i = 0; i < numPairsReference; ++i)
  527. {
  528. const b3Int4& pairA = overlappingPairs[i];
  529. const b3Int4& pairB = overlappingPairsReference[i];
  530. if( pairA.x != pairB.x
  531. || pairA.y != pairB.y
  532. || pairA.z != pairB.z
  533. || pairA.w != pairB.w )
  534. {
  535. b3Error("Error: one or more overlappingPairs differs from reference.\n");
  536. success = false;
  537. break;
  538. }
  539. }
  540. }
  541. else
  542. {
  543. b3Error("Error: numPairs %d != numPairsReference %d \n", numPairs, numPairsReference);
  544. success = false;
  545. }
  546. printf("Broadphase validation: %d \n", success);
  547. }
  548. }
  549. /*
  550. if (m_data->m_gui)
  551. {
  552. B3_PROFILE("update Gui");
  553. int allAabbs = m_data->m_broadphaseGPU->getAllAabbsCPU().size();
  554. int numOverlap = m_data->m_broadphaseGPU->getNumOverlap();
  555. float time = dt/1000.f;
  556. //printf("time = %f\n", time);
  557. char msg[1024];
  558. sprintf(msg,"#objects = %d, #overlapping pairs = %d, time = %f ms", allAabbs,numOverlap,time );
  559. //printf("msg=%s\n",msg);
  560. m_data->m_gui->setStatusBarMessage(msg,true);
  561. }
  562. */
  563. if (numObjects)
  564. {
  565. B3_PROFILE("animate");
  566. GLint err = glGetError();
  567. assert(err==GL_NO_ERROR);
  568. //color overlapping objects in red
  569. if (m_data->m_broadphaseGPU->getNumOverlap())
  570. {
  571. bool colorPairsOnHost = false;
  572. if (colorPairsOnHost )
  573. {
  574. } else
  575. {
  576. int numPairs = m_data->m_broadphaseGPU->getNumOverlap();
  577. cl_mem pairBuf = m_data->m_broadphaseGPU->getOverlappingPairBuffer();
  578. b3LauncherCL launcher(m_clData->m_clQueue, m_data->m_colorPairsKernel,"m_colorPairsKernel");
  579. launcher.setBuffer(m_data->m_instancePosOrnColor->getBufferCL() );
  580. launcher.setConst( numObjects);
  581. launcher.setBuffer( pairBuf);
  582. int indexOffset = TEST_INDEX_OFFSET;
  583. launcher.setConst(indexOffset);
  584. launcher.setConst( numPairs);
  585. launcher.launch1D( numPairs);
  586. clFinish(m_clData->m_clQueue);
  587. }
  588. }
  589. if (numObjects)
  590. {
  591. m_data->m_instancePosOrnColor->copyToHostPointer(positions,3*numObjects,0);
  592. }
  593. glUnmapBuffer( GL_ARRAY_BUFFER);
  594. err = glGetError();
  595. assert(err==GL_NO_ERROR);
  596. }
  597. }
  598. class CommonExampleInterface* PairBenchOpenCLCreateFunc(struct CommonExampleOptions& options)
  599. {
  600. return new PairBench(options.m_guiHelper);
  601. }