Bullet Collision Detection & Physics Library
SpuGatheringCollisionTask.cpp
Go to the documentation of this file.
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
4 
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose,
8 including commercial applications, and to alter it and redistribute it freely,
9 subject to the following restrictions:
10 
11 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.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
14 */
15 
17 
18 //#define DEBUG_SPU_COLLISION_DETECTION 1
19 #include "../SpuDoubleBuffer.h"
20 
21 #include "../SpuCollisionTaskProcess.h"
22 #include "../SpuGatheringCollisionDispatcher.h" //for SPU_BATCHSIZE_BROADPHASE_PAIRS
23 
25 #include "../SpuContactManifoldCollisionAlgorithm.h"
27 #include "SpuContactResult.h"
32 
34 
39 
41 //#include "SpuEpaPenetrationDepthSolver.h"
43 
44 
45 #include "boxBoxDistance.h"
47 #include "SpuCollisionShapes.h" //definition of SpuConvexPolyhedronVertexData
51 
52 #ifdef __SPU__
53 #ifndef USE_LIBSPE2
55 //#define USE_SOFTWARE_CACHE 1
56 #endif
57 #endif //__SPU__
58 
59 int gSkippedCol = 0;
60 int gProcessedCol = 0;
61 
64 #if USE_SOFTWARE_CACHE
65 #include <spu_intrinsics.h>
66 #include <sys/spu_thread.h>
67 #include <sys/spu_event.h>
68 #include <stdint.h>
69 #define SPE_CACHE_NWAY 4
70 //#define SPE_CACHE_NSETS 32, 16
71 #define SPE_CACHE_NSETS 8
72 //#define SPE_CACHELINE_SIZE 512
73 #define SPE_CACHELINE_SIZE 128
74 #define SPE_CACHE_SET_TAGID(set) 15
75 #include "../Extras/software_cache/cache/include/spe_cache.h"
77 
78 
79 int g_CacheMisses=0;
80 int g_CacheHits=0;
81 
82 #if 0 // Added to allow cache misses and hits to be tracked, change this to 1 to restore unmodified version
83 #define spe_cache_read(ea) _spe_cache_lookup_xfer_wait_(ea, 0, 1)
84 #else
85 #define spe_cache_read(ea) \
86 ({ \
87  int set, idx, line, byte; \
88  _spe_cache_nway_lookup_(ea, set, idx); \
89  \
90  if (btUnlikely(idx < 0)) { \
91  ++g_CacheMisses; \
92  idx = _spe_cache_miss_(ea, set, -1); \
93  spu_writech(22, SPE_CACHE_SET_TAGMASK(set)); \
94  spu_mfcstat(MFC_TAG_UPDATE_ALL); \
95  } \
96  else \
97  { \
98  ++g_CacheHits; \
99  } \
100  line = _spe_cacheline_num_(set, idx); \
101  byte = _spe_cacheline_byte_offset_(ea); \
102  (void *) &spe_cache_mem[line + byte]; \
103 })
104 
105 #endif
106 
107 #endif // USE_SOFTWARE_CACHE
108 
109 bool gUseEpa = false;
110 
111 #ifdef USE_SN_TUNER
112 #include <LibSN_SPU.h>
113 #endif //USE_SN_TUNER
114 
115 #if defined (__SPU__) && !defined (USE_LIBSPE2)
116 #include <spu_printf.h>
117 #elif defined (USE_LIBSPE2)
118 #define spu_printf(a)
119 #else
120 #define IGNORE_ALIGNMENT 1
121 #include <stdio.h>
122 #include <stdlib.h>
123 #define spu_printf printf
124 
125 #endif
126 
127 //int gNumConvexPoints0=0;
128 
131 {
134 
137  ATTRIBUTE_ALIGNED16(char gSpuContactManifoldAlgoBuffer [sizeof(SpuContactManifoldCollisionAlgorithm)+16]);
138  ATTRIBUTE_ALIGNED16(char gColObj0Buffer [sizeof(btCollisionObject)+16]);
139  ATTRIBUTE_ALIGNED16(char gColObj1Buffer [sizeof(btCollisionObject)+16]);
141  ATTRIBUTE_ALIGNED16(int spuIndices[16]);
143  CollisionShape_LocalStoreMemory gCollisionShapes[2];
146  CompoundShape_LocalStoreMemory compoundShapeData[2];
147 
155 
157 
159  {
160  return m_lsColObj0Ptr;
161  }
163  {
164  return m_lsColObj1Ptr;
165  }
166 
167 
169  {
170  return m_pairsPointer;
171  }
172 
174  {
175  return m_lsCollisionAlgorithmPtr;
176  }
177 
179  {
180  return m_lsManifoldPtr;
181  }
182 };
183 
184 
185 #if defined(__CELLOS_LV2__) || defined(USE_LIBSPE2)
186 
188 
190 {
191  return &gLocalStoreMemory;
192 }
194 {
195 }
196 #else
197 
199 
201 {
203  sLocalStorePointers.push_back(localStore);
204  return localStore;
205 }
206 
208 {
209  for (int i=0;i<sLocalStorePointers.size();i++)
210  {
211  btAlignedFree(sLocalStorePointers[i]);
212  }
213  sLocalStorePointers.clear();
214 }
215 
216 #endif
217 
219 
220 
221 SIMD_FORCE_INLINE void small_cache_read(void* buffer, ppu_address_t ea, size_t size)
222 {
223 #if USE_SOFTWARE_CACHE
224  // Check for alignment requirements. We need to make sure the entire request fits within one cache line,
225  // so the first and last bytes should fall on the same cache line
226  btAssert((ea & ~SPE_CACHELINE_MASK) == ((ea + size - 1) & ~SPE_CACHELINE_MASK));
227 
228  void* ls = spe_cache_read(ea);
229  memcpy(buffer, ls, size);
230 #else
231  stallingUnalignedDmaSmallGet(buffer,ea,size);
232 #endif
233 }
234 
236  void* ls1, ppu_address_t ea1,
237  void* ls2, ppu_address_t ea2,
238  size_t size)
239 {
240  btAssert(size<16);
241  ATTRIBUTE_ALIGNED16(char tmpBuffer0[32]);
242  ATTRIBUTE_ALIGNED16(char tmpBuffer1[32]);
243  ATTRIBUTE_ALIGNED16(char tmpBuffer2[32]);
244 
245  uint32_t i;
246 
247 
249  char* localStore0 = (char*)ls0;
250  uint32_t last4BitsOffset = ea0 & 0x0f;
251  char* tmpTarget0 = tmpBuffer0 + last4BitsOffset;
252 #ifdef __SPU__
253  cellDmaSmallGet(tmpTarget0,ea0,size,DMA_TAG(1),0,0);
254 #else
255  tmpTarget0 = (char*)cellDmaSmallGetReadOnly(tmpTarget0,ea0,size,DMA_TAG(1),0,0);
256 #endif
257 
258 
259  char* localStore1 = (char*)ls1;
260  last4BitsOffset = ea1 & 0x0f;
261  char* tmpTarget1 = tmpBuffer1 + last4BitsOffset;
262 #ifdef __SPU__
263  cellDmaSmallGet(tmpTarget1,ea1,size,DMA_TAG(1),0,0);
264 #else
265  tmpTarget1 = (char*)cellDmaSmallGetReadOnly(tmpTarget1,ea1,size,DMA_TAG(1),0,0);
266 #endif
267 
268  char* localStore2 = (char*)ls2;
269  last4BitsOffset = ea2 & 0x0f;
270  char* tmpTarget2 = tmpBuffer2 + last4BitsOffset;
271 #ifdef __SPU__
272  cellDmaSmallGet(tmpTarget2,ea2,size,DMA_TAG(1),0,0);
273 #else
274  tmpTarget2 = (char*)cellDmaSmallGetReadOnly(tmpTarget2,ea2,size,DMA_TAG(1),0,0);
275 #endif
276 
277 
279 
280  //this is slowish, perhaps memcpy on SPU is smarter?
281  for (i=0; btLikely( i<size );i++)
282  {
283  localStore0[i] = tmpTarget0[i];
284  localStore1[i] = tmpTarget1[i];
285  localStore2[i] = tmpTarget2[i];
286  }
287 
288 
289 }
290 
291 
292 
293 
295 {
300 
301  ATTRIBUTE_ALIGNED16(btVector3 spuTriangleVertices[3]);
302  ATTRIBUTE_ALIGNED16(btScalar spuUnscaledVertex[4]);
303 
304 
305 
306 public:
308  : m_wuInput(wuInput),
309  m_spuContacts(spuContacts),
310  m_lsMemPtr(lsMemPtr)
311  {
312  }
313 
314  virtual void processNode(int subPart, int triangleIndex)
315  {
318 
319  // spu_printf("processNode with triangleIndex %d\n",triangleIndex);
320 
321  if (m_lsMemPtr->bvhShapeData.gIndexMesh.m_indexType == PHY_SHORT)
322  {
323  unsigned short int* indexBasePtr = (unsigned short int*)(m_lsMemPtr->bvhShapeData.gIndexMesh.m_triangleIndexBase+triangleIndex*m_lsMemPtr->bvhShapeData.gIndexMesh.m_triangleIndexStride);
324  ATTRIBUTE_ALIGNED16(unsigned short int tmpIndices[3]);
325 
326  small_cache_read_triple(&tmpIndices[0],(ppu_address_t)&indexBasePtr[0],
327  &tmpIndices[1],(ppu_address_t)&indexBasePtr[1],
328  &tmpIndices[2],(ppu_address_t)&indexBasePtr[2],
329  sizeof(unsigned short int));
330 
331  m_lsMemPtr->spuIndices[0] = int(tmpIndices[0]);
332  m_lsMemPtr->spuIndices[1] = int(tmpIndices[1]);
333  m_lsMemPtr->spuIndices[2] = int(tmpIndices[2]);
334  } else
335  {
336  unsigned int* indexBasePtr = (unsigned int*)(m_lsMemPtr->bvhShapeData.gIndexMesh.m_triangleIndexBase+triangleIndex*m_lsMemPtr->bvhShapeData.gIndexMesh.m_triangleIndexStride);
337 
338  small_cache_read_triple(&m_lsMemPtr->spuIndices[0],(ppu_address_t)&indexBasePtr[0],
339  &m_lsMemPtr->spuIndices[1],(ppu_address_t)&indexBasePtr[1],
340  &m_lsMemPtr->spuIndices[2],(ppu_address_t)&indexBasePtr[2],
341  sizeof(int));
342  }
343 
344  // spu_printf("SPU index0=%d ,",spuIndices[0]);
345  // spu_printf("SPU index1=%d ,",spuIndices[1]);
346  // spu_printf("SPU index2=%d ,",spuIndices[2]);
347  // spu_printf("SPU: indexBasePtr=%llx\n",indexBasePtr);
348 
349  const btVector3& meshScaling = m_lsMemPtr->bvhShapeData.gTriangleMeshInterfacePtr->getScaling();
350  for (int j=2;btLikely( j>=0 );j--)
351  {
352  int graphicsindex = m_lsMemPtr->spuIndices[j];
353 
354  // spu_printf("SPU index=%d ,",graphicsindex);
355  btScalar* graphicsbasePtr = (btScalar*)(m_lsMemPtr->bvhShapeData.gIndexMesh.m_vertexBase+graphicsindex*m_lsMemPtr->bvhShapeData.gIndexMesh.m_vertexStride);
356  // spu_printf("SPU graphicsbasePtr=%llx\n",graphicsbasePtr);
357 
358 
360 
361  //another DMA for each vertex
362  small_cache_read_triple(&spuUnscaledVertex[0],(ppu_address_t)&graphicsbasePtr[0],
363  &spuUnscaledVertex[1],(ppu_address_t)&graphicsbasePtr[1],
364  &spuUnscaledVertex[2],(ppu_address_t)&graphicsbasePtr[2],
365  sizeof(btScalar));
366 
367  m_tmpTriangleShape.getVertexPtr(j).setValue(spuUnscaledVertex[0]*meshScaling.getX(),
368  spuUnscaledVertex[1]*meshScaling.getY(),
369  spuUnscaledVertex[2]*meshScaling.getZ());
370 
371  // spu_printf("SPU:triangle vertices:%f,%f,%f\n",spuTriangleVertices[j].x(),spuTriangleVertices[j].y(),spuTriangleVertices[j].z());
372  }
373 
374 
375  SpuCollisionPairInput triangleConcaveInput(*m_wuInput);
376 // triangleConcaveInput.m_spuCollisionShapes[1] = &spuTriangleVertices[0];
377  triangleConcaveInput.m_spuCollisionShapes[1] = &m_tmpTriangleShape;
378  triangleConcaveInput.m_shapeType1 = TRIANGLE_SHAPE_PROXYTYPE;
379 
380  m_spuContacts.setShapeIdentifiersB(subPart,triangleIndex);
381 
382  // m_spuContacts.flush();
383 
384  ProcessSpuConvexConvexCollision(&triangleConcaveInput, m_lsMemPtr,m_spuContacts);
386  // m_spuContacts.flush();
387  }
388 
389 };
390 
391 
392 
394 {
395 
396  btConvexShape* convexShape = (btConvexShape*) wuInput->m_spuCollisionShapes[0];
397  btStaticPlaneShape* planeShape = (btStaticPlaneShape*) wuInput->m_spuCollisionShapes[1];
398 
399  bool hasCollision = false;
400  const btVector3& planeNormal = planeShape->getPlaneNormal();
401  const btScalar& planeConstant = planeShape->getPlaneConstant();
402 
403 
404  btTransform convexWorldTransform = wuInput->m_worldTransform0;
405  btTransform convexInPlaneTrans;
406  convexInPlaneTrans= wuInput->m_worldTransform1.inverse() * convexWorldTransform;
407  btTransform planeInConvex;
408  planeInConvex= convexWorldTransform.inverse() * wuInput->m_worldTransform1;
409 
410  //btVector3 vtx = convexShape->localGetSupportVertexWithoutMarginNonVirtual(planeInConvex.getBasis()*-planeNormal);
411  btVector3 vtx = convexShape->localGetSupportVertexNonVirtual(planeInConvex.getBasis()*-planeNormal);
412 
413  btVector3 vtxInPlane = convexInPlaneTrans(vtx);
414  btScalar distance = (planeNormal.dot(vtxInPlane) - planeConstant);
415 
416  btVector3 vtxInPlaneProjected = vtxInPlane - distance*planeNormal;
417  btVector3 vtxInPlaneWorld = wuInput->m_worldTransform1 * vtxInPlaneProjected;
418 
419  hasCollision = distance < lsMemPtr->getContactManifoldPtr()->getContactBreakingThreshold();
420  //resultOut->setPersistentManifold(m_manifoldPtr);
421  if (hasCollision)
422  {
424  btVector3 normalOnSurfaceB =wuInput->m_worldTransform1.getBasis() * planeNormal;
425  btVector3 pOnB = vtxInPlaneWorld;
426  spuContacts.addContactPoint(normalOnSurfaceB,pOnB,distance);
427  }
428 }
429 
431 {
432 
433  register int dmaSize = 0;
434  register ppu_address_t dmaPpuAddress2;
436 
438  ATTRIBUTE_ALIGNED16(char convexHullShape0[sizeof(btConvexHullShape)]);
439  ATTRIBUTE_ALIGNED16(char convexHullShape1[sizeof(btConvexHullShape)]);
440 
442  {
443  // spu_printf("SPU: DMA btConvexHullShape\n");
444 
445  dmaSize = sizeof(btConvexHullShape);
446  dmaPpuAddress2 = wuInput->m_collisionShapes[0];
447 
448  cellDmaGet(&convexHullShape0, dmaPpuAddress2 , dmaSize, DMA_TAG(1), 0, 0);
449  //cellDmaWaitTagStatusAll(DMA_MASK(1));
450  }
451 
453  {
454  // spu_printf("SPU: DMA btConvexHullShape\n");
455  dmaSize = sizeof(btConvexHullShape);
456  dmaPpuAddress2 = wuInput->m_collisionShapes[1];
457  cellDmaGet(&convexHullShape1, dmaPpuAddress2 , dmaSize, DMA_TAG(1), 0, 0);
458  //cellDmaWaitTagStatusAll(DMA_MASK(1));
459  }
460 
462  {
464  dmaConvexVertexData (&lsMemPtr->convexVertexData[0], (btConvexHullShape*)&convexHullShape0);
465  lsMemPtr->convexVertexData[0].gSpuConvexShapePtr = wuInput->m_spuCollisionShapes[0];
466  }
467 
468 
470  {
472  dmaConvexVertexData (&lsMemPtr->convexVertexData[1], (btConvexHullShape*)&convexHullShape1);
473  lsMemPtr->convexVertexData[1].gSpuConvexShapePtr = wuInput->m_spuCollisionShapes[1];
474  }
475 
476 
477  btConvexPointCloudShape cpc0,cpc1;
478 
480  {
482  lsMemPtr->convexVertexData[0].gConvexPoints = &lsMemPtr->convexVertexData[0].g_convexPointBuffer[0];
484  const btVector3& localScaling = ch->getLocalScalingNV();
485  cpc0.setPoints(lsMemPtr->convexVertexData[0].gConvexPoints,lsMemPtr->convexVertexData[0].gNumConvexPoints,false,localScaling);
486  wuInput->m_spuCollisionShapes[0] = &cpc0;
487  }
488 
490  {
492  lsMemPtr->convexVertexData[1].gConvexPoints = &lsMemPtr->convexVertexData[1].g_convexPointBuffer[0];
494  const btVector3& localScaling = ch->getLocalScalingNV();
495  cpc1.setPoints(lsMemPtr->convexVertexData[1].gConvexPoints,lsMemPtr->convexVertexData[1].gNumConvexPoints,false,localScaling);
496  wuInput->m_spuCollisionShapes[1] = &cpc1;
497 
498  }
499 
500 
501 // const btConvexShape* shape0Ptr = (const btConvexShape*)wuInput->m_spuCollisionShapes[0];
502 // const btConvexShape* shape1Ptr = (const btConvexShape*)wuInput->m_spuCollisionShapes[1];
503 // int shapeType0 = wuInput->m_shapeType0;
504 // int shapeType1 = wuInput->m_shapeType1;
505  float marginA = wuInput->m_collisionMargin0;
506  float marginB = wuInput->m_collisionMargin1;
507 
508  SpuClosestPointInput cpInput;
509  cpInput.m_convexVertexData[0] = &lsMemPtr->convexVertexData[0];
510  cpInput.m_convexVertexData[1] = &lsMemPtr->convexVertexData[1];
511  cpInput.m_transformA = wuInput->m_worldTransform0;
512  cpInput.m_transformB = wuInput->m_worldTransform1;
513  float sumMargin = (marginA+marginB+lsMemPtr->getContactManifoldPtr()->getContactBreakingThreshold());
514  cpInput.m_maximumDistanceSquared = sumMargin * sumMargin;
515 
516  ppu_address_t manifoldAddress = (ppu_address_t)manifold;
517 
518  btPersistentManifold* spuManifold=lsMemPtr->getContactManifoldPtr();
519  //spuContacts.setContactInfo(spuManifold,manifoldAddress,wuInput->m_worldTransform0,wuInput->m_worldTransform1,wuInput->m_isSwapped);
520  spuContacts.setContactInfo(spuManifold,manifoldAddress,lsMemPtr->getColObj0()->getWorldTransform(),
521  lsMemPtr->getColObj1()->getWorldTransform(),
522  lsMemPtr->getColObj0()->getRestitution(),lsMemPtr->getColObj1()->getRestitution(),
523  lsMemPtr->getColObj0()->getFriction(),lsMemPtr->getColObj1()->getFriction(),
524  wuInput->m_isSwapped);
525 
526 
527  btConvexPlaneCollideSingleContact(wuInput,lsMemPtr,spuContacts);
528 
529 
530 
531 
532 }
533 
534 
535 
536 
541 {
542  //order: first collision shape is convex, second concave. m_isSwapped is true, if the original order was opposite
543 
545  //need the mesh interface, for access to triangle vertices
546  dmaBvhShapeData (&lsMemPtr->bvhShapeData, trimeshShape);
547 
548  btVector3 aabbMin(-1,-400,-1);
549  btVector3 aabbMax(1,400,1);
550 
551 
552  //recalc aabbs
553  btTransform convexInTriangleSpace;
554  convexInTriangleSpace = wuInput->m_worldTransform1.inverse() * wuInput->m_worldTransform0;
556 
557  computeAabb (aabbMin, aabbMax, convexShape, wuInput->m_collisionShapes[0], wuInput->m_shapeType0, convexInTriangleSpace);
558 
559 
560  //CollisionShape* triangleShape = static_cast<btCollisionShape*>(triBody->m_collisionShape);
561  //convexShape->getAabb(convexInTriangleSpace,m_aabbMin,m_aabbMax);
562 
563  // btScalar extraMargin = collisionMarginTriangle;
564  // btVector3 extra(extraMargin,extraMargin,extraMargin);
565  // aabbMax += extra;
566  // aabbMin -= extra;
567 
569  unsigned short int quantizedQueryAabbMin[3];
570  unsigned short int quantizedQueryAabbMax[3];
571  lsMemPtr->bvhShapeData.getOptimizedBvh()->quantizeWithClamp(quantizedQueryAabbMin,aabbMin,0);
572  lsMemPtr->bvhShapeData.getOptimizedBvh()->quantizeWithClamp(quantizedQueryAabbMax,aabbMax,1);
573 
575  //spu_printf("SPU: numNodes = %d\n",nodeArray.size());
576 
578 
579 
580  spuNodeCallback nodeCallback(wuInput,lsMemPtr,spuContacts);
582  //spu_printf("SPU:indexArray.size() = %d\n",indexArray.size());
583 
584  // spu_printf("SPU: numSubTrees = %d\n",subTrees.size());
585  //not likely to happen
586  if (subTrees.size() && indexArray.size() == 1)
587  {
589  dmaBvhIndexedMesh (&lsMemPtr->bvhShapeData.gIndexMesh, indexArray, 0 /* index into indexArray */, 1 /* dmaTag */);
591 
592  //display the headers
593  int numBatch = subTrees.size();
594  for (int i=0;i<numBatch;)
595  {
596  //@todo- can reorder DMA transfers for less stall
597  int remaining = subTrees.size() - i;
598  int nextBatch = remaining < MAX_SPU_SUBTREE_HEADERS ? remaining : MAX_SPU_SUBTREE_HEADERS;
599 
600  dmaBvhSubTreeHeaders (&lsMemPtr->bvhShapeData.gSubtreeHeaders[0], (ppu_address_t)(&subTrees[i]), nextBatch, 1);
602 
603 
604  // spu_printf("nextBatch = %d\n",nextBatch);
605 
606  for (int j=0;j<nextBatch;j++)
607  {
608  const btBvhSubtreeInfo& subtree = lsMemPtr->bvhShapeData.gSubtreeHeaders[j];
609 
610  unsigned int overlap = spuTestQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,subtree.m_quantizedAabbMin,subtree.m_quantizedAabbMax);
611  if (overlap)
612  {
613  btAssert(subtree.m_subtreeSize);
614 
615  //dma the actual nodes of this subtree
616  dmaBvhSubTreeNodes (&lsMemPtr->bvhShapeData.gSubtreeNodes[0], subtree, nodeArray, 2);
618 
619  /* Walk this subtree */
620  spuWalkStacklessQuantizedTree(&nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax,
621  &lsMemPtr->bvhShapeData.gSubtreeNodes[0],
622  0,
623  subtree.m_subtreeSize);
624  }
625  // spu_printf("subtreeSize = %d\n",gSubtreeHeaders[j].m_subtreeSize);
626  }
627 
628  // unsigned short int m_quantizedAabbMin[3];
629  // unsigned short int m_quantizedAabbMax[3];
630  // int m_rootNodeIndex;
631  // int m_subtreeSize;
632  i+=nextBatch;
633  }
634 
635  //pre-fetch first tree, then loop and double buffer
636  }
637 
638 }
639 
640 
641 #define MAX_DEGENERATE_STATS 15
642 int stats[MAX_DEGENERATE_STATS]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
643 int degenerateStats[MAX_DEGENERATE_STATS]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
644 
645 
650 {
651  register int dmaSize;
652  register ppu_address_t dmaPpuAddress2;
653 
654 #ifdef DEBUG_SPU_COLLISION_DETECTION
655  //spu_printf("SPU: ProcessSpuConvexConvexCollision\n");
656 #endif //DEBUG_SPU_COLLISION_DETECTION
657  //CollisionShape* shape0 = (CollisionShape*)wuInput->m_collisionShapes[0];
658  //CollisionShape* shape1 = (CollisionShape*)wuInput->m_collisionShapes[1];
660 
661  bool genericGjk = true;
662 
663  if (genericGjk)
664  {
665  //try generic GJK
666 
667 
668 
669  //SpuConvexPenetrationDepthSolver* penetrationSolver=0;
670  btVoronoiSimplexSolver simplexSolver;
671  btGjkEpaPenetrationDepthSolver epaPenetrationSolver2;
672 
673  btConvexPenetrationDepthSolver* penetrationSolver = &epaPenetrationSolver2;
674 
675  //SpuMinkowskiPenetrationDepthSolver minkowskiPenetrationSolver;
676 #ifdef ENABLE_EPA
677  if (gUseEpa)
678  {
679  penetrationSolver = &epaPenetrationSolver2;
680  } else
681 #endif
682  {
683  //penetrationSolver = &minkowskiPenetrationSolver;
684  }
685 
686 
688  ATTRIBUTE_ALIGNED16(char convexHullShape0[sizeof(btConvexHullShape)]);
689  ATTRIBUTE_ALIGNED16(char convexHullShape1[sizeof(btConvexHullShape)]);
690 
692  {
693  // spu_printf("SPU: DMA btConvexHullShape\n");
694 
695  dmaSize = sizeof(btConvexHullShape);
696  dmaPpuAddress2 = wuInput->m_collisionShapes[0];
697 
698  cellDmaGet(&convexHullShape0, dmaPpuAddress2 , dmaSize, DMA_TAG(1), 0, 0);
699  //cellDmaWaitTagStatusAll(DMA_MASK(1));
700  }
701 
703  {
704  // spu_printf("SPU: DMA btConvexHullShape\n");
705  dmaSize = sizeof(btConvexHullShape);
706  dmaPpuAddress2 = wuInput->m_collisionShapes[1];
707  cellDmaGet(&convexHullShape1, dmaPpuAddress2 , dmaSize, DMA_TAG(1), 0, 0);
708  //cellDmaWaitTagStatusAll(DMA_MASK(1));
709  }
710 
712  {
714  dmaConvexVertexData (&lsMemPtr->convexVertexData[0], (btConvexHullShape*)&convexHullShape0);
715  lsMemPtr->convexVertexData[0].gSpuConvexShapePtr = wuInput->m_spuCollisionShapes[0];
716  }
717 
718 
720  {
722  dmaConvexVertexData (&lsMemPtr->convexVertexData[1], (btConvexHullShape*)&convexHullShape1);
723  lsMemPtr->convexVertexData[1].gSpuConvexShapePtr = wuInput->m_spuCollisionShapes[1];
724  }
725 
726 
727  btConvexPointCloudShape cpc0,cpc1;
728 
730  {
732  lsMemPtr->convexVertexData[0].gConvexPoints = &lsMemPtr->convexVertexData[0].g_convexPointBuffer[0];
734  const btVector3& localScaling = ch->getLocalScalingNV();
735  cpc0.setPoints(lsMemPtr->convexVertexData[0].gConvexPoints,lsMemPtr->convexVertexData[0].gNumConvexPoints,false,localScaling);
736  wuInput->m_spuCollisionShapes[0] = &cpc0;
737  }
738 
740  {
742  lsMemPtr->convexVertexData[1].gConvexPoints = &lsMemPtr->convexVertexData[1].g_convexPointBuffer[0];
744  const btVector3& localScaling = ch->getLocalScalingNV();
745  cpc1.setPoints(lsMemPtr->convexVertexData[1].gConvexPoints,lsMemPtr->convexVertexData[1].gNumConvexPoints,false,localScaling);
746  wuInput->m_spuCollisionShapes[1] = &cpc1;
747 
748  }
749 
750 
751  const btConvexShape* shape0Ptr = (const btConvexShape*)wuInput->m_spuCollisionShapes[0];
752  const btConvexShape* shape1Ptr = (const btConvexShape*)wuInput->m_spuCollisionShapes[1];
753  int shapeType0 = wuInput->m_shapeType0;
754  int shapeType1 = wuInput->m_shapeType1;
755  float marginA = wuInput->m_collisionMargin0;
756  float marginB = wuInput->m_collisionMargin1;
757 
758  SpuClosestPointInput cpInput;
759  cpInput.m_convexVertexData[0] = &lsMemPtr->convexVertexData[0];
760  cpInput.m_convexVertexData[1] = &lsMemPtr->convexVertexData[1];
761  cpInput.m_transformA = wuInput->m_worldTransform0;
762  cpInput.m_transformB = wuInput->m_worldTransform1;
763  float sumMargin = (marginA+marginB+lsMemPtr->getContactManifoldPtr()->getContactBreakingThreshold());
764  cpInput.m_maximumDistanceSquared = sumMargin * sumMargin;
765 
766  ppu_address_t manifoldAddress = (ppu_address_t)manifold;
767 
768  btPersistentManifold* spuManifold=lsMemPtr->getContactManifoldPtr();
769  //spuContacts.setContactInfo(spuManifold,manifoldAddress,wuInput->m_worldTransform0,wuInput->m_worldTransform1,wuInput->m_isSwapped);
770  spuContacts.setContactInfo(spuManifold,manifoldAddress,lsMemPtr->getColObj0()->getWorldTransform(),
771  lsMemPtr->getColObj1()->getWorldTransform(),
772  lsMemPtr->getColObj0()->getRestitution(),lsMemPtr->getColObj1()->getRestitution(),
773  lsMemPtr->getColObj0()->getFriction(),lsMemPtr->getColObj1()->getFriction(),
774  wuInput->m_isSwapped);
775 
776  {
777  btGjkPairDetector gjk(shape0Ptr,shape1Ptr,shapeType0,shapeType1,marginA,marginB,&simplexSolver,penetrationSolver);//&vsSolver,penetrationSolver);
778  gjk.getClosestPoints(cpInput,spuContacts,0);//,debugDraw);
779 
781  stats[gjk.m_lastUsedMethod]++;
783  degenerateStats[gjk.m_degenerateSimplex]++;
784 
785 #ifdef USE_SEPDISTANCE_UTIL
787  lsMemPtr->getlocalCollisionAlgorithm()->m_sepDistance.initSeparatingDistance(gjk.getCachedSeparatingAxis(),sepDist,wuInput->m_worldTransform0,wuInput->m_worldTransform1);
788  lsMemPtr->needsDmaPutContactManifoldAlgo = true;
789 #endif //USE_SEPDISTANCE_UTIL
790 
791  }
792 
793  }
794 
795 
796 }
797 
798 
799 template<typename T> void DoSwap(T& a, T& b)
800 {
801  char tmp[sizeof(T)];
802  memcpy(tmp, &a, sizeof(T));
803  memcpy(&a, &b, sizeof(T));
804  memcpy(&b, tmp, sizeof(T));
805 }
806 
808 {
809  register int dmaSize;
810  register ppu_address_t dmaPpuAddress2;
811 
812  dmaSize = sizeof(btCollisionObject);//btTransform);
813  dmaPpuAddress2 = /*collisionPairInput.m_isSwapped ? (ppu_address_t)lsMem.gProxyPtr1->m_clientObject :*/ (ppu_address_t)lsMem.getlocalCollisionAlgorithm()->getCollisionObject0();
814  lsMem.m_lsColObj0Ptr = (btCollisionObject*)cellDmaGetReadOnly(&lsMem.gColObj0Buffer, dmaPpuAddress2 , dmaSize, DMA_TAG(1), 0, 0);
815 
816  dmaSize = sizeof(btCollisionObject);//btTransform);
817  dmaPpuAddress2 = /*collisionPairInput.m_isSwapped ? (ppu_address_t)lsMem.gProxyPtr0->m_clientObject :*/ (ppu_address_t)lsMem.getlocalCollisionAlgorithm()->getCollisionObject1();
818  lsMem.m_lsColObj1Ptr = (btCollisionObject*)cellDmaGetReadOnly(&lsMem.gColObj1Buffer, dmaPpuAddress2 , dmaSize, DMA_TAG(2), 0, 0);
819 
821 
822  btCollisionObject* ob0 = lsMem.getColObj0();
823  btCollisionObject* ob1 = lsMem.getColObj1();
824 
825  collisionPairInput.m_worldTransform0 = ob0->getWorldTransform();
826  collisionPairInput.m_worldTransform1 = ob1->getWorldTransform();
827 }
828 
829 
830 
832  SpuContactResult &spuContacts,
833  ppu_address_t collisionShape0Ptr, void* collisionShape0Loc,
834  ppu_address_t collisionShape1Ptr, void* collisionShape1Loc, bool dmaShapes = true)
835 {
836 
837  if (btBroadphaseProxy::isConvex(collisionPairInput.m_shapeType0)
838  && btBroadphaseProxy::isConvex(collisionPairInput.m_shapeType1))
839  {
840  if (dmaShapes)
841  {
842  dmaCollisionShape (collisionShape0Loc, collisionShape0Ptr, 1, collisionPairInput.m_shapeType0);
843  dmaCollisionShape (collisionShape1Loc, collisionShape1Ptr, 2, collisionPairInput.m_shapeType1);
845  }
846 
847  btConvexInternalShape* spuConvexShape0 = (btConvexInternalShape*)collisionShape0Loc;
848  btConvexInternalShape* spuConvexShape1 = (btConvexInternalShape*)collisionShape1Loc;
849 
850  btVector3 dim0 = spuConvexShape0->getImplicitShapeDimensions();
851  btVector3 dim1 = spuConvexShape1->getImplicitShapeDimensions();
852 
853  collisionPairInput.m_primitiveDimensions0 = dim0;
854  collisionPairInput.m_primitiveDimensions1 = dim1;
855  collisionPairInput.m_collisionShapes[0] = collisionShape0Ptr;
856  collisionPairInput.m_collisionShapes[1] = collisionShape1Ptr;
857  collisionPairInput.m_spuCollisionShapes[0] = spuConvexShape0;
858  collisionPairInput.m_spuCollisionShapes[1] = spuConvexShape1;
859  ProcessSpuConvexConvexCollision(&collisionPairInput,&lsMem,spuContacts);
860  }
861  else if (btBroadphaseProxy::isCompound(collisionPairInput.m_shapeType0) &&
862  btBroadphaseProxy::isCompound(collisionPairInput.m_shapeType1))
863  {
864  //snPause();
865 
866  dmaCollisionShape (collisionShape0Loc, collisionShape0Ptr, 1, collisionPairInput.m_shapeType0);
867  dmaCollisionShape (collisionShape1Loc, collisionShape1Ptr, 2, collisionPairInput.m_shapeType1);
869 
870  // Both are compounds, do N^2 CD for now
872 
873  btCompoundShape* spuCompoundShape0 = (btCompoundShape*)collisionShape0Loc;
874  btCompoundShape* spuCompoundShape1 = (btCompoundShape*)collisionShape1Loc;
875 
876  dmaCompoundShapeInfo (&lsMem.compoundShapeData[0], spuCompoundShape0, 1);
877  dmaCompoundShapeInfo (&lsMem.compoundShapeData[1], spuCompoundShape1, 2);
879 
880 
881  dmaCompoundSubShapes (&lsMem.compoundShapeData[0], spuCompoundShape0, 1);
883  dmaCompoundSubShapes (&lsMem.compoundShapeData[1], spuCompoundShape1, 1);
885 
886  int childShapeCount0 = spuCompoundShape0->getNumChildShapes();
887  btAssert(childShapeCount0< MAX_SPU_COMPOUND_SUBSHAPES);
888  int childShapeCount1 = spuCompoundShape1->getNumChildShapes();
889  btAssert(childShapeCount1< MAX_SPU_COMPOUND_SUBSHAPES);
890 
891  // Start the N^2
892  for (int i = 0; i < childShapeCount0; ++i)
893  {
894  btCompoundShapeChild& childShape0 = lsMem.compoundShapeData[0].gSubshapes[i];
896 
897  for (int j = 0; j < childShapeCount1; ++j)
898  {
899  btCompoundShapeChild& childShape1 = lsMem.compoundShapeData[1].gSubshapes[j];
901 
902 
903  /* Create a new collision pair input struct using the two child shapes */
904  SpuCollisionPairInput cinput (collisionPairInput);
905 
906  cinput.m_worldTransform0 = collisionPairInput.m_worldTransform0 * childShape0.m_transform;
907  cinput.m_shapeType0 = childShape0.m_childShapeType;
908  cinput.m_collisionMargin0 = childShape0.m_childMargin;
909 
910  cinput.m_worldTransform1 = collisionPairInput.m_worldTransform1 * childShape1.m_transform;
911  cinput.m_shapeType1 = childShape1.m_childShapeType;
912  cinput.m_collisionMargin1 = childShape1.m_childMargin;
913  /* Recursively call handleCollisionPair () with new collision pair input */
914 
915  handleCollisionPair(cinput, lsMem, spuContacts,
916  (ppu_address_t)childShape0.m_childShape, lsMem.compoundShapeData[0].gSubshapeShape[i],
917  (ppu_address_t)childShape1.m_childShape, lsMem.compoundShapeData[1].gSubshapeShape[j], false);
918  }
919  }
920  }
921  else if (btBroadphaseProxy::isCompound(collisionPairInput.m_shapeType0) )
922  {
923  //snPause();
924 
925  dmaCollisionShape (collisionShape0Loc, collisionShape0Ptr, 1, collisionPairInput.m_shapeType0);
926  dmaCollisionShape (collisionShape1Loc, collisionShape1Ptr, 2, collisionPairInput.m_shapeType1);
928 
929  // object 0 compound, object 1 non-compound
930  btCompoundShape* spuCompoundShape = (btCompoundShape*)collisionShape0Loc;
931  dmaCompoundShapeInfo (&lsMem.compoundShapeData[0], spuCompoundShape, 1);
933 
934  int childShapeCount = spuCompoundShape->getNumChildShapes();
935  btAssert(childShapeCount< MAX_SPU_COMPOUND_SUBSHAPES);
936 
937  for (int i = 0; i < childShapeCount; ++i)
938  {
939  btCompoundShapeChild& childShape = lsMem.compoundShapeData[0].gSubshapes[i];
941  // Dma the child shape
944 
945  SpuCollisionPairInput cinput (collisionPairInput);
946  cinput.m_worldTransform0 = collisionPairInput.m_worldTransform0 * childShape.m_transform;
947  cinput.m_shapeType0 = childShape.m_childShapeType;
948  cinput.m_collisionMargin0 = childShape.m_childMargin;
949 
950  handleCollisionPair(cinput, lsMem, spuContacts,
952  collisionShape1Ptr, collisionShape1Loc, false);
953  }
954  }
955  else if (btBroadphaseProxy::isCompound(collisionPairInput.m_shapeType1) )
956  {
957  //snPause();
958 
959  dmaCollisionShape (collisionShape0Loc, collisionShape0Ptr, 1, collisionPairInput.m_shapeType0);
960  dmaCollisionShape (collisionShape1Loc, collisionShape1Ptr, 2, collisionPairInput.m_shapeType1);
962  // object 0 non-compound, object 1 compound
963  btCompoundShape* spuCompoundShape = (btCompoundShape*)collisionShape1Loc;
964  dmaCompoundShapeInfo (&lsMem.compoundShapeData[0], spuCompoundShape, 1);
966 
967  int childShapeCount = spuCompoundShape->getNumChildShapes();
968  btAssert(childShapeCount< MAX_SPU_COMPOUND_SUBSHAPES);
969 
970 
971  for (int i = 0; i < childShapeCount; ++i)
972  {
973  btCompoundShapeChild& childShape = lsMem.compoundShapeData[0].gSubshapes[i];
975  // Dma the child shape
978 
979  SpuCollisionPairInput cinput (collisionPairInput);
980  cinput.m_worldTransform1 = collisionPairInput.m_worldTransform1 * childShape.m_transform;
981  cinput.m_shapeType1 = childShape.m_childShapeType;
982  cinput.m_collisionMargin1 = childShape.m_childMargin;
983  handleCollisionPair(cinput, lsMem, spuContacts,
984  collisionShape0Ptr, collisionShape0Loc,
985  (ppu_address_t)childShape.m_childShape, lsMem.compoundShapeData[0].gSubshapeShape[i], false);
986  }
987 
988  }
989  else
990  {
991  //a non-convex shape is involved
992  bool handleConvexConcave = false;
993 
994  //snPause();
995 
996  if (btBroadphaseProxy::isConcave(collisionPairInput.m_shapeType0) &&
997  btBroadphaseProxy::isConvex(collisionPairInput.m_shapeType1))
998  {
999  // Swap stuff
1000  DoSwap(collisionShape0Ptr, collisionShape1Ptr);
1001  DoSwap(collisionShape0Loc, collisionShape1Loc);
1002  DoSwap(collisionPairInput.m_shapeType0, collisionPairInput.m_shapeType1);
1003  DoSwap(collisionPairInput.m_worldTransform0, collisionPairInput.m_worldTransform1);
1004  DoSwap(collisionPairInput.m_collisionMargin0, collisionPairInput.m_collisionMargin1);
1005 
1006  collisionPairInput.m_isSwapped = true;
1007  }
1008 
1009  if (btBroadphaseProxy::isConvex(collisionPairInput.m_shapeType0)&&
1010  btBroadphaseProxy::isConcave(collisionPairInput.m_shapeType1))
1011  {
1012  handleConvexConcave = true;
1013  }
1014  if (handleConvexConcave)
1015  {
1016  if (dmaShapes)
1017  {
1018  dmaCollisionShape (collisionShape0Loc, collisionShape0Ptr, 1, collisionPairInput.m_shapeType0);
1019  dmaCollisionShape (collisionShape1Loc, collisionShape1Ptr, 2, collisionPairInput.m_shapeType1);
1021  }
1022 
1023  if (collisionPairInput.m_shapeType1 == STATIC_PLANE_PROXYTYPE)
1024  {
1025  btConvexInternalShape* spuConvexShape0 = (btConvexInternalShape*)collisionShape0Loc;
1026  btStaticPlaneShape* planeShape= (btStaticPlaneShape*)collisionShape1Loc;
1027 
1028  btVector3 dim0 = spuConvexShape0->getImplicitShapeDimensions();
1029  collisionPairInput.m_primitiveDimensions0 = dim0;
1030  collisionPairInput.m_collisionShapes[0] = collisionShape0Ptr;
1031  collisionPairInput.m_collisionShapes[1] = collisionShape1Ptr;
1032  collisionPairInput.m_spuCollisionShapes[0] = spuConvexShape0;
1033  collisionPairInput.m_spuCollisionShapes[1] = planeShape;
1034 
1035  ProcessConvexPlaneSpuCollision(&collisionPairInput,&lsMem,spuContacts);
1036  } else
1037  {
1038  btConvexInternalShape* spuConvexShape0 = (btConvexInternalShape*)collisionShape0Loc;
1039  btBvhTriangleMeshShape* trimeshShape = (btBvhTriangleMeshShape*)collisionShape1Loc;
1040 
1041  btVector3 dim0 = spuConvexShape0->getImplicitShapeDimensions();
1042  collisionPairInput.m_primitiveDimensions0 = dim0;
1043  collisionPairInput.m_collisionShapes[0] = collisionShape0Ptr;
1044  collisionPairInput.m_collisionShapes[1] = collisionShape1Ptr;
1045  collisionPairInput.m_spuCollisionShapes[0] = spuConvexShape0;
1046  collisionPairInput.m_spuCollisionShapes[1] = trimeshShape;
1047 
1048  ProcessConvexConcaveSpuCollision(&collisionPairInput,&lsMem,spuContacts);
1049  }
1050  }
1051 
1052  }
1053 
1054  spuContacts.flush();
1055 
1056 }
1057 
1058 
1059 void processCollisionTask(void* userPtr, void* lsMemPtr)
1060 {
1061 
1063  SpuGatherAndProcessPairsTaskDesc& taskDesc = *taskDescPtr;
1065  CollisionTask_LocalStoreMemory& lsMem = *(colMemPtr);
1066 
1067  gUseEpa = taskDesc.m_useEpa;
1068 
1069  // spu_printf("taskDescPtr=%llx\n",taskDescPtr);
1070 
1071  SpuContactResult spuContacts;
1072 
1074 
1075  ppu_address_t dmaInPtr = taskDesc.m_inPairPtr;
1076  unsigned int numPages = taskDesc.numPages;
1077  unsigned int numOnLastPage = taskDesc.numOnLastPage;
1078 
1079  // prefetch first set of inputs and wait
1080  lsMem.g_workUnitTaskBuffers.init();
1081 
1082  unsigned int nextNumOnPage = (numPages > 1)? MIDPHASE_NUM_WORKUNITS_PER_PAGE : numOnLastPage;
1083  lsMem.g_workUnitTaskBuffers.backBufferDmaGet(dmaInPtr, nextNumOnPage*sizeof(SpuGatherAndProcessWorkUnitInput), DMA_TAG(3));
1084  dmaInPtr += MIDPHASE_WORKUNIT_PAGE_SIZE;
1085 
1086 
1087  register unsigned char *inputPtr;
1088  register unsigned int numOnPage;
1089  register unsigned int j;
1091  register int dmaSize;
1092  register ppu_address_t dmaPpuAddress;
1093  register ppu_address_t dmaPpuAddress2;
1094 
1095  int numPairs;
1096  register int p;
1097  SpuCollisionPairInput collisionPairInput;
1098 
1099  for (unsigned int i = 0; btLikely(i < numPages); i++)
1100  {
1101 
1102  // wait for back buffer dma and swap buffers
1103  inputPtr = lsMem.g_workUnitTaskBuffers.swapBuffers();
1104 
1105  // number on current page is number prefetched last iteration
1106  numOnPage = nextNumOnPage;
1107 
1108 
1109  // prefetch next set of inputs
1110 #if MIDPHASE_NUM_WORKUNIT_PAGES > 2
1111  if ( btLikely( i < numPages-1 ) )
1112 #else
1113  if ( btUnlikely( i < numPages-1 ) )
1114 #endif
1115  {
1116  nextNumOnPage = (i == numPages-2)? numOnLastPage : MIDPHASE_NUM_WORKUNITS_PER_PAGE;
1117  lsMem.g_workUnitTaskBuffers.backBufferDmaGet(dmaInPtr, nextNumOnPage*sizeof(SpuGatherAndProcessWorkUnitInput), DMA_TAG(3));
1118  dmaInPtr += MIDPHASE_WORKUNIT_PAGE_SIZE;
1119  }
1120 
1121  wuInputs = reinterpret_cast<SpuGatherAndProcessWorkUnitInput *>(inputPtr);
1122 
1123 
1124  for (j = 0; btLikely( j < numOnPage ); j++)
1125  {
1126 #ifdef DEBUG_SPU_COLLISION_DETECTION
1127  // printMidphaseInput(&wuInputs[j]);
1128 #endif //DEBUG_SPU_COLLISION_DETECTION
1129 
1130 
1131  numPairs = wuInputs[j].m_endIndex - wuInputs[j].m_startIndex;
1132 
1133  if ( btLikely( numPairs ) )
1134  {
1135  dmaSize = numPairs*sizeof(btBroadphasePair);
1136  dmaPpuAddress = wuInputs[j].m_pairArrayPtr+wuInputs[j].m_startIndex * sizeof(btBroadphasePair);
1137  lsMem.m_pairsPointer = (btBroadphasePair*)cellDmaGetReadOnly(&lsMem.gBroadphasePairsBuffer, dmaPpuAddress , dmaSize, DMA_TAG(1), 0, 0);
1139 
1140 
1141  for (p=0;p<numPairs;p++)
1142  {
1143 
1144  //for each broadphase pair, do something
1145 
1146  btBroadphasePair& pair = lsMem.getBroadphasePairPtr()[p];
1147 #ifdef DEBUG_SPU_COLLISION_DETECTION
1148  spu_printf("pair->m_userInfo = %d\n",pair.m_userInfo);
1149  spu_printf("pair->m_algorithm = %d\n",pair.m_algorithm);
1150  spu_printf("pair->m_pProxy0 = %d\n",pair.m_pProxy0);
1151  spu_printf("pair->m_pProxy1 = %d\n",pair.m_pProxy1);
1152 #endif //DEBUG_SPU_COLLISION_DETECTION
1153 
1154  if (pair.m_internalTmpValue == 2 && pair.m_algorithm && pair.m_pProxy0 && pair.m_pProxy1)
1155  {
1156  dmaSize = sizeof(SpuContactManifoldCollisionAlgorithm);
1157  dmaPpuAddress2 = (ppu_address_t)pair.m_algorithm;
1159 
1161 
1162  lsMem.needsDmaPutContactManifoldAlgo = false;
1163 
1165  collisionPairInput.m_isSwapped = false;
1166 
1167  if (1)
1168  {
1169 
1171 
1172 
1173 #ifdef DEBUG_SPU_COLLISION_DETECTION
1174  // spu_printf("SPU collisionPairInput->m_shapeType0 = %d\n",collisionPairInput->m_shapeType0);
1175  // spu_printf("SPU collisionPairInput->m_shapeType1 = %d\n",collisionPairInput->m_shapeType1);
1176 #endif //DEBUG_SPU_COLLISION_DETECTION
1177 
1178 
1179  dmaSize = sizeof(btPersistentManifold);
1180 
1181  dmaPpuAddress2 = collisionPairInput.m_persistentManifoldPtr;
1182  lsMem.m_lsManifoldPtr = (btPersistentManifold*)cellDmaGetReadOnly(&lsMem.gPersistentManifoldBuffer, dmaPpuAddress2 , dmaSize, DMA_TAG(1), 0, 0);
1183 
1184  collisionPairInput.m_shapeType0 = lsMem.getlocalCollisionAlgorithm()->getShapeType0();
1185  collisionPairInput.m_shapeType1 = lsMem.getlocalCollisionAlgorithm()->getShapeType1();
1186  collisionPairInput.m_collisionMargin0 = lsMem.getlocalCollisionAlgorithm()->getCollisionMargin0();
1187  collisionPairInput.m_collisionMargin1 = lsMem.getlocalCollisionAlgorithm()->getCollisionMargin1();
1188 
1189 
1190 
1191  //??cellDmaWaitTagStatusAll(DMA_MASK(1));
1192 
1193 
1194  if (1)
1195  {
1196  //snPause();
1197 
1198  // Get the collision objects
1199  dmaAndSetupCollisionObjects(collisionPairInput, lsMem);
1200 
1201  if (lsMem.getColObj0()->isActive() || lsMem.getColObj1()->isActive())
1202  {
1203 
1204  lsMem.needsDmaPutContactManifoldAlgo = true;
1205 #ifdef USE_SEPDISTANCE_UTIL
1206  lsMem.getlocalCollisionAlgorithm()->m_sepDistance.updateSeparatingDistance(collisionPairInput.m_worldTransform0,collisionPairInput.m_worldTransform1);
1207 #endif //USE_SEPDISTANCE_UTIL
1208 
1209 #define USE_DEDICATED_BOX_BOX 1
1210 #ifdef USE_DEDICATED_BOX_BOX
1211  bool boxbox = ((lsMem.getlocalCollisionAlgorithm()->getShapeType0()==BOX_SHAPE_PROXYTYPE)&&
1213  if (boxbox)
1214  {
1215  //spu_printf("boxbox dist = %f\n",distance);
1216  btPersistentManifold* spuManifold=lsMem.getContactManifoldPtr();
1217  btPersistentManifold* manifold = (btPersistentManifold*)collisionPairInput.m_persistentManifoldPtr;
1218  ppu_address_t manifoldAddress = (ppu_address_t)manifold;
1219 
1220  spuContacts.setContactInfo(spuManifold,manifoldAddress,lsMem.getColObj0()->getWorldTransform(),
1221  lsMem.getColObj1()->getWorldTransform(),
1222  lsMem.getColObj0()->getRestitution(),lsMem.getColObj1()->getRestitution(),
1223  lsMem.getColObj0()->getFriction(),lsMem.getColObj1()->getFriction(),
1224  collisionPairInput.m_isSwapped);
1225 
1226 
1227  //float distance=0.f;
1228  btVector3 normalInB;
1229 
1230 
1231  if (
1232 #ifdef USE_SEPDISTANCE_UTIL
1233  lsMem.getlocalCollisionAlgorithm()->m_sepDistance.getConservativeSeparatingDistance()<=0.f
1234 #else
1235  1
1236 #endif
1237  )
1238  {
1239 //#define USE_PE_BOX_BOX 1
1240 #ifdef USE_PE_BOX_BOX
1241  {
1242 
1243  //getCollisionMargin0
1246  btVector3 shapeDim0 = lsMem.getlocalCollisionAlgorithm()->getShapeDimensions0()+btVector3(margin0,margin0,margin0);
1247  btVector3 shapeDim1 = lsMem.getlocalCollisionAlgorithm()->getShapeDimensions1()+btVector3(margin1,margin1,margin1);
1248 /*
1249  //Box boxA(shapeDim0.getX(),shapeDim0.getY(),shapeDim0.getZ());
1250  vmVector3 vmPos0 = getVmVector3(collisionPairInput.m_worldTransform0.getOrigin());
1251  vmVector3 vmPos1 = getVmVector3(collisionPairInput.m_worldTransform1.getOrigin());
1252  vmMatrix3 vmMatrix0 = getVmMatrix3(collisionPairInput.m_worldTransform0.getBasis());
1253  vmMatrix3 vmMatrix1 = getVmMatrix3(collisionPairInput.m_worldTransform1.getBasis());
1254 
1255  vmTransform3 transformA(vmMatrix0,vmPos0);
1256  Box boxB(shapeDim1.getX(),shapeDim1.getY(),shapeDim1.getZ());
1257  vmTransform3 transformB(vmMatrix1,vmPos1);
1258  BoxPoint resultClosestBoxPointA;
1259  BoxPoint resultClosestBoxPointB;
1260  vmVector3 resultNormal;
1261  */
1262 
1263 #ifdef USE_SEPDISTANCE_UTIL
1264  float distanceThreshold = FLT_MAX
1265 #else
1266  //float distanceThreshold = 0.f;
1267 #endif
1268 
1269 
1270  vmVector3 n;
1271  Box boxA;
1272  vmVector3 hA(shapeDim0.getX(),shapeDim0.getY(),shapeDim0.getZ());
1273  vmVector3 hB(shapeDim1.getX(),shapeDim1.getY(),shapeDim1.getZ());
1274  boxA.mHalf= hA;
1275  vmTransform3 trA;
1276  trA.setTranslation(getVmVector3(collisionPairInput.m_worldTransform0.getOrigin()));
1277  trA.setUpper3x3(getVmMatrix3(collisionPairInput.m_worldTransform0.getBasis()));
1278  Box boxB;
1279  boxB.mHalf = hB;
1280  vmTransform3 trB;
1281  trB.setTranslation(getVmVector3(collisionPairInput.m_worldTransform1.getOrigin()));
1282  trB.setUpper3x3(getVmMatrix3(collisionPairInput.m_worldTransform1.getBasis()));
1283 
1284  float distanceThreshold = spuManifold->getContactBreakingThreshold();//0.001f;
1285 
1286 
1287  BoxPoint ptA,ptB;
1288  float dist = boxBoxDistance(n, ptA, ptB,
1289  boxA, trA, boxB, trB,
1290  distanceThreshold );
1291 
1292 
1293 // float distance = boxBoxDistance(resultNormal,resultClosestBoxPointA,resultClosestBoxPointB, boxA, transformA, boxB,transformB,distanceThreshold);
1294 
1295  normalInB = -getBtVector3(n);//resultNormal);
1296 
1297  //if(dist < distanceThreshold)//spuManifold->getContactBreakingThreshold())
1298  if(dist < spuManifold->getContactBreakingThreshold())
1299  {
1300  btVector3 pointOnB = collisionPairInput.m_worldTransform1(getBtVector3(ptB.localPoint));
1301 
1302  spuContacts.addContactPoint(
1303  normalInB,
1304  pointOnB,
1305  dist);
1306  }
1307  }
1308 #else
1309  {
1310 
1313  btVector3 shapeDim0 = lsMem.getlocalCollisionAlgorithm()->getShapeDimensions0()+btVector3(margin0,margin0,margin0);
1314  btVector3 shapeDim1 = lsMem.getlocalCollisionAlgorithm()->getShapeDimensions1()+btVector3(margin1,margin1,margin1);
1315 
1316 
1317  btBoxShape box0(shapeDim0);
1318  btBoxShape box1(shapeDim1);
1319 
1320  struct SpuBridgeContactCollector : public btDiscreteCollisionDetectorInterface::Result
1321  {
1322  SpuContactResult& m_spuContacts;
1323 
1324  virtual void setShapeIdentifiersA(int partId0,int index0)
1325  {
1326  m_spuContacts.setShapeIdentifiersA(partId0,index0);
1327  }
1328  virtual void setShapeIdentifiersB(int partId1,int index1)
1329  {
1330  m_spuContacts.setShapeIdentifiersB(partId1,index1);
1331  }
1332  virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)
1333  {
1334  m_spuContacts.addContactPoint(normalOnBInWorld,pointInWorld,depth);
1335  }
1336 
1337  SpuBridgeContactCollector(SpuContactResult& spuContacts)
1338  :m_spuContacts(spuContacts)
1339  {
1340 
1341  }
1342  };
1343 
1344  SpuBridgeContactCollector bridgeOutput(spuContacts);
1345 
1348  input.m_transformA = collisionPairInput.m_worldTransform0;
1349  input.m_transformB = collisionPairInput.m_worldTransform1;
1350 
1351  btBoxBoxDetector detector(&box0,&box1);
1352 
1353  detector.getClosestPoints(input,bridgeOutput,0);
1354 
1355  }
1356 #endif //USE_PE_BOX_BOX
1357 
1358  lsMem.needsDmaPutContactManifoldAlgo = true;
1359 #ifdef USE_SEPDISTANCE_UTIL
1360  btScalar sepDist2 = distance+spuManifold->getContactBreakingThreshold();
1361  lsMem.getlocalCollisionAlgorithm()->m_sepDistance.initSeparatingDistance(normalInB,sepDist2,collisionPairInput.m_worldTransform0,collisionPairInput.m_worldTransform1);
1362 #endif //USE_SEPDISTANCE_UTIL
1363  gProcessedCol++;
1364  } else
1365  {
1366  gSkippedCol++;
1367  }
1368 
1369  spuContacts.flush();
1370 
1371 
1372  } else
1373 #endif //USE_DEDICATED_BOX_BOX
1374  {
1375  if (
1376 #ifdef USE_SEPDISTANCE_UTIL
1377  lsMem.getlocalCollisionAlgorithm()->m_sepDistance.getConservativeSeparatingDistance()<=0.f
1378 #else
1379  1
1380 #endif //USE_SEPDISTANCE_UTIL
1381  )
1382  {
1383  handleCollisionPair(collisionPairInput, lsMem, spuContacts,
1386  } else
1387  {
1388  //spu_printf("boxbox dist = %f\n",distance);
1389  btPersistentManifold* spuManifold=lsMem.getContactManifoldPtr();
1390  btPersistentManifold* manifold = (btPersistentManifold*)collisionPairInput.m_persistentManifoldPtr;
1391  ppu_address_t manifoldAddress = (ppu_address_t)manifold;
1392 
1393  spuContacts.setContactInfo(spuManifold,manifoldAddress,lsMem.getColObj0()->getWorldTransform(),
1394  lsMem.getColObj1()->getWorldTransform(),
1395  lsMem.getColObj0()->getRestitution(),lsMem.getColObj1()->getRestitution(),
1396  lsMem.getColObj0()->getFriction(),lsMem.getColObj1()->getFriction(),
1397  collisionPairInput.m_isSwapped);
1398 
1399  spuContacts.flush();
1400  }
1401  }
1402 
1403  }
1404 
1405  }
1406  }
1407 
1408 #ifdef USE_SEPDISTANCE_UTIL
1409 #if defined (__SPU__) || defined (USE_LIBSPE2)
1411  {
1412  dmaSize = sizeof(SpuContactManifoldCollisionAlgorithm);
1413  dmaPpuAddress2 = (ppu_address_t)pair.m_algorithm;
1414  cellDmaLargePut(&lsMem.gSpuContactManifoldAlgoBuffer, dmaPpuAddress2 , dmaSize, DMA_TAG(1), 0, 0);
1416  }
1417 #endif
1418 #endif //#ifdef USE_SEPDISTANCE_UTIL
1419 
1420  }
1421  }
1422  }
1423  } //end for (j = 0; j < numOnPage; j++)
1424 
1425  }// for
1426 
1427 
1428 
1429  return;
1430 }
1431 
1432 
void dmaCompoundShapeInfo(CompoundShape_LocalStoreMemory *compoundShapeLocation, btCompoundShape *spuCompoundShape, uint32_t dmaTag)
char gColObj1Buffer[sizeof(btCollisionObject)+16]
void dmaAndSetupCollisionObjects(SpuCollisionPairInput &collisionPairInput, CollisionTask_LocalStoreMemory &lsMem)
const btVector3 & getLocalScalingNV() const
btPersistentManifold is a contact point cache, it stays persistent as long as objects are overlapping...
void push_back(const T &_Val)
void computeAabb(btVector3 &aabbMin, btVector3 &aabbMax, btConvexInternalShape *convexShape, ppu_address_t convexShapePtr, int shapeType, const btTransform &xform)
not supported on IBM SDK, until we fix the alignment of btVector3
bvhMeshShape_LocalStoreMemory bvhShapeData
char gSpuContactManifoldAlgoBuffer[sizeof(SpuContactManifoldCollisionAlgorithm)+16]
#define BT_LARGE_FLOAT
Definition: btScalar.h:268
void quantizeWithClamp(unsigned short *out, const btVector3 &point2, int isMax) const
btBroadphasePair gBroadphasePairsBuffer[128]
This CollisionTask_LocalStoreMemory is mainly used for the SPU version, using explicit DMA Other plat...
SpuContactManifoldCollisionAlgorithm * getlocalCollisionAlgorithm()
ppu_address_t m_persistentManifoldPtr
vmPoint3 localPoint
Definition: Box.h:98
btBoxBoxDetector wraps the ODE box-box collision detector re-distributed under the Zlib license with ...
Transform3 & setTranslation(const Vector3 &translateVec)
btBvhSubtreeInfo gSubtreeHeaders[32]
int cellDmaGet(void *ls, uint64_t ea, uint32_t size, uint32_t tag, uint32_t tid, uint32_t rid)
Definition: SpuFakeDma.cpp:173
The btAlignedObjectArray template class uses a subset of the stl::vector interface for its methods It...
float dist(const Point3 &pnt0, const Point3 &pnt1)
btScalar getContactBreakingThreshold() const
void dmaCompoundSubShapes(CompoundShape_LocalStoreMemory *compoundShapeLocation, btCompoundShape *spuCompoundShape, uint32_t dmaTag)
CollisionTask_LocalStoreMemory * m_lsMemPtr
ConvexPenetrationDepthSolver provides an interface for penetration depth calculation.
btScalar getCachedSeparatingDistance() const
DoubleBuffer< unsigned char, MIDPHASE_WORKUNIT_PAGE_SIZE > g_workUnitTaskBuffers
bool gUseEpa
software caching
btTransform m_worldTransform0
btTransform m_worldTransform1
The btConvexInternalShape is an internal base class, shared by most convex shape implementations.
SpuCollisionPairInput * m_wuInput
uint32_t ppu_address_t
Task Description for SPU collision detection.
btVector3 m_primitiveDimensions0
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:51
#define DMA_MASK(a)
Definition: SpuFakeDma.h:113
#define btAssert(x)
Definition: btScalar.h:101
const btVector3 & getScaling() const
#define SIMD_FORCE_INLINE
Definition: btScalar.h:58
void dmaBvhSubTreeHeaders(btBvhSubtreeInfo *subTreeHeaders, ppu_address_t subTreePtr, int batchSize, uint32_t dmaTag)
SpuContactResult & m_spuContacts
#define SPU_BATCHSIZE_BROADPHASE_PAIRS
Tuning value to optimized SPU utilization Too small value means Task overhead is large compared to co...
static bool isCompound(int proxyType)
btCollisionShape * m_childShape
void btConvexPlaneCollideSingleContact(SpuCollisionPairInput *wuInput, CollisionTask_LocalStoreMemory *lsMemPtr, SpuContactResult &spuContacts)
SpuContactResult exports the contact points using double-buffered DMA transfers, only when needed So ...
#define DMA_TAG(a)
Definition: SpuFakeDma.h:112
int stallingUnalignedDmaSmallGet(void *ls, uint64_t ea, uint32_t size)
this unalignedDma should not be frequently used, only for small data. It handles alignment and perfor...
Definition: SpuFakeDma.cpp:62
btQuantizedBvhNode gSubtreeNodes[2048/sizeof(btQuantizedBvhNode)]
void handleCollisionPair(SpuCollisionPairInput &collisionPairInput, CollisionTask_LocalStoreMemory &lsMem, SpuContactResult &spuContacts, ppu_address_t collisionShape0Ptr, void *collisionShape0Loc, ppu_address_t collisionShape1Ptr, void *collisionShape1Loc, bool dmaShapes=true)
int degenerateStats[MAX_DEGENERATE_STATS]
Vectormath::Aos::Vector3 getVmVector3(const btVector3 &bulletVec)
btScalar dot(const btVector3 &v) const
Return the dot product.
Definition: btVector3.h:235
int spuIndices[16]
we reserve 32bit integer indices, even though they might be 16bit
char gColObj0Buffer[sizeof(btCollisionObject)+16]
ppu_address_t m_collisionShapes[2]
btCollisionObject * m_lsColObj0Ptr
The following pointers might either point into this local store memory, or to the original/other memo...
PHY_ScalarType m_indexType
const btScalar & getZ() const
Return the z value.
Definition: btVector3.h:565
The btConvexShape is an abstract shape interface, implemented by all convex shapes such as btBoxShape...
Definition: btConvexShape.h:31
int cellDmaLargePut(const void *ls, uint64_t ea, uint32_t size, uint32_t tag, uint32_t tid, uint32_t rid)
cellDmaLargePut Win32 replacements for Cell DMA to allow simulating most of the SPU code (just memcpy...
Definition: SpuFakeDma.cpp:192
void clear()
clear the array, deallocated memory. Generally it is better to use array.resize(0), to reduce performance overhead of run-time memory (de)allocations.
const btVector3 & getCachedSeparatingAxis() const
void dmaBvhIndexedMesh(btIndexedMesh *IndexMesh, IndexedMeshArray &indexArray, int index, uint32_t dmaTag)
btBvhSubtreeInfo provides info to gather a subtree of limited size
void processCollisionTask(void *userPtr, void *lsMemPtr)
The btBvhTriangleMeshShape is a static-triangle mesh shape, it can only be used for fixed/non-moving ...
void deleteCollisionLocalStoreMemory()
#define btUnlikely(_c)
Definition: btScalar.h:107
void small_cache_read(void *buffer, ppu_address_t ea, size_t size)
btTransform & getWorldTransform()
virtual void setShapeIdentifiersB(int partId1, int index1)=0
int size() const
return the number of elements in the array
btVector3 & getOrigin()
Return the origin vector translation.
Definition: btTransform.h:117
void setPoints(btVector3 *points, int numPoints, bool computeAabb=true, const btVector3 &localScaling=btVector3(1.f, 1.f, 1.f))
#define MAX_DEGENERATE_STATS
btVoronoiSimplexSolver is an implementation of the closest point distance algorithm from a 1-4 points...
#define btLikely(_c)
Definition: btScalar.h:106
MidphaseWorkUnitInput stores individual primitive versus mesh collision detection input...
btIndexedMesh gIndexMesh
only a single mesh part for now, we can add support for multiple parts, but quantized trees don't sup...
vmVector3 mHalf
Definition: Box.h:42
btCollisionShape * m_spuCollisionShapes[2]
btVector3 m_primitiveDimensions1
const btScalar & getY() const
Return the y value.
Definition: btVector3.h:563
#define btAlignedFree(ptr)
btCollisionObject can be used to manage collision detection objects.
btMatrix3x3 & getBasis()
Return the basis matrix for the rotation.
Definition: btTransform.h:112
const btScalar & getX() const
Return the x value.
Definition: btVector3.h:561
void ProcessConvexConcaveSpuCollision(SpuCollisionPairInput *wuInput, CollisionTask_LocalStoreMemory *lsMemPtr, SpuContactResult &spuContacts)
Convex versus Concave triangle mesh collision detection (handles concave triangle mesh versus sphere...
void * cellDmaGetReadOnly(void *ls, uint64_t ea, uint32_t size, uint32_t tag, uint32_t tid, uint32_t rid)
Definition: SpuFakeDma.cpp:50
virtual void getClosestPoints(const ClosestPointInput &input, Result &output, class btIDebugDraw *debugDraw, bool swapResults=false)
void cellDmaWaitTagStatusAll(int ignore)
cellDmaWaitTagStatusAll Win32 replacements for Cell DMA to allow simulating most of the SPU code (jus...
Definition: SpuFakeDma.cpp:210
unsigned int uint32_t
btScalar getRestitution() const
const unsigned char * m_triangleIndexBase
btTransform inverse() const
Return the inverse of this transform.
Definition: btTransform.h:188
btVector3 localGetSupportVertexNonVirtual(const btVector3 &vec) const
btPersistentManifold * getContactManifoldPtr()
btBroadphaseProxy * m_pProxy1
btCollisionAlgorithm * m_algorithm
void * cellDmaSmallGetReadOnly(void *ls, uint64_t ea, uint32_t size, uint32_t tag, uint32_t tid, uint32_t rid)
Definition: SpuFakeDma.cpp:37
The btBoxShape is a box primitive around the origin, its sides axis aligned with length specified by ...
Definition: btBoxShape.h:26
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:83
#define ATTRIBUTE_ALIGNED16(a)
Definition: btScalar.h:59
btBroadphaseProxy * m_pProxy0
void dmaCollisionShape(void *collisionShapeLocation, ppu_address_t collisionShapePtr, uint32_t dmaTag, int shapeType)
#define spu_printf
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:34
void dmaBvhShapeData(bvhMeshShape_LocalStoreMemory *bvhMeshShape, btBvhTriangleMeshShape *triMeshShape)
virtual void addContactPoint(const btVector3 &normalOnBInWorld, const btVector3 &pointInWorld, btScalar depth)
unsigned short int m_quantizedAabbMax[3]
Vectormath::Aos::Matrix3 getVmMatrix3(const btMatrix3x3 &btMat)
CollisionShape_LocalStoreMemory gCollisionShapes[2]
EpaPenetrationDepthSolver uses the Expanding Polytope Algorithm to calculate the penetration depth be...
virtual void addContactPoint(const btVector3 &normalOnBInWorld, const btVector3 &pointInWorld, btScalar depth)=0
btVector3 getBtVector3(const Vectormath::Aos::Vector3 &vmVec)
#define MIDPHASE_NUM_WORKUNITS_PER_PAGE
The Box is an internal class used by the boxBoxDistance calculation.
Definition: Box.h:39
const btVector3 & getImplicitShapeDimensions() const
BvhSubtreeInfoArray & getSubtreeInfoArray()
void ProcessConvexPlaneSpuCollision(SpuCollisionPairInput *wuInput, CollisionTask_LocalStoreMemory *lsMemPtr, SpuContactResult &spuContacts)
Make sure no destructors are called on this memory.
SpuContactManifoldCollisionAlgorithm provides contact manifold and should be processed on SPU...
SpuConvexPolyhedronVertexData convexVertexData[2]
CompoundShape_LocalStoreMemory compoundShapeData[2]
void small_cache_read_triple(void *ls0, ppu_address_t ea0, void *ls1, ppu_address_t ea1, void *ls2, ppu_address_t ea2, size_t size)
btScalar getFriction() const
btGjkPairDetector uses GJK to implement the btDiscreteCollisionDetectorInterface
float boxBoxDistance(vmVector3 &normal, BoxPoint &boxPointA, BoxPoint &boxPointB, PE_REF(Box) boxA, const vmTransform3 &transformA, PE_REF(Box) boxB, const vmTransform3 &transformB, float distanceThreshold)
static bool isConcave(int proxyType)
void spuWalkStacklessQuantizedTree(btNodeOverlapCallback *nodeCallback, unsigned short int *quantizedQueryAabbMin, unsigned short int *quantizedQueryAabbMax, const btQuantizedBvhNode *rootNode, int startNodeIndex, int endNodeIndex)
void backBufferDmaGet(uint64_t ea, unsigned int numBytes, unsigned int tag)
void * createCollisionLocalStoreMemory()
#define btAlignedAlloc(size, alignment)
The btConvexHullShape implements an implicit convex hull of an array of vertices. ...
btTriangleIndexVertexArray * gTriangleMeshInterfacePtr
The btConvexPointCloudShape implements an implicit convex hull of an array of vertices.
The btCompoundShape allows to store multiple other btCollisionShapes This allows for moving concave c...
The BoxPoint class is an internally used class to contain feature information for boxBoxDistance calc...
Definition: Box.h:93
SpuContactManifoldCollisionAlgorithm * m_lsCollisionAlgorithmPtr
void dmaConvexVertexData(SpuConvexPolyhedronVertexData *convexVertexData, btConvexHullShape *convexShapeSPU)
The btStaticPlaneShape simulates an infinite non-moving (static) collision plane. ...
void setContactInfo(btPersistentManifold *spuManifold, ppu_address_t manifoldAddress, const btTransform &worldTrans0, const btTransform &worldTrans1, btScalar restitution0, btScalar restitution1, btScalar friction0, btScalar friction01, bool isSwapped)
btCompoundShapeChild gSubshapes[16]
#define MAX_SPU_COMPOUND_SUBSHAPES
unsigned short int m_quantizedAabbMin[3]
virtual void setShapeIdentifiersA(int partId0, int index0)=0
setShapeIdentifiersA/B provides experimental support for per-triangle material / custom material comb...
void ProcessSpuConvexConvexCollision(SpuCollisionPairInput *wuInput, CollisionTask_LocalStoreMemory *lsMemPtr, SpuContactResult &spuContacts)
Convex versus Convex collision detection (handles collision between sphere, box, cylinder, triangle, cone, convex polyhedron etc)
const btCollisionShape * getCollisionShape() const
unsigned int spuTestQuantizedAabbAgainstQuantizedAabb(unsigned short int *aabbMin1, unsigned short int *aabbMax1, const unsigned short int *aabbMin2, const unsigned short int *aabbMax2)
Transform3 & setUpper3x3(const Matrix3 &mat3)
QuantizedNodeArray & getQuantizedNodeArray()
int stats[MAX_DEGENERATE_STATS]
void DoSwap(T &a, T &b)
void dmaBvhSubTreeNodes(btQuantizedBvhNode *nodes, const btBvhSubtreeInfo &subtree, QuantizedNodeArray &nodeArray, int dmaTag)
#define MIDPHASE_WORKUNIT_PAGE_SIZE
virtual void processNode(int subPart, int triangleIndex)
#define MAX_SPU_SUBTREE_HEADERS
btOptimizedBvh * getOptimizedBvh()
static bool isConvex(int proxyType)
btAlignedObjectArray< CollisionTask_LocalStoreMemory * > sLocalStorePointers
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:266
virtual void setShapeIdentifiersB(int partId1, int index1)
bool isActive() const
struct SpuConvexPolyhedronVertexData * m_convexVertexData[2]
virtual void getClosestPoints(const ClosestPointInput &input, Result &output, class btIDebugDraw *debugDraw, bool swapResults=false)
const unsigned char * m_vertexBase
int getNumChildShapes() const
The btBroadphasePair class contains a pair of aabb-overlapping objects.