SpuGatheringCollisionTask.cpp

Go to the documentation of this file.
00001 /*
00002 Bullet Continuous Collision Detection and Physics Library
00003 Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
00004 
00005 This software is provided 'as-is', without any express or implied warranty.
00006 In no event will the authors be held liable for any damages arising from the use of this software.
00007 Permission is granted to anyone to use this software for any purpose, 
00008 including commercial applications, and to alter it and redistribute it freely, 
00009 subject to the following restrictions:
00010 
00011 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.
00012 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
00013 3. This notice may not be removed or altered from any source distribution.
00014 */
00015 
00016 #include "SpuGatheringCollisionTask.h"
00017 
00018 //#define DEBUG_SPU_COLLISION_DETECTION 1
00019 #include "../SpuDoubleBuffer.h"
00020 
00021 #include "../SpuCollisionTaskProcess.h"
00022 #include "../SpuGatheringCollisionDispatcher.h" //for SPU_BATCHSIZE_BROADPHASE_PAIRS
00023 
00024 #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
00025 #include "../SpuContactManifoldCollisionAlgorithm.h"
00026 #include "BulletCollision/CollisionDispatch/btCollisionObject.h"
00027 #include "SpuContactResult.h"
00028 #include "BulletCollision/CollisionShapes/btOptimizedBvh.h"
00029 #include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h"
00030 #include "BulletCollision/CollisionShapes/btSphereShape.h"
00031 #include "BulletCollision/CollisionShapes/btConvexPointCloudShape.h"
00032 
00033 #include "BulletCollision/CollisionShapes/btCapsuleShape.h"
00034 
00035 #include "BulletCollision/CollisionShapes/btConvexShape.h"
00036 #include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h"
00037 #include "BulletCollision/CollisionShapes/btConvexHullShape.h"
00038 #include "BulletCollision/CollisionShapes/btCompoundShape.h"
00039 
00040 #include "SpuMinkowskiPenetrationDepthSolver.h"
00041 //#include "SpuEpaPenetrationDepthSolver.h"
00042 #include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
00043 
00044 
00045 #include "boxBoxDistance.h"
00046 #include "BulletMultiThreaded/vectormath2bullet.h"
00047 #include "SpuCollisionShapes.h" //definition of SpuConvexPolyhedronVertexData
00048 #include "BulletCollision/CollisionDispatch/btBoxBoxDetector.h"
00049 #include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
00050 #include "BulletCollision/CollisionShapes/btTriangleShape.h"
00051 
00052 #ifdef __SPU__
00054 #ifndef USE_LIBSPE2
00055 #define USE_SOFTWARE_CACHE 1
00056 #endif
00057 #endif //__SPU__
00058 
00059 int gSkippedCol = 0;
00060 int gProcessedCol = 0;
00061 
00064 #if USE_SOFTWARE_CACHE
00065 #include <spu_intrinsics.h>
00066 #include <sys/spu_thread.h>
00067 #include <sys/spu_event.h>
00068 #include <stdint.h>
00069 #define SPE_CACHE_NWAY                  4
00070 //#define SPE_CACHE_NSETS               32, 16
00071 #define SPE_CACHE_NSETS                 8
00072 //#define SPE_CACHELINE_SIZE            512
00073 #define SPE_CACHELINE_SIZE              128
00074 #define SPE_CACHE_SET_TAGID(set)        15
00076 #include "../Extras/software_cache/cache/include/spe_cache.h"
00077 
00078 
00079 int g_CacheMisses=0;
00080 int g_CacheHits=0;
00081 
00082 #if 0 // Added to allow cache misses and hits to be tracked, change this to 1 to restore unmodified version
00083 #define spe_cache_read(ea)              _spe_cache_lookup_xfer_wait_(ea, 0, 1)
00084 #else
00085 #define spe_cache_read(ea)              \
00086 ({                                                              \
00087     int set, idx, line, byte;                                   \
00088     _spe_cache_nway_lookup_(ea, set, idx);                      \
00089                                                                 \
00090     if (btUnlikely(idx < 0)) {                                  \
00091         ++g_CacheMisses;                        \
00092             idx = _spe_cache_miss_(ea, set, -1);                        \
00093         spu_writech(22, SPE_CACHE_SET_TAGMASK(set));            \
00094         spu_mfcstat(MFC_TAG_UPDATE_ALL);                        \
00095     }                                                           \
00096     else                            \
00097     {                               \
00098         ++g_CacheHits;              \
00099     }                               \
00100     line = _spe_cacheline_num_(set, idx);                       \
00101     byte = _spe_cacheline_byte_offset_(ea);                     \
00102     (void *) &spe_cache_mem[line + byte];                       \
00103 })
00104 
00105 #endif
00106 
00107 #endif // USE_SOFTWARE_CACHE
00108 
00109 bool gUseEpa = false;
00110 
00111 #ifdef USE_SN_TUNER
00112 #include <LibSN_SPU.h>
00113 #endif //USE_SN_TUNER
00114 
00115 #if defined (__SPU__) && !defined (USE_LIBSPE2)
00116 #include <spu_printf.h>
00117 #elif defined (USE_LIBSPE2)
00118 #define spu_printf(a)
00119 #else
00120 #define IGNORE_ALIGNMENT 1
00121 #include <stdio.h>
00122 #include <stdlib.h>
00123 #define spu_printf printf
00124 
00125 #endif
00126 
00127 //int gNumConvexPoints0=0;
00128 
00130 struct  CollisionTask_LocalStoreMemory
00131 {
00134 
00135         ATTRIBUTE_ALIGNED16(btBroadphasePair    gBroadphasePairsBuffer[SPU_BATCHSIZE_BROADPHASE_PAIRS]);
00136         DoubleBuffer<unsigned char, MIDPHASE_WORKUNIT_PAGE_SIZE> g_workUnitTaskBuffers;
00137         ATTRIBUTE_ALIGNED16(char gSpuContactManifoldAlgoBuffer [sizeof(SpuContactManifoldCollisionAlgorithm)+16]);
00138         ATTRIBUTE_ALIGNED16(char gColObj0Buffer [sizeof(btCollisionObject)+16]);
00139         ATTRIBUTE_ALIGNED16(char gColObj1Buffer [sizeof(btCollisionObject)+16]);
00141         ATTRIBUTE_ALIGNED16(int spuIndices[16]);
00142         btPersistentManifold    gPersistentManifoldBuffer;
00143         CollisionShape_LocalStoreMemory gCollisionShapes[2];
00144         bvhMeshShape_LocalStoreMemory bvhShapeData;
00145         SpuConvexPolyhedronVertexData convexVertexData[2];
00146         CompoundShape_LocalStoreMemory compoundShapeData[2];
00147                 
00150         btCollisionObject*      m_lsColObj0Ptr;
00151         btCollisionObject*      m_lsColObj1Ptr;
00152         btBroadphasePair* m_pairsPointer;
00153         btPersistentManifold*   m_lsManifoldPtr;
00154         SpuContactManifoldCollisionAlgorithm*   m_lsCollisionAlgorithmPtr;
00155 
00156         bool    needsDmaPutContactManifoldAlgo;
00157 
00158         btCollisionObject* getColObj0()
00159         {
00160                 return m_lsColObj0Ptr;
00161         }
00162         btCollisionObject* getColObj1()
00163         {
00164                 return m_lsColObj1Ptr;
00165         }
00166 
00167 
00168         btBroadphasePair* getBroadphasePairPtr()
00169         {
00170                 return m_pairsPointer;
00171         }
00172 
00173         SpuContactManifoldCollisionAlgorithm*   getlocalCollisionAlgorithm()
00174         {
00175                 return m_lsCollisionAlgorithmPtr;
00176         }
00177         
00178         btPersistentManifold*   getContactManifoldPtr()
00179         {
00180                 return m_lsManifoldPtr;
00181         }
00182 };
00183 
00184 
00185 #if defined(__CELLOS_LV2__) || defined(USE_LIBSPE2) 
00186 
00187 ATTRIBUTE_ALIGNED16(CollisionTask_LocalStoreMemory      gLocalStoreMemory);
00188 
00189 void* createCollisionLocalStoreMemory()
00190 {
00191         return &gLocalStoreMemory;
00192 }
00193 #else
00194 void* createCollisionLocalStoreMemory()
00195 {
00196         return new CollisionTask_LocalStoreMemory;
00197 }
00198 
00199 #endif
00200 
00201 void    ProcessSpuConvexConvexCollision(SpuCollisionPairInput* wuInput, CollisionTask_LocalStoreMemory* lsMemPtr, SpuContactResult& spuContacts);
00202 
00203 
00204 SIMD_FORCE_INLINE void small_cache_read(void* buffer, ppu_address_t ea, size_t size)
00205 {
00206 #if USE_SOFTWARE_CACHE
00207         // Check for alignment requirements. We need to make sure the entire request fits within one cache line,
00208         // so the first and last bytes should fall on the same cache line
00209         btAssert((ea & ~SPE_CACHELINE_MASK) == ((ea + size - 1) & ~SPE_CACHELINE_MASK));
00210 
00211         void* ls = spe_cache_read(ea);
00212         memcpy(buffer, ls, size);
00213 #else
00214         stallingUnalignedDmaSmallGet(buffer,ea,size);
00215 #endif
00216 }
00217 
00218 SIMD_FORCE_INLINE void small_cache_read_triple( void* ls0, ppu_address_t ea0,
00219                                                                                                 void* ls1, ppu_address_t ea1,
00220                                                                                                 void* ls2, ppu_address_t ea2,
00221                                                                                                 size_t size)
00222 {
00223                 btAssert(size<16);
00224                 ATTRIBUTE_ALIGNED16(char        tmpBuffer0[32]);
00225                 ATTRIBUTE_ALIGNED16(char        tmpBuffer1[32]);
00226                 ATTRIBUTE_ALIGNED16(char        tmpBuffer2[32]);
00227 
00228                 uint32_t i;
00229                 
00230 
00232                 char* localStore0 = (char*)ls0;
00233                 uint32_t last4BitsOffset = ea0 & 0x0f;
00234                 char* tmpTarget0 = tmpBuffer0 + last4BitsOffset;
00235 #ifdef __SPU__
00236                 cellDmaSmallGet(tmpTarget0,ea0,size,DMA_TAG(1),0,0);
00237 #else
00238                 tmpTarget0 = (char*)cellDmaSmallGetReadOnly(tmpTarget0,ea0,size,DMA_TAG(1),0,0);
00239 #endif
00240 
00241 
00242                 char* localStore1 = (char*)ls1;
00243                 last4BitsOffset = ea1 & 0x0f;
00244                 char* tmpTarget1 = tmpBuffer1 + last4BitsOffset;
00245 #ifdef __SPU__
00246                 cellDmaSmallGet(tmpTarget1,ea1,size,DMA_TAG(1),0,0);
00247 #else
00248                 tmpTarget1 = (char*)cellDmaSmallGetReadOnly(tmpTarget1,ea1,size,DMA_TAG(1),0,0);
00249 #endif
00250                 
00251                 char* localStore2 = (char*)ls2;
00252                 last4BitsOffset = ea2 & 0x0f;
00253                 char* tmpTarget2 = tmpBuffer2 + last4BitsOffset;
00254 #ifdef __SPU__
00255                 cellDmaSmallGet(tmpTarget2,ea2,size,DMA_TAG(1),0,0);
00256 #else
00257                 tmpTarget2 = (char*)cellDmaSmallGetReadOnly(tmpTarget2,ea2,size,DMA_TAG(1),0,0);
00258 #endif
00259                 
00260                 
00261                 cellDmaWaitTagStatusAll( DMA_MASK(1) );
00262 
00263                 //this is slowish, perhaps memcpy on SPU is smarter?
00264                 for (i=0; btLikely( i<size );i++)
00265                 {
00266                         localStore0[i] = tmpTarget0[i];
00267                         localStore1[i] = tmpTarget1[i];
00268                         localStore2[i] = tmpTarget2[i];
00269                 }
00270 
00271                 
00272 }
00273 
00274 
00275 
00276 
00277 class spuNodeCallback : public btNodeOverlapCallback
00278 {
00279         SpuCollisionPairInput* m_wuInput;
00280         SpuContactResult&               m_spuContacts;
00281         CollisionTask_LocalStoreMemory* m_lsMemPtr;
00282         ATTRIBUTE_ALIGNED16(btTriangleShape)    m_tmpTriangleShape;
00283 
00284         ATTRIBUTE_ALIGNED16(btVector3   spuTriangleVertices[3]);
00285         ATTRIBUTE_ALIGNED16(btScalar    spuUnscaledVertex[4]);
00286         
00287 
00288 
00289 public:
00290         spuNodeCallback(SpuCollisionPairInput* wuInput, CollisionTask_LocalStoreMemory* lsMemPtr,SpuContactResult& spuContacts)
00291                 :       m_wuInput(wuInput),
00292                 m_spuContacts(spuContacts),
00293                 m_lsMemPtr(lsMemPtr)
00294         {
00295         }
00296 
00297         virtual void processNode(int subPart, int triangleIndex)
00298         {
00301 
00302                 //              spu_printf("processNode with triangleIndex %d\n",triangleIndex);
00303 
00304                 if (m_lsMemPtr->bvhShapeData.gIndexMesh.m_indexType == PHY_SHORT)
00305                 {
00306                         unsigned short int* indexBasePtr = (unsigned short int*)(m_lsMemPtr->bvhShapeData.gIndexMesh.m_triangleIndexBase+triangleIndex*m_lsMemPtr->bvhShapeData.gIndexMesh.m_triangleIndexStride);
00307                         ATTRIBUTE_ALIGNED16(unsigned short int tmpIndices[3]);
00308 
00309                         small_cache_read_triple(&tmpIndices[0],(ppu_address_t)&indexBasePtr[0],
00310                                                                         &tmpIndices[1],(ppu_address_t)&indexBasePtr[1],
00311                                                                         &tmpIndices[2],(ppu_address_t)&indexBasePtr[2],
00312                                                                         sizeof(unsigned short int));
00313 
00314                         m_lsMemPtr->spuIndices[0] = int(tmpIndices[0]);
00315                         m_lsMemPtr->spuIndices[1] = int(tmpIndices[1]);
00316                         m_lsMemPtr->spuIndices[2] = int(tmpIndices[2]);
00317                 } else
00318                 {
00319                         unsigned int* indexBasePtr = (unsigned int*)(m_lsMemPtr->bvhShapeData.gIndexMesh.m_triangleIndexBase+triangleIndex*m_lsMemPtr->bvhShapeData.gIndexMesh.m_triangleIndexStride);
00320 
00321                         small_cache_read_triple(&m_lsMemPtr->spuIndices[0],(ppu_address_t)&indexBasePtr[0],
00322                                                                 &m_lsMemPtr->spuIndices[1],(ppu_address_t)&indexBasePtr[1],
00323                                                                 &m_lsMemPtr->spuIndices[2],(ppu_address_t)&indexBasePtr[2],
00324                                                                 sizeof(int));
00325                 }
00326                 
00327                 //              spu_printf("SPU index0=%d ,",spuIndices[0]);
00328                 //              spu_printf("SPU index1=%d ,",spuIndices[1]);
00329                 //              spu_printf("SPU index2=%d ,",spuIndices[2]);
00330                 //              spu_printf("SPU: indexBasePtr=%llx\n",indexBasePtr);
00331 
00332                 const btVector3& meshScaling = m_lsMemPtr->bvhShapeData.gTriangleMeshInterfacePtr->getScaling();
00333                 for (int j=2;btLikely( j>=0 );j--)
00334                 {
00335                         int graphicsindex = m_lsMemPtr->spuIndices[j];
00336 
00337                         //                      spu_printf("SPU index=%d ,",graphicsindex);
00338                         btScalar* graphicsbasePtr = (btScalar*)(m_lsMemPtr->bvhShapeData.gIndexMesh.m_vertexBase+graphicsindex*m_lsMemPtr->bvhShapeData.gIndexMesh.m_vertexStride);
00339                         //                      spu_printf("SPU graphicsbasePtr=%llx\n",graphicsbasePtr);
00340 
00341 
00343 
00344                         //another DMA for each vertex
00345                         small_cache_read_triple(&spuUnscaledVertex[0],(ppu_address_t)&graphicsbasePtr[0],
00346                                                                         &spuUnscaledVertex[1],(ppu_address_t)&graphicsbasePtr[1],
00347                                                                         &spuUnscaledVertex[2],(ppu_address_t)&graphicsbasePtr[2],
00348                                                                         sizeof(btScalar));
00349                         
00350                         m_tmpTriangleShape.getVertexPtr(j).setValue(spuUnscaledVertex[0]*meshScaling.getX(),
00351                                 spuUnscaledVertex[1]*meshScaling.getY(),
00352                                 spuUnscaledVertex[2]*meshScaling.getZ());
00353 
00354                         //                      spu_printf("SPU:triangle vertices:%f,%f,%f\n",spuTriangleVertices[j].x(),spuTriangleVertices[j].y(),spuTriangleVertices[j].z());
00355                 }
00356 
00357 
00358                 SpuCollisionPairInput triangleConcaveInput(*m_wuInput);
00359 //              triangleConcaveInput.m_spuCollisionShapes[1] = &spuTriangleVertices[0];
00360                 triangleConcaveInput.m_spuCollisionShapes[1] = &m_tmpTriangleShape;
00361                 triangleConcaveInput.m_shapeType1 = TRIANGLE_SHAPE_PROXYTYPE;
00362 
00363                 m_spuContacts.setShapeIdentifiersB(subPart,triangleIndex);
00364 
00365                 //              m_spuContacts.flush();
00366 
00367                 ProcessSpuConvexConvexCollision(&triangleConcaveInput, m_lsMemPtr,m_spuContacts);
00369                 //      m_spuContacts.flush();
00370         }
00371 
00372 };
00373 
00374 
00375 
00376 void btConvexPlaneCollideSingleContact (SpuCollisionPairInput* wuInput,CollisionTask_LocalStoreMemory* lsMemPtr,SpuContactResult&  spuContacts)
00377 {
00378         
00379         btConvexShape* convexShape = (btConvexShape*) wuInput->m_spuCollisionShapes[0];
00380         btStaticPlaneShape* planeShape = (btStaticPlaneShape*) wuInput->m_spuCollisionShapes[1];
00381 
00382     bool hasCollision = false;
00383         const btVector3& planeNormal = planeShape->getPlaneNormal();
00384         const btScalar& planeConstant = planeShape->getPlaneConstant();
00385         
00386         
00387         btTransform convexWorldTransform = wuInput->m_worldTransform0;
00388         btTransform convexInPlaneTrans;
00389         convexInPlaneTrans= wuInput->m_worldTransform1.inverse() * convexWorldTransform;
00390         btTransform planeInConvex;
00391         planeInConvex= convexWorldTransform.inverse() * wuInput->m_worldTransform1;
00392         
00393         //btVector3 vtx = convexShape->localGetSupportVertexWithoutMarginNonVirtual(planeInConvex.getBasis()*-planeNormal);
00394         btVector3 vtx = convexShape->localGetSupportVertexNonVirtual(planeInConvex.getBasis()*-planeNormal);
00395 
00396         btVector3 vtxInPlane = convexInPlaneTrans(vtx);
00397         btScalar distance = (planeNormal.dot(vtxInPlane) - planeConstant);
00398 
00399         btVector3 vtxInPlaneProjected = vtxInPlane - distance*planeNormal;
00400         btVector3 vtxInPlaneWorld = wuInput->m_worldTransform1 * vtxInPlaneProjected;
00401 
00402         hasCollision = distance < lsMemPtr->getContactManifoldPtr()->getContactBreakingThreshold();
00403         //resultOut->setPersistentManifold(m_manifoldPtr);
00404         if (hasCollision)
00405         {
00407                 btVector3 normalOnSurfaceB =wuInput->m_worldTransform1.getBasis() * planeNormal;
00408                 btVector3 pOnB = vtxInPlaneWorld;
00409                 spuContacts.addContactPoint(normalOnSurfaceB,pOnB,distance);
00410         }
00411 }
00412 
00413 void    ProcessConvexPlaneSpuCollision(SpuCollisionPairInput* wuInput, CollisionTask_LocalStoreMemory* lsMemPtr, SpuContactResult& spuContacts)
00414 {
00415 
00416                 register        int dmaSize = 0;
00417                 register ppu_address_t  dmaPpuAddress2;
00418                 btPersistentManifold* manifold = (btPersistentManifold*)wuInput->m_persistentManifoldPtr;
00419 
00421                 ATTRIBUTE_ALIGNED16(char convexHullShape0[sizeof(btConvexHullShape)]);
00422                 ATTRIBUTE_ALIGNED16(char convexHullShape1[sizeof(btConvexHullShape)]);
00423 
00424                 if ( btLikely( wuInput->m_shapeType0== CONVEX_HULL_SHAPE_PROXYTYPE ) )
00425                 {
00426                         //      spu_printf("SPU: DMA btConvexHullShape\n");
00427                         
00428                         dmaSize = sizeof(btConvexHullShape);
00429                         dmaPpuAddress2 = wuInput->m_collisionShapes[0];
00430 
00431                         cellDmaGet(&convexHullShape0, dmaPpuAddress2  , dmaSize, DMA_TAG(1), 0, 0);
00432                         //cellDmaWaitTagStatusAll(DMA_MASK(1));
00433                 }
00434 
00435                 if ( btLikely( wuInput->m_shapeType1 == CONVEX_HULL_SHAPE_PROXYTYPE ) )
00436                 {
00437                         //      spu_printf("SPU: DMA btConvexHullShape\n");
00438                         dmaSize = sizeof(btConvexHullShape);
00439                         dmaPpuAddress2 = wuInput->m_collisionShapes[1];
00440                         cellDmaGet(&convexHullShape1, dmaPpuAddress2  , dmaSize, DMA_TAG(1), 0, 0);
00441                         //cellDmaWaitTagStatusAll(DMA_MASK(1));
00442                 }
00443                 
00444                 if ( btLikely( wuInput->m_shapeType0 == CONVEX_HULL_SHAPE_PROXYTYPE ) )
00445                 {               
00446                         cellDmaWaitTagStatusAll(DMA_MASK(1));
00447                         dmaConvexVertexData (&lsMemPtr->convexVertexData[0], (btConvexHullShape*)&convexHullShape0);
00448                         lsMemPtr->convexVertexData[0].gSpuConvexShapePtr = wuInput->m_spuCollisionShapes[0];
00449                 }
00450 
00451                         
00452                 if ( btLikely( wuInput->m_shapeType1 == CONVEX_HULL_SHAPE_PROXYTYPE ) )
00453                 {
00454                         cellDmaWaitTagStatusAll(DMA_MASK(1));
00455                         dmaConvexVertexData (&lsMemPtr->convexVertexData[1], (btConvexHullShape*)&convexHullShape1);
00456                         lsMemPtr->convexVertexData[1].gSpuConvexShapePtr = wuInput->m_spuCollisionShapes[1];
00457                 }
00458 
00459                 
00460                 btConvexPointCloudShape cpc0,cpc1;
00461 
00462                 if ( btLikely( wuInput->m_shapeType0 == CONVEX_HULL_SHAPE_PROXYTYPE ) )
00463                 {
00464                         cellDmaWaitTagStatusAll(DMA_MASK(2));
00465                         lsMemPtr->convexVertexData[0].gConvexPoints = &lsMemPtr->convexVertexData[0].g_convexPointBuffer[0];
00466                         btConvexHullShape* ch = (btConvexHullShape*)wuInput->m_spuCollisionShapes[0];
00467                         const btVector3& localScaling = ch->getLocalScalingNV();
00468                         cpc0.setPoints(lsMemPtr->convexVertexData[0].gConvexPoints,lsMemPtr->convexVertexData[0].gNumConvexPoints,false,localScaling);
00469                         wuInput->m_spuCollisionShapes[0] = &cpc0;
00470                 }
00471 
00472                 if ( btLikely( wuInput->m_shapeType1 == CONVEX_HULL_SHAPE_PROXYTYPE ) )
00473                 {
00474                         cellDmaWaitTagStatusAll(DMA_MASK(2));           
00475                         lsMemPtr->convexVertexData[1].gConvexPoints = &lsMemPtr->convexVertexData[1].g_convexPointBuffer[0];
00476                         btConvexHullShape* ch = (btConvexHullShape*)wuInput->m_spuCollisionShapes[1];
00477                         const btVector3& localScaling = ch->getLocalScalingNV();
00478                         cpc1.setPoints(lsMemPtr->convexVertexData[1].gConvexPoints,lsMemPtr->convexVertexData[1].gNumConvexPoints,false,localScaling);
00479                         wuInput->m_spuCollisionShapes[1] = &cpc1;
00480 
00481                 }
00482 
00483 
00484                 const btConvexShape* shape0Ptr = (const btConvexShape*)wuInput->m_spuCollisionShapes[0];
00485                 const btConvexShape* shape1Ptr = (const btConvexShape*)wuInput->m_spuCollisionShapes[1];
00486                 int shapeType0 = wuInput->m_shapeType0;
00487                 int shapeType1 = wuInput->m_shapeType1;
00488                 float marginA = wuInput->m_collisionMargin0;
00489                 float marginB = wuInput->m_collisionMargin1;
00490 
00491                 SpuClosestPointInput    cpInput;
00492                 cpInput.m_convexVertexData[0] = &lsMemPtr->convexVertexData[0];
00493                 cpInput.m_convexVertexData[1] = &lsMemPtr->convexVertexData[1];
00494                 cpInput.m_transformA = wuInput->m_worldTransform0;
00495                 cpInput.m_transformB = wuInput->m_worldTransform1;
00496                 float sumMargin = (marginA+marginB+lsMemPtr->getContactManifoldPtr()->getContactBreakingThreshold());
00497                 cpInput.m_maximumDistanceSquared = sumMargin * sumMargin;
00498 
00499                 ppu_address_t manifoldAddress = (ppu_address_t)manifold;
00500 
00501                 btPersistentManifold* spuManifold=lsMemPtr->getContactManifoldPtr();
00502                 //spuContacts.setContactInfo(spuManifold,manifoldAddress,wuInput->m_worldTransform0,wuInput->m_worldTransform1,wuInput->m_isSwapped);
00503                 spuContacts.setContactInfo(spuManifold,manifoldAddress,lsMemPtr->getColObj0()->getWorldTransform(),
00504                         lsMemPtr->getColObj1()->getWorldTransform(),
00505                         lsMemPtr->getColObj0()->getRestitution(),lsMemPtr->getColObj1()->getRestitution(),
00506                         lsMemPtr->getColObj0()->getFriction(),lsMemPtr->getColObj1()->getFriction(),
00507                         wuInput->m_isSwapped);
00508 
00509 
00510                 btConvexPlaneCollideSingleContact(wuInput,lsMemPtr,spuContacts);
00511 
00512 
00513                 
00514         
00515 }
00516 
00517 
00518 
00519 
00523 void    ProcessConvexConcaveSpuCollision(SpuCollisionPairInput* wuInput, CollisionTask_LocalStoreMemory* lsMemPtr, SpuContactResult& spuContacts)
00524 {
00525         //order: first collision shape is convex, second concave. m_isSwapped is true, if the original order was opposite
00526         
00527         btBvhTriangleMeshShape* trimeshShape = (btBvhTriangleMeshShape*)wuInput->m_spuCollisionShapes[1];
00528         //need the mesh interface, for access to triangle vertices
00529         dmaBvhShapeData (&lsMemPtr->bvhShapeData, trimeshShape);
00530 
00531         btVector3 aabbMin(-1,-400,-1);
00532         btVector3 aabbMax(1,400,1);
00533 
00534 
00535         //recalc aabbs
00536         btTransform convexInTriangleSpace;
00537         convexInTriangleSpace = wuInput->m_worldTransform1.inverse() * wuInput->m_worldTransform0;
00538         btConvexInternalShape* convexShape = (btConvexInternalShape*)wuInput->m_spuCollisionShapes[0];
00539 
00540         computeAabb (aabbMin, aabbMax, convexShape, wuInput->m_collisionShapes[0], wuInput->m_shapeType0, convexInTriangleSpace);
00541 
00542 
00543         //CollisionShape* triangleShape = static_cast<btCollisionShape*>(triBody->m_collisionShape);
00544         //convexShape->getAabb(convexInTriangleSpace,m_aabbMin,m_aabbMax);
00545 
00546         //      btScalar extraMargin = collisionMarginTriangle;
00547         //      btVector3 extra(extraMargin,extraMargin,extraMargin);
00548         //      aabbMax += extra;
00549         //      aabbMin -= extra;
00550 
00552         unsigned short int quantizedQueryAabbMin[3];
00553         unsigned short int quantizedQueryAabbMax[3];
00554         lsMemPtr->bvhShapeData.getOptimizedBvh()->quantizeWithClamp(quantizedQueryAabbMin,aabbMin,0);
00555         lsMemPtr->bvhShapeData.getOptimizedBvh()->quantizeWithClamp(quantizedQueryAabbMax,aabbMax,1);
00556 
00557         QuantizedNodeArray&     nodeArray = lsMemPtr->bvhShapeData.getOptimizedBvh()->getQuantizedNodeArray();
00558         //spu_printf("SPU: numNodes = %d\n",nodeArray.size());
00559 
00560         BvhSubtreeInfoArray& subTrees = lsMemPtr->bvhShapeData.getOptimizedBvh()->getSubtreeInfoArray();
00561 
00562 
00563         spuNodeCallback nodeCallback(wuInput,lsMemPtr,spuContacts);
00564         IndexedMeshArray&       indexArray = lsMemPtr->bvhShapeData.gTriangleMeshInterfacePtr->getIndexedMeshArray();
00565         //spu_printf("SPU:indexArray.size() = %d\n",indexArray.size());
00566 
00567         //      spu_printf("SPU: numSubTrees = %d\n",subTrees.size());
00568         //not likely to happen
00569         if (subTrees.size() && indexArray.size() == 1)
00570         {
00572                 dmaBvhIndexedMesh (&lsMemPtr->bvhShapeData.gIndexMesh, indexArray, 0 /* index into indexArray */, 1 /* dmaTag */);
00573                 cellDmaWaitTagStatusAll(DMA_MASK(1));
00574                 
00575                 //display the headers
00576                 int numBatch = subTrees.size();
00577                 for (int i=0;i<numBatch;)
00578                 {
00579                         //@todo- can reorder DMA transfers for less stall
00580                         int remaining = subTrees.size() - i;
00581                         int nextBatch = remaining < MAX_SPU_SUBTREE_HEADERS ? remaining : MAX_SPU_SUBTREE_HEADERS;
00582                         
00583                         dmaBvhSubTreeHeaders (&lsMemPtr->bvhShapeData.gSubtreeHeaders[0], (ppu_address_t)(&subTrees[i]), nextBatch, 1);
00584                         cellDmaWaitTagStatusAll(DMA_MASK(1));
00585                         
00586 
00587                         //                      spu_printf("nextBatch = %d\n",nextBatch);
00588 
00589                         for (int j=0;j<nextBatch;j++)
00590                         {
00591                                 const btBvhSubtreeInfo& subtree = lsMemPtr->bvhShapeData.gSubtreeHeaders[j];
00592 
00593                                 unsigned int overlap = spuTestQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,subtree.m_quantizedAabbMin,subtree.m_quantizedAabbMax);
00594                                 if (overlap)
00595                                 {
00596                                         btAssert(subtree.m_subtreeSize);
00597 
00598                                         //dma the actual nodes of this subtree
00599                                         dmaBvhSubTreeNodes (&lsMemPtr->bvhShapeData.gSubtreeNodes[0], subtree, nodeArray, 2);
00600                                         cellDmaWaitTagStatusAll(DMA_MASK(2));
00601 
00602                                         /* Walk this subtree */
00603                                         spuWalkStacklessQuantizedTree(&nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax,
00604                                                 &lsMemPtr->bvhShapeData.gSubtreeNodes[0],
00605                                                 0,
00606                                                 subtree.m_subtreeSize);
00607                                 }
00608                                 //                              spu_printf("subtreeSize = %d\n",gSubtreeHeaders[j].m_subtreeSize);
00609                         }
00610 
00611                         //      unsigned short int      m_quantizedAabbMin[3];
00612                         //      unsigned short int      m_quantizedAabbMax[3];
00613                         //      int                     m_rootNodeIndex;
00614                         //      int                     m_subtreeSize;
00615                         i+=nextBatch;
00616                 }
00617 
00618                 //pre-fetch first tree, then loop and double buffer
00619         }
00620 
00621 }
00622 
00623 
00624 int stats[11]={0,0,0,0,0,0,0,0,0,0,0};
00625 int degenerateStats[11]={0,0,0,0,0,0,0,0,0,0,0};
00626 
00627 
00631 void    ProcessSpuConvexConvexCollision(SpuCollisionPairInput* wuInput, CollisionTask_LocalStoreMemory* lsMemPtr, SpuContactResult& spuContacts)
00632 {
00633         register int dmaSize;
00634         register ppu_address_t  dmaPpuAddress2;
00635         
00636 #ifdef DEBUG_SPU_COLLISION_DETECTION
00637         //spu_printf("SPU: ProcessSpuConvexConvexCollision\n");
00638 #endif //DEBUG_SPU_COLLISION_DETECTION
00639         //CollisionShape* shape0 = (CollisionShape*)wuInput->m_collisionShapes[0];
00640         //CollisionShape* shape1 = (CollisionShape*)wuInput->m_collisionShapes[1];
00641         btPersistentManifold* manifold = (btPersistentManifold*)wuInput->m_persistentManifoldPtr;
00642 
00643         bool genericGjk = true;
00644 
00645         if (genericGjk)
00646         {
00647                 //try generic GJK
00648 
00649                 
00650                 
00651                 //SpuConvexPenetrationDepthSolver* penetrationSolver=0;
00652                 btVoronoiSimplexSolver simplexSolver;
00653                 btGjkEpaPenetrationDepthSolver  epaPenetrationSolver2;
00654                 
00655                 btConvexPenetrationDepthSolver* penetrationSolver = &epaPenetrationSolver2;
00656                 
00657                 //SpuMinkowskiPenetrationDepthSolver    minkowskiPenetrationSolver;
00658 #ifdef ENABLE_EPA
00659                 if (gUseEpa)
00660                 {
00661                         penetrationSolver = &epaPenetrationSolver2;
00662                 } else
00663 #endif
00664                 {
00665                         //penetrationSolver = &minkowskiPenetrationSolver;
00666                 }
00667 
00668 
00670                 ATTRIBUTE_ALIGNED16(char convexHullShape0[sizeof(btConvexHullShape)]);
00671                 ATTRIBUTE_ALIGNED16(char convexHullShape1[sizeof(btConvexHullShape)]);
00672 
00673                 if ( btLikely( wuInput->m_shapeType0== CONVEX_HULL_SHAPE_PROXYTYPE ) )
00674                 {
00675                         //      spu_printf("SPU: DMA btConvexHullShape\n");
00676                         
00677                         dmaSize = sizeof(btConvexHullShape);
00678                         dmaPpuAddress2 = wuInput->m_collisionShapes[0];
00679 
00680                         cellDmaGet(&convexHullShape0, dmaPpuAddress2  , dmaSize, DMA_TAG(1), 0, 0);
00681                         //cellDmaWaitTagStatusAll(DMA_MASK(1));
00682                 }
00683 
00684                 if ( btLikely( wuInput->m_shapeType1 == CONVEX_HULL_SHAPE_PROXYTYPE ) )
00685                 {
00686                         //      spu_printf("SPU: DMA btConvexHullShape\n");
00687                         dmaSize = sizeof(btConvexHullShape);
00688                         dmaPpuAddress2 = wuInput->m_collisionShapes[1];
00689                         cellDmaGet(&convexHullShape1, dmaPpuAddress2  , dmaSize, DMA_TAG(1), 0, 0);
00690                         //cellDmaWaitTagStatusAll(DMA_MASK(1));
00691                 }
00692                 
00693                 if ( btLikely( wuInput->m_shapeType0 == CONVEX_HULL_SHAPE_PROXYTYPE ) )
00694                 {               
00695                         cellDmaWaitTagStatusAll(DMA_MASK(1));
00696                         dmaConvexVertexData (&lsMemPtr->convexVertexData[0], (btConvexHullShape*)&convexHullShape0);
00697                         lsMemPtr->convexVertexData[0].gSpuConvexShapePtr = wuInput->m_spuCollisionShapes[0];
00698                 }
00699 
00700                         
00701                 if ( btLikely( wuInput->m_shapeType1 == CONVEX_HULL_SHAPE_PROXYTYPE ) )
00702                 {
00703                         cellDmaWaitTagStatusAll(DMA_MASK(1));
00704                         dmaConvexVertexData (&lsMemPtr->convexVertexData[1], (btConvexHullShape*)&convexHullShape1);
00705                         lsMemPtr->convexVertexData[1].gSpuConvexShapePtr = wuInput->m_spuCollisionShapes[1];
00706                 }
00707 
00708                 
00709                 btConvexPointCloudShape cpc0,cpc1;
00710 
00711                 if ( btLikely( wuInput->m_shapeType0 == CONVEX_HULL_SHAPE_PROXYTYPE ) )
00712                 {
00713                         cellDmaWaitTagStatusAll(DMA_MASK(2));
00714                         lsMemPtr->convexVertexData[0].gConvexPoints = &lsMemPtr->convexVertexData[0].g_convexPointBuffer[0];
00715                         btConvexHullShape* ch = (btConvexHullShape*)wuInput->m_spuCollisionShapes[0];
00716                         const btVector3& localScaling = ch->getLocalScalingNV();
00717                         cpc0.setPoints(lsMemPtr->convexVertexData[0].gConvexPoints,lsMemPtr->convexVertexData[0].gNumConvexPoints,false,localScaling);
00718                         wuInput->m_spuCollisionShapes[0] = &cpc0;
00719                 }
00720 
00721                 if ( btLikely( wuInput->m_shapeType1 == CONVEX_HULL_SHAPE_PROXYTYPE ) )
00722                 {
00723                         cellDmaWaitTagStatusAll(DMA_MASK(2));           
00724                         lsMemPtr->convexVertexData[1].gConvexPoints = &lsMemPtr->convexVertexData[1].g_convexPointBuffer[0];
00725                         btConvexHullShape* ch = (btConvexHullShape*)wuInput->m_spuCollisionShapes[1];
00726                         const btVector3& localScaling = ch->getLocalScalingNV();
00727                         cpc1.setPoints(lsMemPtr->convexVertexData[1].gConvexPoints,lsMemPtr->convexVertexData[1].gNumConvexPoints,false,localScaling);
00728                         wuInput->m_spuCollisionShapes[1] = &cpc1;
00729 
00730                 }
00731 
00732 
00733                 const btConvexShape* shape0Ptr = (const btConvexShape*)wuInput->m_spuCollisionShapes[0];
00734                 const btConvexShape* shape1Ptr = (const btConvexShape*)wuInput->m_spuCollisionShapes[1];
00735                 int shapeType0 = wuInput->m_shapeType0;
00736                 int shapeType1 = wuInput->m_shapeType1;
00737                 float marginA = wuInput->m_collisionMargin0;
00738                 float marginB = wuInput->m_collisionMargin1;
00739 
00740                 SpuClosestPointInput    cpInput;
00741                 cpInput.m_convexVertexData[0] = &lsMemPtr->convexVertexData[0];
00742                 cpInput.m_convexVertexData[1] = &lsMemPtr->convexVertexData[1];
00743                 cpInput.m_transformA = wuInput->m_worldTransform0;
00744                 cpInput.m_transformB = wuInput->m_worldTransform1;
00745                 float sumMargin = (marginA+marginB+lsMemPtr->getContactManifoldPtr()->getContactBreakingThreshold());
00746                 cpInput.m_maximumDistanceSquared = sumMargin * sumMargin;
00747 
00748                 ppu_address_t manifoldAddress = (ppu_address_t)manifold;
00749 
00750                 btPersistentManifold* spuManifold=lsMemPtr->getContactManifoldPtr();
00751                 //spuContacts.setContactInfo(spuManifold,manifoldAddress,wuInput->m_worldTransform0,wuInput->m_worldTransform1,wuInput->m_isSwapped);
00752                 spuContacts.setContactInfo(spuManifold,manifoldAddress,lsMemPtr->getColObj0()->getWorldTransform(),
00753                         lsMemPtr->getColObj1()->getWorldTransform(),
00754                         lsMemPtr->getColObj0()->getRestitution(),lsMemPtr->getColObj1()->getRestitution(),
00755                         lsMemPtr->getColObj0()->getFriction(),lsMemPtr->getColObj1()->getFriction(),
00756                         wuInput->m_isSwapped);
00757 
00758                 {
00759                         btGjkPairDetector gjk(shape0Ptr,shape1Ptr,shapeType0,shapeType1,marginA,marginB,&simplexSolver,penetrationSolver);//&vsSolver,penetrationSolver);
00760                         gjk.getClosestPoints(cpInput,spuContacts,0);//,debugDraw);
00761                         
00762                         stats[gjk.m_lastUsedMethod]++;
00763                         degenerateStats[gjk.m_degenerateSimplex]++;
00764 
00765 #ifdef USE_SEPDISTANCE_UTIL                     
00766                         btScalar sepDist = gjk.getCachedSeparatingDistance()+spuManifold->getContactBreakingThreshold();
00767                         lsMemPtr->getlocalCollisionAlgorithm()->m_sepDistance.initSeparatingDistance(gjk.getCachedSeparatingAxis(),sepDist,wuInput->m_worldTransform0,wuInput->m_worldTransform1);
00768                         lsMemPtr->needsDmaPutContactManifoldAlgo = true;
00769 #endif //USE_SEPDISTANCE_UTIL
00770 
00771                 }
00772 
00773         }
00774 
00775 
00776 }
00777 
00778 
00779 template<typename T> void DoSwap(T& a, T& b)
00780 {
00781         char tmp[sizeof(T)];
00782         memcpy(tmp, &a, sizeof(T));
00783         memcpy(&a, &b, sizeof(T));
00784         memcpy(&b, tmp, sizeof(T));
00785 }
00786 
00787 SIMD_FORCE_INLINE void  dmaAndSetupCollisionObjects(SpuCollisionPairInput& collisionPairInput, CollisionTask_LocalStoreMemory& lsMem)
00788 {
00789         register int dmaSize;
00790         register ppu_address_t  dmaPpuAddress2;
00791                 
00792         dmaSize = sizeof(btCollisionObject);//btTransform);
00793         dmaPpuAddress2 = /*collisionPairInput.m_isSwapped ? (ppu_address_t)lsMem.gProxyPtr1->m_clientObject :*/ (ppu_address_t)lsMem.getlocalCollisionAlgorithm()->getCollisionObject0();
00794         lsMem.m_lsColObj0Ptr = (btCollisionObject*)cellDmaGetReadOnly(&lsMem.gColObj0Buffer, dmaPpuAddress2  , dmaSize, DMA_TAG(1), 0, 0);              
00795 
00796         dmaSize = sizeof(btCollisionObject);//btTransform);
00797         dmaPpuAddress2 = /*collisionPairInput.m_isSwapped ? (ppu_address_t)lsMem.gProxyPtr0->m_clientObject :*/ (ppu_address_t)lsMem.getlocalCollisionAlgorithm()->getCollisionObject1();
00798         lsMem.m_lsColObj1Ptr = (btCollisionObject*)cellDmaGetReadOnly(&lsMem.gColObj1Buffer, dmaPpuAddress2  , dmaSize, DMA_TAG(2), 0, 0);              
00799         
00800         cellDmaWaitTagStatusAll(DMA_MASK(1) | DMA_MASK(2));
00801 
00802         btCollisionObject* ob0 = lsMem.getColObj0();
00803         btCollisionObject* ob1 = lsMem.getColObj1();
00804 
00805         collisionPairInput.m_worldTransform0 = ob0->getWorldTransform();
00806         collisionPairInput.m_worldTransform1 = ob1->getWorldTransform();
00807 }
00808 
00809 
00810 
00811 void    handleCollisionPair(SpuCollisionPairInput& collisionPairInput, CollisionTask_LocalStoreMemory& lsMem,
00812                                                         SpuContactResult &spuContacts,
00813                                                         ppu_address_t collisionShape0Ptr, void* collisionShape0Loc,
00814                                                         ppu_address_t collisionShape1Ptr, void* collisionShape1Loc, bool dmaShapes = true)
00815 {
00816         
00817         if (btBroadphaseProxy::isConvex(collisionPairInput.m_shapeType0) 
00818                 && btBroadphaseProxy::isConvex(collisionPairInput.m_shapeType1))
00819         {
00820                 if (dmaShapes)
00821                 {
00822                         dmaCollisionShape (collisionShape0Loc, collisionShape0Ptr, 1, collisionPairInput.m_shapeType0);
00823                         dmaCollisionShape (collisionShape1Loc, collisionShape1Ptr, 2, collisionPairInput.m_shapeType1);
00824                         cellDmaWaitTagStatusAll(DMA_MASK(1) | DMA_MASK(2));
00825                 }
00826 
00827                 btConvexInternalShape* spuConvexShape0 = (btConvexInternalShape*)collisionShape0Loc;
00828                 btConvexInternalShape* spuConvexShape1 = (btConvexInternalShape*)collisionShape1Loc;
00829 
00830                 btVector3 dim0 = spuConvexShape0->getImplicitShapeDimensions();
00831                 btVector3 dim1 = spuConvexShape1->getImplicitShapeDimensions();
00832 
00833                 collisionPairInput.m_primitiveDimensions0 = dim0;
00834                 collisionPairInput.m_primitiveDimensions1 = dim1;
00835                 collisionPairInput.m_collisionShapes[0] = collisionShape0Ptr;
00836                 collisionPairInput.m_collisionShapes[1] = collisionShape1Ptr;
00837                 collisionPairInput.m_spuCollisionShapes[0] = spuConvexShape0;
00838                 collisionPairInput.m_spuCollisionShapes[1] = spuConvexShape1;
00839                 ProcessSpuConvexConvexCollision(&collisionPairInput,&lsMem,spuContacts);
00840         } 
00841         else if (btBroadphaseProxy::isCompound(collisionPairInput.m_shapeType0) && 
00842                         btBroadphaseProxy::isCompound(collisionPairInput.m_shapeType1))
00843         {
00844                 //snPause();
00845 
00846                 dmaCollisionShape (collisionShape0Loc, collisionShape0Ptr, 1, collisionPairInput.m_shapeType0);
00847                 dmaCollisionShape (collisionShape1Loc, collisionShape1Ptr, 2, collisionPairInput.m_shapeType1);
00848                 cellDmaWaitTagStatusAll(DMA_MASK(1) | DMA_MASK(2));
00849 
00850                 // Both are compounds, do N^2 CD for now
00852         
00853                 btCompoundShape* spuCompoundShape0 = (btCompoundShape*)collisionShape0Loc;
00854                 btCompoundShape* spuCompoundShape1 = (btCompoundShape*)collisionShape1Loc;
00855 
00856                 dmaCompoundShapeInfo (&lsMem.compoundShapeData[0], spuCompoundShape0, 1);
00857                 dmaCompoundShapeInfo (&lsMem.compoundShapeData[1], spuCompoundShape1, 2);
00858                 cellDmaWaitTagStatusAll(DMA_MASK(1) | DMA_MASK(2));
00859                 
00860 
00861                 dmaCompoundSubShapes (&lsMem.compoundShapeData[0], spuCompoundShape0, 1);
00862                 cellDmaWaitTagStatusAll(DMA_MASK(1));
00863                 dmaCompoundSubShapes (&lsMem.compoundShapeData[1], spuCompoundShape1, 1);
00864                 cellDmaWaitTagStatusAll(DMA_MASK(1));
00865 
00866                 int childShapeCount0 = spuCompoundShape0->getNumChildShapes();
00867                 int childShapeCount1 = spuCompoundShape1->getNumChildShapes();
00868 
00869                 // Start the N^2
00870                 for (int i = 0; i < childShapeCount0; ++i)
00871                 {
00872                         btCompoundShapeChild& childShape0 = lsMem.compoundShapeData[0].gSubshapes[i];
00873 
00874                         for (int j = 0; j < childShapeCount1; ++j)
00875                         {
00876                                 btCompoundShapeChild& childShape1 = lsMem.compoundShapeData[1].gSubshapes[j];
00877 
00878                                 /* Create a new collision pair input struct using the two child shapes */
00879                                 SpuCollisionPairInput cinput (collisionPairInput);
00880 
00881                                 cinput.m_worldTransform0 = collisionPairInput.m_worldTransform0 * childShape0.m_transform;
00882                                 cinput.m_shapeType0 = childShape0.m_childShapeType;
00883                                 cinput.m_collisionMargin0 = childShape0.m_childMargin;
00884 
00885                                 cinput.m_worldTransform1 = collisionPairInput.m_worldTransform1 * childShape1.m_transform;
00886                                 cinput.m_shapeType1 = childShape1.m_childShapeType;
00887                                 cinput.m_collisionMargin1 = childShape1.m_childMargin;
00888                                 /* Recursively call handleCollisionPair () with new collision pair input */
00889                                 handleCollisionPair(cinput, lsMem, spuContacts,                 
00890                                         (ppu_address_t)childShape0.m_childShape, lsMem.compoundShapeData[0].gSubshapeShape[i], 
00891                                         (ppu_address_t)childShape1.m_childShape, lsMem.compoundShapeData[1].gSubshapeShape[j], false); // bug fix: changed index to j.
00892                         }
00893                 }
00894         }
00895         else if (btBroadphaseProxy::isCompound(collisionPairInput.m_shapeType0) )
00896         {
00897                 //snPause();
00898                 
00899                 dmaCollisionShape (collisionShape0Loc, collisionShape0Ptr, 1, collisionPairInput.m_shapeType0);
00900                 dmaCollisionShape (collisionShape1Loc, collisionShape1Ptr, 2, collisionPairInput.m_shapeType1);
00901                 cellDmaWaitTagStatusAll(DMA_MASK(1) | DMA_MASK(2));
00902 
00903                 // object 0 compound, object 1 non-compound
00904                 btCompoundShape* spuCompoundShape = (btCompoundShape*)collisionShape0Loc;
00905                 dmaCompoundShapeInfo (&lsMem.compoundShapeData[0], spuCompoundShape, 1);
00906                 cellDmaWaitTagStatusAll(DMA_MASK(1));
00907 
00908                 int childShapeCount = spuCompoundShape->getNumChildShapes();
00909 
00910                 for (int i = 0; i < childShapeCount; ++i)
00911                 {
00912                         btCompoundShapeChild& childShape = lsMem.compoundShapeData[0].gSubshapes[i];
00913 
00914                         // Dma the child shape
00915                         dmaCollisionShape (&lsMem.compoundShapeData[0].gSubshapeShape[i], (ppu_address_t)childShape.m_childShape, 1, childShape.m_childShapeType);
00916                         cellDmaWaitTagStatusAll(DMA_MASK(1));
00917                         
00918                         SpuCollisionPairInput cinput (collisionPairInput);
00919                         cinput.m_worldTransform0 = collisionPairInput.m_worldTransform0 * childShape.m_transform;
00920                         cinput.m_shapeType0 = childShape.m_childShapeType;
00921                         cinput.m_collisionMargin0 = childShape.m_childMargin;
00922 
00923                         handleCollisionPair(cinput, lsMem, spuContacts,                 
00924                                 (ppu_address_t)childShape.m_childShape, lsMem.compoundShapeData[0].gSubshapeShape[i], 
00925                                 collisionShape1Ptr, collisionShape1Loc, false);
00926                 }
00927         }
00928         else if (btBroadphaseProxy::isCompound(collisionPairInput.m_shapeType1) )
00929         {
00930                 //snPause();
00931                 
00932                 dmaCollisionShape (collisionShape0Loc, collisionShape0Ptr, 1, collisionPairInput.m_shapeType0);
00933                 dmaCollisionShape (collisionShape1Loc, collisionShape1Ptr, 2, collisionPairInput.m_shapeType1);
00934                 cellDmaWaitTagStatusAll(DMA_MASK(1) | DMA_MASK(2));
00935                 // object 0 non-compound, object 1 compound
00936                 btCompoundShape* spuCompoundShape = (btCompoundShape*)collisionShape1Loc;
00937                 dmaCompoundShapeInfo (&lsMem.compoundShapeData[0], spuCompoundShape, 1);
00938                 cellDmaWaitTagStatusAll(DMA_MASK(1));
00939                 
00940                 int childShapeCount = spuCompoundShape->getNumChildShapes();
00941 
00942                 for (int i = 0; i < childShapeCount; ++i)
00943                 {
00944                         btCompoundShapeChild& childShape = lsMem.compoundShapeData[0].gSubshapes[i];
00945                         // Dma the child shape
00946                         dmaCollisionShape (&lsMem.compoundShapeData[0].gSubshapeShape[i], (ppu_address_t)childShape.m_childShape, 1, childShape.m_childShapeType);
00947                         cellDmaWaitTagStatusAll(DMA_MASK(1));
00948 
00949                         SpuCollisionPairInput cinput (collisionPairInput);
00950                         cinput.m_worldTransform1 = collisionPairInput.m_worldTransform1 * childShape.m_transform;
00951                         cinput.m_shapeType1 = childShape.m_childShapeType;
00952                         cinput.m_collisionMargin1 = childShape.m_childMargin;
00953                         handleCollisionPair(cinput, lsMem, spuContacts,
00954                                 collisionShape0Ptr, collisionShape0Loc, 
00955                                 (ppu_address_t)childShape.m_childShape, lsMem.compoundShapeData[0].gSubshapeShape[i], false);
00956                 }
00957                 
00958         }
00959         else
00960         {
00961                 //a non-convex shape is involved                                                                        
00962                 bool handleConvexConcave = false;
00963 
00964                 //snPause();
00965 
00966                 if (btBroadphaseProxy::isConcave(collisionPairInput.m_shapeType0) &&
00967                         btBroadphaseProxy::isConvex(collisionPairInput.m_shapeType1))
00968                 {
00969                         // Swap stuff
00970                         DoSwap(collisionShape0Ptr, collisionShape1Ptr);
00971                         DoSwap(collisionShape0Loc, collisionShape1Loc);
00972                         DoSwap(collisionPairInput.m_shapeType0, collisionPairInput.m_shapeType1);
00973                         DoSwap(collisionPairInput.m_worldTransform0, collisionPairInput.m_worldTransform1);
00974                         DoSwap(collisionPairInput.m_collisionMargin0, collisionPairInput.m_collisionMargin1);
00975                         
00976                         collisionPairInput.m_isSwapped = true;
00977                 }
00978                 
00979                 if (btBroadphaseProxy::isConvex(collisionPairInput.m_shapeType0)&&
00980                         btBroadphaseProxy::isConcave(collisionPairInput.m_shapeType1))
00981                 {
00982                         handleConvexConcave = true;
00983                 }
00984                 if (handleConvexConcave)
00985                 {
00986                         if (dmaShapes)
00987                         {
00988                                 dmaCollisionShape (collisionShape0Loc, collisionShape0Ptr, 1, collisionPairInput.m_shapeType0);
00989                                 dmaCollisionShape (collisionShape1Loc, collisionShape1Ptr, 2, collisionPairInput.m_shapeType1);
00990                                 cellDmaWaitTagStatusAll(DMA_MASK(1) | DMA_MASK(2));
00991                         }
00992                         
00993                         if (collisionPairInput.m_shapeType1 == STATIC_PLANE_PROXYTYPE)
00994                         {
00995                                 btConvexInternalShape* spuConvexShape0 = (btConvexInternalShape*)collisionShape0Loc;
00996                                 btStaticPlaneShape* planeShape= (btStaticPlaneShape*)collisionShape1Loc;
00997 
00998                                 btVector3 dim0 = spuConvexShape0->getImplicitShapeDimensions();
00999                                 collisionPairInput.m_primitiveDimensions0 = dim0;
01000                                 collisionPairInput.m_collisionShapes[0] = collisionShape0Ptr;
01001                                 collisionPairInput.m_collisionShapes[1] = collisionShape1Ptr;
01002                                 collisionPairInput.m_spuCollisionShapes[0] = spuConvexShape0;
01003                                 collisionPairInput.m_spuCollisionShapes[1] = planeShape;
01004 
01005                                 ProcessConvexPlaneSpuCollision(&collisionPairInput,&lsMem,spuContacts);
01006                         } else
01007                         {
01008                                 btConvexInternalShape* spuConvexShape0 = (btConvexInternalShape*)collisionShape0Loc;
01009                                 btBvhTriangleMeshShape* trimeshShape = (btBvhTriangleMeshShape*)collisionShape1Loc;
01010 
01011                                 btVector3 dim0 = spuConvexShape0->getImplicitShapeDimensions();
01012                                 collisionPairInput.m_primitiveDimensions0 = dim0;
01013                                 collisionPairInput.m_collisionShapes[0] = collisionShape0Ptr;
01014                                 collisionPairInput.m_collisionShapes[1] = collisionShape1Ptr;
01015                                 collisionPairInput.m_spuCollisionShapes[0] = spuConvexShape0;
01016                                 collisionPairInput.m_spuCollisionShapes[1] = trimeshShape;
01017 
01018                                 ProcessConvexConcaveSpuCollision(&collisionPairInput,&lsMem,spuContacts);
01019                         }
01020                 }
01021 
01022         }
01023         
01024         spuContacts.flush();
01025 
01026 }
01027 
01028 
01029 void    processCollisionTask(void* userPtr, void* lsMemPtr)
01030 {
01031 
01032         SpuGatherAndProcessPairsTaskDesc* taskDescPtr = (SpuGatherAndProcessPairsTaskDesc*)userPtr;
01033         SpuGatherAndProcessPairsTaskDesc& taskDesc = *taskDescPtr;
01034         CollisionTask_LocalStoreMemory* colMemPtr = (CollisionTask_LocalStoreMemory*)lsMemPtr;
01035         CollisionTask_LocalStoreMemory& lsMem = *(colMemPtr);
01036 
01037         gUseEpa = taskDesc.m_useEpa;
01038 
01039         //      spu_printf("taskDescPtr=%llx\n",taskDescPtr);
01040 
01041         SpuContactResult spuContacts;
01042 
01044 
01045         ppu_address_t dmaInPtr = taskDesc.m_inPairPtr;
01046         unsigned int numPages = taskDesc.numPages;
01047         unsigned int numOnLastPage = taskDesc.numOnLastPage;
01048 
01049         // prefetch first set of inputs and wait
01050         lsMem.g_workUnitTaskBuffers.init();
01051 
01052         unsigned int nextNumOnPage = (numPages > 1)? MIDPHASE_NUM_WORKUNITS_PER_PAGE : numOnLastPage;
01053         lsMem.g_workUnitTaskBuffers.backBufferDmaGet(dmaInPtr, nextNumOnPage*sizeof(SpuGatherAndProcessWorkUnitInput), DMA_TAG(3));
01054         dmaInPtr += MIDPHASE_WORKUNIT_PAGE_SIZE;
01055 
01056         
01057         register unsigned char *inputPtr;
01058         register unsigned int numOnPage;
01059         register unsigned int j;
01060         SpuGatherAndProcessWorkUnitInput* wuInputs;     
01061         register int dmaSize;
01062         register ppu_address_t  dmaPpuAddress;
01063         register ppu_address_t  dmaPpuAddress2;
01064 
01065         int numPairs;
01066         register int p;
01067         SpuCollisionPairInput collisionPairInput;
01068         
01069         for (unsigned int i = 0; btLikely(i < numPages); i++)
01070         {
01071 
01072                 // wait for back buffer dma and swap buffers
01073                 inputPtr = lsMem.g_workUnitTaskBuffers.swapBuffers();
01074 
01075                 // number on current page is number prefetched last iteration
01076                 numOnPage = nextNumOnPage;
01077 
01078 
01079                 // prefetch next set of inputs
01080 #if MIDPHASE_NUM_WORKUNIT_PAGES > 2
01081                 if ( btLikely( i < numPages-1 ) )
01082 #else
01083                 if ( btUnlikely( i < numPages-1 ) )
01084 #endif
01085                 {
01086                         nextNumOnPage = (i == numPages-2)? numOnLastPage : MIDPHASE_NUM_WORKUNITS_PER_PAGE;
01087                         lsMem.g_workUnitTaskBuffers.backBufferDmaGet(dmaInPtr, nextNumOnPage*sizeof(SpuGatherAndProcessWorkUnitInput), DMA_TAG(3));
01088                         dmaInPtr += MIDPHASE_WORKUNIT_PAGE_SIZE;
01089                 }
01090 
01091                 wuInputs = reinterpret_cast<SpuGatherAndProcessWorkUnitInput *>(inputPtr);
01092                 
01093                 
01094                 for (j = 0; btLikely( j < numOnPage ); j++)
01095                 {
01096 #ifdef DEBUG_SPU_COLLISION_DETECTION
01097                 //      printMidphaseInput(&wuInputs[j]);
01098 #endif //DEBUG_SPU_COLLISION_DETECTION
01099 
01100 
01101                         numPairs = wuInputs[j].m_endIndex - wuInputs[j].m_startIndex;
01102                         
01103                         if ( btLikely( numPairs ) )
01104                         {
01105                                         dmaSize = numPairs*sizeof(btBroadphasePair);
01106                                         dmaPpuAddress = wuInputs[j].m_pairArrayPtr+wuInputs[j].m_startIndex * sizeof(btBroadphasePair);
01107                                         lsMem.m_pairsPointer = (btBroadphasePair*)cellDmaGetReadOnly(&lsMem.gBroadphasePairsBuffer, dmaPpuAddress  , dmaSize, DMA_TAG(1), 0, 0);
01108                                         cellDmaWaitTagStatusAll(DMA_MASK(1));
01109                                 
01110 
01111                                 for (p=0;p<numPairs;p++)
01112                                 {
01113 
01114                                         //for each broadphase pair, do something
01115 
01116                                         btBroadphasePair& pair = lsMem.getBroadphasePairPtr()[p];
01117 #ifdef DEBUG_SPU_COLLISION_DETECTION
01118                                         spu_printf("pair->m_userInfo = %d\n",pair.m_userInfo);
01119                                         spu_printf("pair->m_algorithm = %d\n",pair.m_algorithm);
01120                                         spu_printf("pair->m_pProxy0 = %d\n",pair.m_pProxy0);
01121                                         spu_printf("pair->m_pProxy1 = %d\n",pair.m_pProxy1);
01122 #endif //DEBUG_SPU_COLLISION_DETECTION
01123 
01124                                         if (pair.m_internalTmpValue == 2 && pair.m_algorithm && pair.m_pProxy0 && pair.m_pProxy1)
01125                                         {
01126                                                 dmaSize = sizeof(SpuContactManifoldCollisionAlgorithm);
01127                                                 dmaPpuAddress2 = (ppu_address_t)pair.m_algorithm;
01128                                                 lsMem.m_lsCollisionAlgorithmPtr = (SpuContactManifoldCollisionAlgorithm*)cellDmaGetReadOnly(&lsMem.gSpuContactManifoldAlgoBuffer, dmaPpuAddress2  , dmaSize, DMA_TAG(1), 0, 0);
01129 
01130                                                 cellDmaWaitTagStatusAll(DMA_MASK(1));
01131 
01132                                                 lsMem.needsDmaPutContactManifoldAlgo = false;
01133 
01134                                                 collisionPairInput.m_persistentManifoldPtr = (ppu_address_t) lsMem.getlocalCollisionAlgorithm()->getContactManifoldPtr();
01135                                                 collisionPairInput.m_isSwapped = false;
01136 
01137                                                 if (1)
01138                                                 {
01139 
01141 
01142 
01143 #ifdef DEBUG_SPU_COLLISION_DETECTION
01144                                         //              spu_printf("SPU collisionPairInput->m_shapeType0 = %d\n",collisionPairInput->m_shapeType0);
01145                                         //              spu_printf("SPU collisionPairInput->m_shapeType1 = %d\n",collisionPairInput->m_shapeType1);
01146 #endif //DEBUG_SPU_COLLISION_DETECTION
01147 
01148                                                         
01149                                                         dmaSize = sizeof(btPersistentManifold);
01150 
01151                                                         dmaPpuAddress2 = collisionPairInput.m_persistentManifoldPtr;
01152                                                         lsMem.m_lsManifoldPtr = (btPersistentManifold*)cellDmaGetReadOnly(&lsMem.gPersistentManifoldBuffer, dmaPpuAddress2  , dmaSize, DMA_TAG(1), 0, 0);
01153 
01154                                                         collisionPairInput.m_shapeType0 = lsMem.getlocalCollisionAlgorithm()->getShapeType0();
01155                                                         collisionPairInput.m_shapeType1 = lsMem.getlocalCollisionAlgorithm()->getShapeType1();
01156                                                         collisionPairInput.m_collisionMargin0 = lsMem.getlocalCollisionAlgorithm()->getCollisionMargin0();
01157                                                         collisionPairInput.m_collisionMargin1 = lsMem.getlocalCollisionAlgorithm()->getCollisionMargin1();
01158                                                         
01159                                                         
01160                                                         
01161                                                         //??cellDmaWaitTagStatusAll(DMA_MASK(1));
01162                                                         
01163 
01164                                                         if (1)
01165                                                         {
01166                                                                 //snPause();
01167 
01168                                                                 // Get the collision objects
01169                                                                 dmaAndSetupCollisionObjects(collisionPairInput, lsMem);
01170 
01171                                                                 if (lsMem.getColObj0()->isActive() || lsMem.getColObj1()->isActive())
01172                                                                 {
01173 
01174                                                                         lsMem.needsDmaPutContactManifoldAlgo = true;
01175 #ifdef USE_SEPDISTANCE_UTIL
01176                                                                         lsMem.getlocalCollisionAlgorithm()->m_sepDistance.updateSeparatingDistance(collisionPairInput.m_worldTransform0,collisionPairInput.m_worldTransform1);
01177 #endif //USE_SEPDISTANCE_UTIL
01178                                                         
01179 #define USE_DEDICATED_BOX_BOX 1
01180 #ifdef USE_DEDICATED_BOX_BOX
01181                                                                         bool boxbox = ((lsMem.getlocalCollisionAlgorithm()->getShapeType0()==BOX_SHAPE_PROXYTYPE)&&
01182                                                                                 (lsMem.getlocalCollisionAlgorithm()->getShapeType1()==BOX_SHAPE_PROXYTYPE));
01183                                                                         if (boxbox)
01184                                                                         {
01185                                                                                 //spu_printf("boxbox dist = %f\n",distance);
01186                                                                                 btPersistentManifold* spuManifold=lsMem.getContactManifoldPtr();
01187                                                                                 btPersistentManifold* manifold = (btPersistentManifold*)collisionPairInput.m_persistentManifoldPtr;
01188                                                                                 ppu_address_t manifoldAddress = (ppu_address_t)manifold;
01189 
01190                                                                                 spuContacts.setContactInfo(spuManifold,manifoldAddress,lsMem.getColObj0()->getWorldTransform(),
01191                                                                                         lsMem.getColObj1()->getWorldTransform(),
01192                                                                                         lsMem.getColObj0()->getRestitution(),lsMem.getColObj1()->getRestitution(),
01193                                                                                         lsMem.getColObj0()->getFriction(),lsMem.getColObj1()->getFriction(),
01194                                                                                         collisionPairInput.m_isSwapped);
01195 
01196                                                 
01197                                                                         //float distance=0.f;
01198                                                                         btVector3 normalInB;
01199 
01200 
01201                                                                         if (
01202 #ifdef USE_SEPDISTANCE_UTIL
01203                                                                                 lsMem.getlocalCollisionAlgorithm()->m_sepDistance.getConservativeSeparatingDistance()<=0.f
01204 #else
01205                                                                                 1
01206 #endif                                                                                  
01207                                                                                 )
01208                                                                                 {
01209 //#define USE_PE_BOX_BOX 1
01210 #ifdef USE_PE_BOX_BOX
01211                                                                                         {
01212 
01213                                                                                                 //getCollisionMargin0
01214                                                                                                 btScalar margin0 = lsMem.getlocalCollisionAlgorithm()->getCollisionMargin0();
01215                                                                                                 btScalar margin1 = lsMem.getlocalCollisionAlgorithm()->getCollisionMargin1();
01216                                                                                                 btVector3 shapeDim0 = lsMem.getlocalCollisionAlgorithm()->getShapeDimensions0()+btVector3(margin0,margin0,margin0);
01217                                                                                                 btVector3 shapeDim1 = lsMem.getlocalCollisionAlgorithm()->getShapeDimensions1()+btVector3(margin1,margin1,margin1);
01218 
01219                                                                                                 Box boxA(shapeDim0.getX(),shapeDim0.getY(),shapeDim0.getZ());
01220                                                                                                 Vector3 vmPos0 = getVmVector3(collisionPairInput.m_worldTransform0.getOrigin());
01221                                                                                                 Vector3 vmPos1 = getVmVector3(collisionPairInput.m_worldTransform1.getOrigin());
01222                                                                                                 Matrix3 vmMatrix0 = getVmMatrix3(collisionPairInput.m_worldTransform0.getBasis());
01223                                                                                                 Matrix3 vmMatrix1 = getVmMatrix3(collisionPairInput.m_worldTransform1.getBasis());
01224 
01225                                                                                                 Transform3 transformA(vmMatrix0,vmPos0);
01226                                                                                                 Box boxB(shapeDim1.getX(),shapeDim1.getY(),shapeDim1.getZ());
01227                                                                                                 Transform3 transformB(vmMatrix1,vmPos1);
01228                                                                                                 BoxPoint resultClosestBoxPointA;
01229                                                                                                 BoxPoint resultClosestBoxPointB;
01230                                                                                                 Vector3 resultNormal;
01231 #ifdef USE_SEPDISTANCE_UTIL
01232                                                                                                 float distanceThreshold = FLT_MAX
01233 #else
01234                                                                                                 float distanceThreshold = 0.f;
01235 #endif
01236 
01237 
01238                                                                                                 distance = boxBoxDistance(resultNormal,resultClosestBoxPointA,resultClosestBoxPointB,  boxA, transformA, boxB,transformB,distanceThreshold);
01239                                                                                                 
01240                                                                                                 normalInB = -getBtVector3(resultNormal);
01241 
01242                                                                                                 if(distance < spuManifold->getContactBreakingThreshold())
01243                                                                                                 {
01244                                                                                                         btVector3 pointOnB = collisionPairInput.m_worldTransform1(getBtVector3(resultClosestBoxPointB.localPoint));
01245 
01246                                                                                                         spuContacts.addContactPoint(
01247                                                                                                                 normalInB,
01248                                                                                                                 pointOnB,
01249                                                                                                                 distance);
01250                                                                                                 }
01251                                                                                         } 
01252 #else                                                                   
01253                                                                                         {
01254 
01255                                                                                                 btScalar margin0 = lsMem.getlocalCollisionAlgorithm()->getCollisionMargin0();
01256                                                                                                 btScalar margin1 = lsMem.getlocalCollisionAlgorithm()->getCollisionMargin1();
01257                                                                                                 btVector3 shapeDim0 = lsMem.getlocalCollisionAlgorithm()->getShapeDimensions0()+btVector3(margin0,margin0,margin0);
01258                                                                                                 btVector3 shapeDim1 = lsMem.getlocalCollisionAlgorithm()->getShapeDimensions1()+btVector3(margin1,margin1,margin1);
01259 
01260 
01261                                                                                                 btBoxShape box0(shapeDim0);
01262                                                                                                 btBoxShape box1(shapeDim1);
01263 
01264                                                                                                 struct SpuBridgeContactCollector : public btDiscreteCollisionDetectorInterface::Result
01265                                                                                                 {
01266                                                                                                         SpuContactResult&       m_spuContacts;
01267 
01268                                                                                                         virtual void setShapeIdentifiersA(int partId0,int index0)
01269                                                                                                         {
01270                                                                                                                 m_spuContacts.setShapeIdentifiersA(partId0,index0);
01271                                                                                                         }
01272                                                                                                         virtual void setShapeIdentifiersB(int partId1,int index1)
01273                                                                                                         {
01274                                                                                                                 m_spuContacts.setShapeIdentifiersB(partId1,index1);
01275                                                                                                         }
01276                                                                                                         virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)
01277                                                                                                         {
01278                                                                                                                 m_spuContacts.addContactPoint(normalOnBInWorld,pointInWorld,depth);
01279                                                                                                         }
01280 
01281                                                                                                         SpuBridgeContactCollector(SpuContactResult& spuContacts)
01282                                                                                                                 :m_spuContacts(spuContacts)
01283                                                                                                         {
01284 
01285                                                                                                         }
01286                                                                                                 };
01287                                                                                                 
01288                                                                                                 SpuBridgeContactCollector  bridgeOutput(spuContacts);
01289 
01290                                                                                                 btDiscreteCollisionDetectorInterface::ClosestPointInput input;
01291                                                                                                 input.m_maximumDistanceSquared = BT_LARGE_FLOAT;
01292                                                                                                 input.m_transformA = collisionPairInput.m_worldTransform0;
01293                                                                                                 input.m_transformB = collisionPairInput.m_worldTransform1;
01294 
01295                                                                                                 btBoxBoxDetector detector(&box0,&box1);
01296                                                                                                 
01297                                                                                                 detector.getClosestPoints(input,bridgeOutput,0);
01298 
01299                                                                                         }
01300 #endif //USE_PE_BOX_BOX
01301                                                                                         
01302                                                                                         lsMem.needsDmaPutContactManifoldAlgo = true;
01303 #ifdef USE_SEPDISTANCE_UTIL
01304                                                                                         btScalar sepDist2 = distance+spuManifold->getContactBreakingThreshold();
01305                                                                                         lsMem.getlocalCollisionAlgorithm()->m_sepDistance.initSeparatingDistance(normalInB,sepDist2,collisionPairInput.m_worldTransform0,collisionPairInput.m_worldTransform1);
01306 #endif //USE_SEPDISTANCE_UTIL
01307                                                                                         gProcessedCol++;
01308                                                                                 } else
01309                                                                                 {
01310                                                                                         gSkippedCol++;
01311                                                                                 }
01312 
01313                                                                                 spuContacts.flush();
01314                                                                                         
01315 
01316                                                                         } else
01317 #endif //USE_DEDICATED_BOX_BOX
01318                                                                         {
01319                                                                                 if (
01320 #ifdef USE_SEPDISTANCE_UTIL
01321                                                                                         lsMem.getlocalCollisionAlgorithm()->m_sepDistance.getConservativeSeparatingDistance()<=0.f
01322 #else
01323                                                                                         1
01324 #endif //USE_SEPDISTANCE_UTIL
01325                                                                                         )
01326                                                                                 {
01327                                                                                         handleCollisionPair(collisionPairInput, lsMem, spuContacts,
01328                                                                                                 (ppu_address_t)lsMem.getColObj0()->getRootCollisionShape(), &lsMem.gCollisionShapes[0].collisionShape,
01329                                                                                                 (ppu_address_t)lsMem.getColObj1()->getRootCollisionShape(), &lsMem.gCollisionShapes[1].collisionShape);
01330                                                                                 } else
01331                                                                                 {
01332                                                                                                 //spu_printf("boxbox dist = %f\n",distance);
01333                                                                                         btPersistentManifold* spuManifold=lsMem.getContactManifoldPtr();
01334                                                                                         btPersistentManifold* manifold = (btPersistentManifold*)collisionPairInput.m_persistentManifoldPtr;
01335                                                                                         ppu_address_t manifoldAddress = (ppu_address_t)manifold;
01336 
01337                                                                                         spuContacts.setContactInfo(spuManifold,manifoldAddress,lsMem.getColObj0()->getWorldTransform(),
01338                                                                                                 lsMem.getColObj1()->getWorldTransform(),
01339                                                                                                 lsMem.getColObj0()->getRestitution(),lsMem.getColObj1()->getRestitution(),
01340                                                                                                 lsMem.getColObj0()->getFriction(),lsMem.getColObj1()->getFriction(),
01341                                                                                                 collisionPairInput.m_isSwapped);
01342 
01343                                                                                         spuContacts.flush();
01344                                                                                 }
01345                                                                         }
01346                                                                 
01347                                                                 }
01348 
01349                                                         }
01350                                                 }
01351 
01352 #ifdef USE_SEPDISTANCE_UTIL
01353 #if defined (__SPU__) || defined (USE_LIBSPE2)
01354                                                 if (lsMem.needsDmaPutContactManifoldAlgo)
01355                                                 {
01356                                                         dmaSize = sizeof(SpuContactManifoldCollisionAlgorithm);
01357                                                         dmaPpuAddress2 = (ppu_address_t)pair.m_algorithm;
01358                                                         cellDmaLargePut(&lsMem.gSpuContactManifoldAlgoBuffer, dmaPpuAddress2  , dmaSize, DMA_TAG(1), 0, 0);
01359                                                         cellDmaWaitTagStatusAll(DMA_MASK(1));
01360                                                 }
01361 #endif
01362 #endif //#ifdef USE_SEPDISTANCE_UTIL
01363 
01364                                         }
01365                                 }
01366                         }
01367                 } //end for (j = 0; j < numOnPage; j++)
01368 
01369         }//     for 
01370 
01371 
01372 
01373         return;
01374 }
01375 
01376 

Generated on Mon Feb 15 22:17:08 2010 for Bullet Collision Detection & Physics Library by  doxygen 1.6.1