Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/physics/src/bullet/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.cpp @ 1966

Last change on this file since 1966 was 1966, checked in by rgrieder, 16 years ago

Let's go for multithreaded physics!

  • Property svn:eol-style set to native
File size: 35.1 KB
Line 
1
2#include "SpuGatheringCollisionTask.h"
3
4//#define DEBUG_SPU_COLLISION_DETECTION 1
5#include "../SpuDoubleBuffer.h"
6
7#include "../SpuCollisionTaskProcess.h"
8#include "../SpuGatheringCollisionDispatcher.h" //for SPU_BATCHSIZE_BROADPHASE_PAIRS
9
10#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
11#include "../SpuContactManifoldCollisionAlgorithm.h"
12#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
13#include "SpuContactResult.h"
14#include "BulletCollision/CollisionShapes/btOptimizedBvh.h"
15#include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h"
16#include "BulletCollision/CollisionShapes/btSphereShape.h"
17
18#include "BulletCollision/CollisionShapes/btCapsuleShape.h"
19
20#include "BulletCollision/CollisionShapes/btConvexShape.h"
21#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h"
22#include "BulletCollision/CollisionShapes/btConvexHullShape.h"
23#include "BulletCollision/CollisionShapes/btCompoundShape.h"
24
25#include "SpuMinkowskiPenetrationDepthSolver.h"
26#include "SpuEpaPenetrationDepthSolver.h"
27#include "SpuGjkPairDetector.h"
28#include "SpuVoronoiSimplexSolver.h"
29
30#include "SpuCollisionShapes.h" //definition of SpuConvexPolyhedronVertexData
31
32#ifdef __SPU__
33///Software caching from the IBM Cell SDK, it reduces 25% SPU time for our test cases
34#ifndef USE_LIBSPE2
35#define USE_SOFTWARE_CACHE 1
36#endif
37#endif //__SPU__
38
39////////////////////////////////////////////////
40/// software caching
41#if USE_SOFTWARE_CACHE
42#include <spu_intrinsics.h>
43#include <sys/spu_thread.h>
44#include <sys/spu_event.h>
45#include <stdint.h>
46#define SPE_CACHE_NWAY                  4
47//#define SPE_CACHE_NSETS               32, 16
48#define SPE_CACHE_NSETS                 8
49//#define SPE_CACHELINE_SIZE            512
50#define SPE_CACHELINE_SIZE              128
51#define SPE_CACHE_SET_TAGID(set)        15
52///make sure that spe_cache.h is below those defines!
53#include "software_cache/cache/include/spe_cache.h"
54
55
56int g_CacheMisses=0;
57int g_CacheHits=0;
58
59#if 0 // Added to allow cache misses and hits to be tracked, change this to 1 to restore unmodified version
60#define spe_cache_read(ea)              _spe_cache_lookup_xfer_wait_(ea, 0, 1)
61#else
62#define spe_cache_read(ea)              \
63({                                                              \
64    int set, idx, line, byte;                                   \
65    _spe_cache_nway_lookup_(ea, set, idx);                      \
66                                                                \
67    if (btUnlikely(idx < 0)) {                                  \
68        ++g_CacheMisses;                        \
69            idx = _spe_cache_miss_(ea, set, -1);                        \
70        spu_writech(22, SPE_CACHE_SET_TAGMASK(set));            \
71        spu_mfcstat(MFC_TAG_UPDATE_ALL);                        \
72    }                                                           \
73    else                            \
74    {                               \
75        ++g_CacheHits;              \
76    }                               \
77    line = _spe_cacheline_num_(set, idx);                       \
78    byte = _spe_cacheline_byte_offset_(ea);                     \
79    (void *) &spe_cache_mem[line + byte];                       \
80})
81
82#endif
83
84#endif // USE_SOFTWARE_CACHE
85
86bool gUseEpa = false;
87
88#ifdef USE_SN_TUNER
89#include <LibSN_SPU.h>
90#endif //USE_SN_TUNER
91
92#if defined (__CELLOS_LV2__) || defined (USE_LIBSPE2)
93#else
94#define IGNORE_ALIGNMENT 1
95#define spu_printf printf
96#include <stdio.h>
97#endif
98
99//int gNumConvexPoints0=0;
100
101///Make sure no destructors are called on this memory
102struct  CollisionTask_LocalStoreMemory
103{
104        ATTRIBUTE_ALIGNED16(char        bufferProxy0[sizeof(btBroadphaseProxy)+16]);
105        ATTRIBUTE_ALIGNED16(char        bufferProxy1[sizeof(btBroadphaseProxy)+16]);
106
107        ATTRIBUTE_ALIGNED16(btBroadphaseProxy*  gProxyPtr0);
108        ATTRIBUTE_ALIGNED16(btBroadphaseProxy*  gProxyPtr1);
109
110        //ATTRIBUTE_ALIGNED16(btCollisionObject gColObj0);
111        //ATTRIBUTE_ALIGNED16(btCollisionObject gColObj1);
112        ATTRIBUTE_ALIGNED16(char gColObj0 [sizeof(btCollisionObject)+16]);
113        ATTRIBUTE_ALIGNED16(char gColObj1 [sizeof(btCollisionObject)+16]);
114       
115        btCollisionObject* getColObj0()
116        {
117                return (btCollisionObject*) gColObj0;
118        }
119        btCollisionObject* getColObj1()
120        {
121                return (btCollisionObject*) gColObj1;
122        }
123
124        DoubleBuffer<unsigned char, MIDPHASE_WORKUNIT_PAGE_SIZE> g_workUnitTaskBuffers;
125        ATTRIBUTE_ALIGNED16(btBroadphasePair    gBroadphasePairs[SPU_BATCHSIZE_BROADPHASE_PAIRS]);
126
127
128        //SpuContactManifoldCollisionAlgorithm  gSpuContactManifoldAlgo;
129        //ATTRIBUTE_ALIGNED16(char      gSpuContactManifoldAlgo[sizeof(SpuContactManifoldCollisionAlgorithm)+128]);
130
131        SpuContactManifoldCollisionAlgorithm    gSpuContactManifoldAlgo;
132
133        SpuContactManifoldCollisionAlgorithm*   getlocalCollisionAlgorithm()
134        {
135                return (SpuContactManifoldCollisionAlgorithm*)&gSpuContactManifoldAlgo;
136
137        }
138        btPersistentManifold    gPersistentManifold;
139
140        CollisionShape_LocalStoreMemory gCollisionShapes[2];
141
142        ///we reserve 32bit integer indices, even though they might be 16bit
143        ATTRIBUTE_ALIGNED16(int spuIndices[16]);
144
145        bvhMeshShape_LocalStoreMemory bvhShapeData;
146        SpuConvexPolyhedronVertexData convexVertexData[2];
147        CompoundShape_LocalStoreMemory compoundShapeData[2];
148};
149
150
151#if defined(__CELLOS_LV2__) || defined(USE_LIBSPE2)
152
153ATTRIBUTE_ALIGNED16(CollisionTask_LocalStoreMemory      gLocalStoreMemory);
154
155void* createCollisionLocalStoreMemory()
156{
157        return &gLocalStoreMemory;
158}
159#else
160void* createCollisionLocalStoreMemory()
161{
162        return new CollisionTask_LocalStoreMemory;
163};
164
165#endif
166
167void    ProcessSpuConvexConvexCollision(SpuCollisionPairInput* wuInput, CollisionTask_LocalStoreMemory* lsMemPtr, SpuContactResult& spuContacts);
168
169
170SIMD_FORCE_INLINE void small_cache_read(void* buffer, ppu_address_t ea, size_t size)
171{
172#if USE_SOFTWARE_CACHE
173        // Check for alignment requirements. We need to make sure the entire request fits within one cache line,
174        // so the first and last bytes should fall on the same cache line
175        btAssert((ea & ~SPE_CACHELINE_MASK) == ((ea + size - 1) & ~SPE_CACHELINE_MASK));
176
177        void* ls = spe_cache_read(ea);
178        memcpy(buffer, ls, size);
179#else
180        stallingUnalignedDmaSmallGet(buffer,ea,size);
181#endif
182}
183
184SIMD_FORCE_INLINE void small_cache_read_triple( void* ls0, ppu_address_t ea0,
185                                                                                                void* ls1, ppu_address_t ea1,
186                                                                                                void* ls2, ppu_address_t ea2,
187                                                                                                size_t size)
188{
189                btAssert(size<16);
190                ATTRIBUTE_ALIGNED16(char        tmpBuffer0[32]);
191                ATTRIBUTE_ALIGNED16(char        tmpBuffer1[32]);
192                ATTRIBUTE_ALIGNED16(char        tmpBuffer2[32]);
193
194                uint32_t i;
195               
196
197                ///make sure last 4 bits are the same, for cellDmaSmallGet
198                char* localStore0 = (char*)ls0;
199                uint32_t last4BitsOffset = ea0 & 0x0f;
200                char* tmpTarget0 = tmpBuffer0 + last4BitsOffset;
201#ifdef __SPU__
202                cellDmaSmallGet(tmpTarget0,ea0,size,DMA_TAG(1),0,0);
203#else
204                tmpTarget0 = (char*)cellDmaSmallGetReadOnly(tmpTarget0,ea0,size,DMA_TAG(1),0,0);
205#endif
206
207
208                char* localStore1 = (char*)ls1;
209                last4BitsOffset = ea1 & 0x0f;
210                char* tmpTarget1 = tmpBuffer1 + last4BitsOffset;
211#ifdef __SPU__
212                cellDmaSmallGet(tmpTarget1,ea1,size,DMA_TAG(1),0,0);
213#else
214                tmpTarget1 = (char*)cellDmaSmallGetReadOnly(tmpTarget1,ea1,size,DMA_TAG(1),0,0);
215#endif
216               
217                char* localStore2 = (char*)ls2;
218                last4BitsOffset = ea2 & 0x0f;
219                char* tmpTarget2 = tmpBuffer2 + last4BitsOffset;
220#ifdef __SPU__
221                cellDmaSmallGet(tmpTarget2,ea2,size,DMA_TAG(1),0,0);
222#else
223                tmpTarget2 = (char*)cellDmaSmallGetReadOnly(tmpTarget2,ea2,size,DMA_TAG(1),0,0);
224#endif
225               
226               
227                cellDmaWaitTagStatusAll( DMA_MASK(1) );
228
229                //this is slowish, perhaps memcpy on SPU is smarter?
230                for (i=0; btLikely( i<size );i++)
231                {
232                        localStore0[i] = tmpTarget0[i];
233                        localStore1[i] = tmpTarget1[i];
234                        localStore2[i] = tmpTarget2[i];
235                }
236
237               
238}
239
240
241
242class spuNodeCallback : public btNodeOverlapCallback
243{
244        SpuCollisionPairInput* m_wuInput;
245        SpuContactResult&               m_spuContacts;
246        CollisionTask_LocalStoreMemory* m_lsMemPtr;
247
248        ATTRIBUTE_ALIGNED16(btVector3   spuTriangleVertices[3]);
249        ATTRIBUTE_ALIGNED16(btScalar    spuUnscaledVertex[4]);
250       
251
252
253public:
254        spuNodeCallback(SpuCollisionPairInput* wuInput, CollisionTask_LocalStoreMemory* lsMemPtr,SpuContactResult& spuContacts)
255                :       m_wuInput(wuInput),
256                m_lsMemPtr(lsMemPtr),
257                m_spuContacts(spuContacts)
258        {
259        }
260
261        virtual void processNode(int subPart, int triangleIndex)
262        {
263                ///Create a triangle on the stack, call process collision, with GJK
264                ///DMA the vertices, can benefit from software caching
265
266                //              spu_printf("processNode with triangleIndex %d\n",triangleIndex);
267
268///TODO: add switch between short int, and int indices, based on indexType
269
270                // ugly solution to support both 16bit and 32bit indices
271                if (m_lsMemPtr->bvhShapeData.gIndexMesh.m_indexType == PHY_SHORT)
272                {
273                        unsigned short int* indexBasePtr = (unsigned short int*)(m_lsMemPtr->bvhShapeData.gIndexMesh.m_triangleIndexBase+triangleIndex*m_lsMemPtr->bvhShapeData.gIndexMesh.m_triangleIndexStride);
274                        ATTRIBUTE_ALIGNED16(unsigned short int tmpIndices[3]);
275
276                        small_cache_read_triple(&tmpIndices[0],(ppu_address_t)&indexBasePtr[0],
277                                                                        &tmpIndices[1],(ppu_address_t)&indexBasePtr[1],
278                                                                        &tmpIndices[2],(ppu_address_t)&indexBasePtr[2],
279                                                                        sizeof(unsigned short int));
280
281                        m_lsMemPtr->spuIndices[0] = int(tmpIndices[0]);
282                        m_lsMemPtr->spuIndices[1] = int(tmpIndices[1]);
283                        m_lsMemPtr->spuIndices[2] = int(tmpIndices[2]);
284                } else
285                {
286                        unsigned int* indexBasePtr = (unsigned int*)(m_lsMemPtr->bvhShapeData.gIndexMesh.m_triangleIndexBase+triangleIndex*m_lsMemPtr->bvhShapeData.gIndexMesh.m_triangleIndexStride);
287
288                        small_cache_read_triple(&m_lsMemPtr->spuIndices[0],(ppu_address_t)&indexBasePtr[0],
289                                                                &m_lsMemPtr->spuIndices[1],(ppu_address_t)&indexBasePtr[1],
290                                                                &m_lsMemPtr->spuIndices[2],(ppu_address_t)&indexBasePtr[2],
291                                                                sizeof(int));
292                }
293               
294                //              spu_printf("SPU index0=%d ,",spuIndices[0]);
295                //              spu_printf("SPU index1=%d ,",spuIndices[1]);
296                //              spu_printf("SPU index2=%d ,",spuIndices[2]);
297                //              spu_printf("SPU: indexBasePtr=%llx\n",indexBasePtr);
298
299                const btVector3& meshScaling = m_lsMemPtr->bvhShapeData.gTriangleMeshInterfacePtr->getScaling();
300                for (int j=2;btLikely( j>=0 );j--)
301                {
302                        int graphicsindex = m_lsMemPtr->spuIndices[j];
303
304                        //                      spu_printf("SPU index=%d ,",graphicsindex);
305                        btScalar* graphicsbasePtr = (btScalar*)(m_lsMemPtr->bvhShapeData.gIndexMesh.m_vertexBase+graphicsindex*m_lsMemPtr->bvhShapeData.gIndexMesh.m_vertexStride);
306                        //                      spu_printf("SPU graphicsbasePtr=%llx\n",graphicsbasePtr);
307
308
309                        ///handle un-aligned vertices...
310
311                        //another DMA for each vertex
312                        small_cache_read_triple(&spuUnscaledVertex[0],(ppu_address_t)&graphicsbasePtr[0],
313                                                                        &spuUnscaledVertex[1],(ppu_address_t)&graphicsbasePtr[1],
314                                                                        &spuUnscaledVertex[2],(ppu_address_t)&graphicsbasePtr[2],
315                                                                        sizeof(btScalar));
316                       
317                        spuTriangleVertices[j] = btVector3(
318                                spuUnscaledVertex[0]*meshScaling.getX(),
319                                spuUnscaledVertex[1]*meshScaling.getY(),
320                                spuUnscaledVertex[2]*meshScaling.getZ());
321
322                        //                      spu_printf("SPU:triangle vertices:%f,%f,%f\n",spuTriangleVertices[j].x(),spuTriangleVertices[j].y(),spuTriangleVertices[j].z());
323                }
324
325
326
327                //btTriangleShape       tmpTriangleShape(spuTriangleVertices[0],spuTriangleVertices[1],spuTriangleVertices[2]);
328
329
330                SpuCollisionPairInput triangleConcaveInput(*m_wuInput);
331                triangleConcaveInput.m_spuCollisionShapes[1] = &spuTriangleVertices[0];
332                triangleConcaveInput.m_shapeType1 = TRIANGLE_SHAPE_PROXYTYPE;
333
334                m_spuContacts.setShapeIdentifiers(-1,-1,subPart,triangleIndex);
335
336                //              m_spuContacts.flush();
337
338                ProcessSpuConvexConvexCollision(&triangleConcaveInput, m_lsMemPtr,m_spuContacts);
339                ///this flush should be automatic
340                //      m_spuContacts.flush();
341        }
342
343};
344
345
346////////////////////////
347/// Convex versus Concave triangle mesh collision detection (handles concave triangle mesh versus sphere, box, cylinder, triangle, cone, convex polyhedron etc)
348///////////////////
349void    ProcessConvexConcaveSpuCollision(SpuCollisionPairInput* wuInput, CollisionTask_LocalStoreMemory* lsMemPtr, SpuContactResult& spuContacts)
350{
351        //order: first collision shape is convex, second concave. m_isSwapped is true, if the original order was opposite
352        register int dmaSize;
353        register ppu_address_t  dmaPpuAddress2;
354
355        btBvhTriangleMeshShape* trimeshShape = (btBvhTriangleMeshShape*)wuInput->m_spuCollisionShapes[1];
356        //need the mesh interface, for access to triangle vertices
357        dmaBvhShapeData (&lsMemPtr->bvhShapeData, trimeshShape);
358
359        btVector3 aabbMin(-1,-400,-1);
360        btVector3 aabbMax(1,400,1);
361
362
363        //recalc aabbs
364        btTransform convexInTriangleSpace;
365        convexInTriangleSpace = wuInput->m_worldTransform1.inverse() * wuInput->m_worldTransform0;
366        btConvexInternalShape* convexShape = (btConvexInternalShape*)wuInput->m_spuCollisionShapes[0];
367
368        computeAabb (aabbMin, aabbMax, convexShape, wuInput->m_collisionShapes[0], wuInput->m_shapeType0, convexInTriangleSpace);
369
370
371        //CollisionShape* triangleShape = static_cast<btCollisionShape*>(triBody->m_collisionShape);
372        //convexShape->getAabb(convexInTriangleSpace,m_aabbMin,m_aabbMax);
373
374        //      btScalar extraMargin = collisionMarginTriangle;
375        //      btVector3 extra(extraMargin,extraMargin,extraMargin);
376        //      aabbMax += extra;
377        //      aabbMin -= extra;
378
379        ///quantize query AABB
380        unsigned short int quantizedQueryAabbMin[3];
381        unsigned short int quantizedQueryAabbMax[3];
382        lsMemPtr->bvhShapeData.getOptimizedBvh()->quantizeWithClamp(quantizedQueryAabbMin,aabbMin,0);
383        lsMemPtr->bvhShapeData.getOptimizedBvh()->quantizeWithClamp(quantizedQueryAabbMax,aabbMax,1);
384
385        QuantizedNodeArray&     nodeArray = lsMemPtr->bvhShapeData.getOptimizedBvh()->getQuantizedNodeArray();
386        //spu_printf("SPU: numNodes = %d\n",nodeArray.size());
387
388        BvhSubtreeInfoArray& subTrees = lsMemPtr->bvhShapeData.getOptimizedBvh()->getSubtreeInfoArray();
389
390
391        spuNodeCallback nodeCallback(wuInput,lsMemPtr,spuContacts);
392        IndexedMeshArray&       indexArray = lsMemPtr->bvhShapeData.gTriangleMeshInterfacePtr->getIndexedMeshArray();
393        //spu_printf("SPU:indexArray.size() = %d\n",indexArray.size());
394
395        //      spu_printf("SPU: numSubTrees = %d\n",subTrees.size());
396        //not likely to happen
397        if (subTrees.size() && indexArray.size() == 1)
398        {
399                ///DMA in the index info
400                dmaBvhIndexedMesh (&lsMemPtr->bvhShapeData.gIndexMesh, indexArray, 0 /* index into indexArray */, 1 /* dmaTag */);
401                cellDmaWaitTagStatusAll(DMA_MASK(1));
402               
403                //display the headers
404                int numBatch = subTrees.size();
405                for (int i=0;i<numBatch;)
406                {
407// BEN: TODO - can reorder DMA transfers for less stall
408                        int remaining = subTrees.size() - i;
409                        int nextBatch = remaining < MAX_SPU_SUBTREE_HEADERS ? remaining : MAX_SPU_SUBTREE_HEADERS;
410                       
411                        dmaBvhSubTreeHeaders (&lsMemPtr->bvhShapeData.gSubtreeHeaders[0], (ppu_address_t)(&subTrees[i]), nextBatch, 1);
412                        cellDmaWaitTagStatusAll(DMA_MASK(1));
413                       
414
415                        //                      spu_printf("nextBatch = %d\n",nextBatch);
416
417                        for (int j=0;j<nextBatch;j++)
418                        {
419                                const btBvhSubtreeInfo& subtree = lsMemPtr->bvhShapeData.gSubtreeHeaders[j];
420
421                                unsigned int overlap = spuTestQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,subtree.m_quantizedAabbMin,subtree.m_quantizedAabbMax);
422                                if (overlap)
423                                {
424                                        btAssert(subtree.m_subtreeSize);
425
426                                        //dma the actual nodes of this subtree
427                                        dmaBvhSubTreeNodes (&lsMemPtr->bvhShapeData.gSubtreeNodes[0], subtree, nodeArray, 2);
428                                        cellDmaWaitTagStatusAll(DMA_MASK(2));
429
430                                        /* Walk this subtree */
431                                        spuWalkStacklessQuantizedTree(&nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax,
432                                                &lsMemPtr->bvhShapeData.gSubtreeNodes[0],
433                                                0,
434                                                subtree.m_subtreeSize);
435                                }
436                                //                              spu_printf("subtreeSize = %d\n",gSubtreeHeaders[j].m_subtreeSize);
437                        }
438
439                        //      unsigned short int      m_quantizedAabbMin[3];
440                        //      unsigned short int      m_quantizedAabbMax[3];
441                        //      int                     m_rootNodeIndex;
442                        //      int                     m_subtreeSize;
443                        i+=nextBatch;
444                }
445
446                //pre-fetch first tree, then loop and double buffer
447        }
448
449}
450
451
452
453////////////////////////
454/// Convex versus Convex collision detection (handles collision between sphere, box, cylinder, triangle, cone, convex polyhedron etc)
455///////////////////
456void    ProcessSpuConvexConvexCollision(SpuCollisionPairInput* wuInput, CollisionTask_LocalStoreMemory* lsMemPtr, SpuContactResult& spuContacts)
457{
458        register int dmaSize;
459        register ppu_address_t  dmaPpuAddress2;
460       
461#ifdef DEBUG_SPU_COLLISION_DETECTION
462        //spu_printf("SPU: ProcessSpuConvexConvexCollision\n");
463#endif //DEBUG_SPU_COLLISION_DETECTION
464        //CollisionShape* shape0 = (CollisionShape*)wuInput->m_collisionShapes[0];
465        //CollisionShape* shape1 = (CollisionShape*)wuInput->m_collisionShapes[1];
466        btPersistentManifold* manifold = (btPersistentManifold*)wuInput->m_persistentManifoldPtr;
467
468        bool genericGjk = true;
469
470        if (genericGjk)
471        {
472                //try generic GJK
473
474                SpuVoronoiSimplexSolver vsSolver;
475                SpuEpaPenetrationDepthSolver epaPenetrationSolver;
476                SpuMinkowskiPenetrationDepthSolver      minkowskiPenetrationSolver;
477                SpuConvexPenetrationDepthSolver* penetrationSolver;
478
479                if (gUseEpa)
480                {
481                        penetrationSolver = &epaPenetrationSolver;
482                } else {
483                        penetrationSolver = &minkowskiPenetrationSolver;
484                }
485
486
487                ///DMA in the vertices for convex shapes
488                ATTRIBUTE_ALIGNED16(char convexHullShape0[sizeof(btConvexHullShape)]);
489                ATTRIBUTE_ALIGNED16(char convexHullShape1[sizeof(btConvexHullShape)]);
490
491                if ( btLikely( wuInput->m_shapeType0== CONVEX_HULL_SHAPE_PROXYTYPE ) )
492                {
493                        //      spu_printf("SPU: DMA btConvexHullShape\n");
494                       
495                        dmaSize = sizeof(btConvexHullShape);
496                        dmaPpuAddress2 = wuInput->m_collisionShapes[0];
497
498                        cellDmaGet(&convexHullShape0, dmaPpuAddress2  , dmaSize, DMA_TAG(1), 0, 0);
499                        //cellDmaWaitTagStatusAll(DMA_MASK(1));
500                }
501
502                if ( btLikely( wuInput->m_shapeType1 == CONVEX_HULL_SHAPE_PROXYTYPE ) )
503                {
504                        //      spu_printf("SPU: DMA btConvexHullShape\n");
505                        dmaSize = sizeof(btConvexHullShape);
506                        dmaPpuAddress2 = wuInput->m_collisionShapes[1];
507                        cellDmaGet(&convexHullShape1, dmaPpuAddress2  , dmaSize, DMA_TAG(1), 0, 0);
508                        //cellDmaWaitTagStatusAll(DMA_MASK(1));
509                }
510               
511                if ( btLikely( wuInput->m_shapeType0 == CONVEX_HULL_SHAPE_PROXYTYPE ) )
512                {               
513                        cellDmaWaitTagStatusAll(DMA_MASK(1));
514                        dmaConvexVertexData (&lsMemPtr->convexVertexData[0], (btConvexHullShape*)&convexHullShape0);
515                        lsMemPtr->convexVertexData[0].gSpuConvexShapePtr = wuInput->m_spuCollisionShapes[0];
516                }
517
518                       
519                if ( btLikely( wuInput->m_shapeType1 == CONVEX_HULL_SHAPE_PROXYTYPE ) )
520                {
521                        cellDmaWaitTagStatusAll(DMA_MASK(1));
522                        dmaConvexVertexData (&lsMemPtr->convexVertexData[1], (btConvexHullShape*)&convexHullShape1);
523                        lsMemPtr->convexVertexData[1].gSpuConvexShapePtr = wuInput->m_spuCollisionShapes[1];
524                }
525
526                if ( btLikely( wuInput->m_shapeType0 == CONVEX_HULL_SHAPE_PROXYTYPE ) )
527                {               
528                        cellDmaWaitTagStatusAll(DMA_MASK(2));
529                        lsMemPtr->convexVertexData[0].gConvexPoints = &lsMemPtr->convexVertexData[0].g_convexPointBuffer[0];
530                }
531
532                if ( btLikely( wuInput->m_shapeType1 == CONVEX_HULL_SHAPE_PROXYTYPE ) )
533                {
534                        cellDmaWaitTagStatusAll(DMA_MASK(2));           
535                        lsMemPtr->convexVertexData[1].gConvexPoints = &lsMemPtr->convexVertexData[1].g_convexPointBuffer[0];
536                }
537
538
539                void* shape0Ptr = wuInput->m_spuCollisionShapes[0];
540                void* shape1Ptr = wuInput->m_spuCollisionShapes[1];
541                int shapeType0 = wuInput->m_shapeType0;
542                int shapeType1 = wuInput->m_shapeType1;
543                float marginA = wuInput->m_collisionMargin0;
544                float marginB = wuInput->m_collisionMargin1;
545
546                SpuClosestPointInput    cpInput;
547                cpInput.m_convexVertexData[0] = &lsMemPtr->convexVertexData[0];
548                cpInput.m_convexVertexData[1] = &lsMemPtr->convexVertexData[1];
549                cpInput.m_transformA = wuInput->m_worldTransform0;
550                cpInput.m_transformB = wuInput->m_worldTransform1;
551                float sumMargin = (marginA+marginB+lsMemPtr->gPersistentManifold.getContactBreakingThreshold());
552                cpInput.m_maximumDistanceSquared = sumMargin * sumMargin;
553
554                ppu_address_t manifoldAddress = (ppu_address_t)manifold;
555
556                btPersistentManifold* spuManifold=&lsMemPtr->gPersistentManifold;
557                //spuContacts.setContactInfo(spuManifold,manifoldAddress,wuInput->m_worldTransform0,wuInput->m_worldTransform1,wuInput->m_isSwapped);
558                spuContacts.setContactInfo(spuManifold,manifoldAddress,lsMemPtr->getColObj0()->getWorldTransform(),
559                        lsMemPtr->getColObj1()->getWorldTransform(),
560                        lsMemPtr->getColObj0()->getRestitution(),lsMemPtr->getColObj1()->getRestitution(),
561                        lsMemPtr->getColObj0()->getFriction(),lsMemPtr->getColObj1()->getFriction(),
562                        wuInput->m_isSwapped);
563
564                SpuGjkPairDetector gjk(shape0Ptr,shape1Ptr,shapeType0,shapeType1,marginA,marginB,&vsSolver,penetrationSolver);
565                gjk.getClosestPoints(cpInput,spuContacts);//,debugDraw);
566        }
567
568
569}
570
571
572template<typename T> void DoSwap(T& a, T& b)
573{
574        char tmp[sizeof(T)];
575        memcpy(tmp, &a, sizeof(T));
576        memcpy(&a, &b, sizeof(T));
577        memcpy(&b, tmp, sizeof(T));
578}
579
580SIMD_FORCE_INLINE void  dmaAndSetupCollisionObjects(SpuCollisionPairInput& collisionPairInput, CollisionTask_LocalStoreMemory& lsMem)
581{
582        register int dmaSize;
583        register ppu_address_t  dmaPpuAddress2;
584               
585        dmaSize = sizeof(btCollisionObject);
586        dmaPpuAddress2 = /*collisionPairInput.m_isSwapped ? (ppu_address_t)lsMem.gProxyPtr1->m_clientObject :*/ (ppu_address_t)lsMem.gProxyPtr0->m_clientObject;
587        cellDmaGet(&lsMem.gColObj0, dmaPpuAddress2  , dmaSize, DMA_TAG(1), 0, 0);               
588
589        dmaSize = sizeof(btCollisionObject);
590        dmaPpuAddress2 = /*collisionPairInput.m_isSwapped ? (ppu_address_t)lsMem.gProxyPtr0->m_clientObject :*/ (ppu_address_t)lsMem.gProxyPtr1->m_clientObject;
591        cellDmaGet(&lsMem.gColObj1, dmaPpuAddress2  , dmaSize, DMA_TAG(2), 0, 0);               
592       
593        cellDmaWaitTagStatusAll(DMA_MASK(1) | DMA_MASK(2));
594
595        collisionPairInput.m_worldTransform0 = lsMem.getColObj0()->getWorldTransform();
596        collisionPairInput.m_worldTransform1 = lsMem.getColObj1()->getWorldTransform();
597}
598
599
600
601void    handleCollisionPair(SpuCollisionPairInput& collisionPairInput, CollisionTask_LocalStoreMemory& lsMem,
602                                                        SpuContactResult &spuContacts,
603                                                        ppu_address_t collisionShape0Ptr, void* collisionShape0Loc,
604                                                        ppu_address_t collisionShape1Ptr, void* collisionShape1Loc, bool dmaShapes = true)
605{
606        register int dmaSize;
607        register        ppu_address_t   dmaPpuAddress2;
608       
609        if (btBroadphaseProxy::isConvex(collisionPairInput.m_shapeType0) 
610                && btBroadphaseProxy::isConvex(collisionPairInput.m_shapeType1))
611        {
612                if (dmaShapes)
613                {
614                        dmaCollisionShape (collisionShape0Loc, collisionShape0Ptr, 1, collisionPairInput.m_shapeType0);
615                        dmaCollisionShape (collisionShape1Loc, collisionShape1Ptr, 2, collisionPairInput.m_shapeType1);
616                        cellDmaWaitTagStatusAll(DMA_MASK(1) | DMA_MASK(2));
617                }
618
619                btConvexInternalShape* spuConvexShape0 = (btConvexInternalShape*)collisionShape0Loc;
620                btConvexInternalShape* spuConvexShape1 = (btConvexInternalShape*)collisionShape1Loc;
621
622                btVector3 dim0 = spuConvexShape0->getImplicitShapeDimensions();
623                btVector3 dim1 = spuConvexShape1->getImplicitShapeDimensions();
624
625                collisionPairInput.m_primitiveDimensions0 = dim0;
626                collisionPairInput.m_primitiveDimensions1 = dim1;
627                collisionPairInput.m_collisionShapes[0] = collisionShape0Ptr;
628                collisionPairInput.m_collisionShapes[1] = collisionShape1Ptr;
629                collisionPairInput.m_spuCollisionShapes[0] = spuConvexShape0;
630                collisionPairInput.m_spuCollisionShapes[1] = spuConvexShape1;
631                ProcessSpuConvexConvexCollision(&collisionPairInput,&lsMem,spuContacts);
632        } 
633        else if (btBroadphaseProxy::isCompound(collisionPairInput.m_shapeType0) && 
634                        btBroadphaseProxy::isCompound(collisionPairInput.m_shapeType1))
635        {
636                //snPause();
637
638                dmaCollisionShape (collisionShape0Loc, collisionShape0Ptr, 1, collisionPairInput.m_shapeType0);
639                dmaCollisionShape (collisionShape1Loc, collisionShape1Ptr, 2, collisionPairInput.m_shapeType1);
640                cellDmaWaitTagStatusAll(DMA_MASK(1) | DMA_MASK(2));
641
642                // Both are compounds, do N^2 CD for now
643                // TODO: add some AABB-based pruning
644       
645                btCompoundShape* spuCompoundShape0 = (btCompoundShape*)collisionShape0Loc;
646                btCompoundShape* spuCompoundShape1 = (btCompoundShape*)collisionShape1Loc;
647
648                dmaCompoundShapeInfo (&lsMem.compoundShapeData[0], spuCompoundShape0, 1);
649                dmaCompoundShapeInfo (&lsMem.compoundShapeData[1], spuCompoundShape1, 2);
650                cellDmaWaitTagStatusAll(DMA_MASK(1) | DMA_MASK(2));
651               
652
653                dmaCompoundSubShapes (&lsMem.compoundShapeData[0], spuCompoundShape0, 1);
654                cellDmaWaitTagStatusAll(DMA_MASK(1));
655                dmaCompoundSubShapes (&lsMem.compoundShapeData[1], spuCompoundShape1, 1);
656                cellDmaWaitTagStatusAll(DMA_MASK(1));
657
658                int childShapeCount0 = spuCompoundShape0->getNumChildShapes();
659                int childShapeCount1 = spuCompoundShape1->getNumChildShapes();
660
661                // Start the N^2
662                for (int i = 0; i < childShapeCount0; ++i)
663                {
664                        btCompoundShapeChild& childShape0 = lsMem.compoundShapeData[0].gSubshapes[i];
665
666                        for (int j = 0; j < childShapeCount1; ++j)
667                        {
668                                btCompoundShapeChild& childShape1 = lsMem.compoundShapeData[1].gSubshapes[j];
669
670                                /* Create a new collision pair input struct using the two child shapes */
671                                SpuCollisionPairInput cinput (collisionPairInput);
672
673                                cinput.m_worldTransform0 = collisionPairInput.m_worldTransform0 * childShape0.m_transform;
674                                cinput.m_shapeType0 = childShape0.m_childShapeType;
675                                cinput.m_collisionMargin0 = childShape0.m_childMargin;
676
677                                cinput.m_worldTransform1 = collisionPairInput.m_worldTransform1 * childShape1.m_transform;
678                                cinput.m_shapeType1 = childShape1.m_childShapeType;
679                                cinput.m_collisionMargin1 = childShape1.m_childMargin;
680                                /* Recursively call handleCollisionPair () with new collision pair input */
681                                handleCollisionPair(cinput, lsMem, spuContacts,                 
682                                        (ppu_address_t)childShape0.m_childShape, lsMem.compoundShapeData[0].gSubshapeShape[i], 
683                                        (ppu_address_t)childShape1.m_childShape, lsMem.compoundShapeData[1].gSubshapeShape[j], false); // bug fix: changed index to j.
684                        }
685                }
686        }
687        else if (btBroadphaseProxy::isCompound(collisionPairInput.m_shapeType0) )
688        {
689                //snPause();
690               
691                dmaCollisionShape (collisionShape0Loc, collisionShape0Ptr, 1, collisionPairInput.m_shapeType0);
692                dmaCollisionShape (collisionShape1Loc, collisionShape1Ptr, 2, collisionPairInput.m_shapeType1);
693                cellDmaWaitTagStatusAll(DMA_MASK(1) | DMA_MASK(2));
694
695                // object 0 compound, object 1 non-compound
696                btCompoundShape* spuCompoundShape = (btCompoundShape*)collisionShape0Loc;
697                dmaCompoundShapeInfo (&lsMem.compoundShapeData[0], spuCompoundShape, 1);
698                cellDmaWaitTagStatusAll(DMA_MASK(1));
699
700                int childShapeCount = spuCompoundShape->getNumChildShapes();
701
702                for (int i = 0; i < childShapeCount; ++i)
703                {
704                        btCompoundShapeChild& childShape = lsMem.compoundShapeData[0].gSubshapes[i];
705
706                        // Dma the child shape
707                        dmaCollisionShape (&lsMem.compoundShapeData[0].gSubshapeShape[i], (ppu_address_t)childShape.m_childShape, 1, childShape.m_childShapeType);
708                        cellDmaWaitTagStatusAll(DMA_MASK(1));
709                       
710                        SpuCollisionPairInput cinput (collisionPairInput);
711                        cinput.m_worldTransform0 = collisionPairInput.m_worldTransform0 * childShape.m_transform;
712                        cinput.m_shapeType0 = childShape.m_childShapeType;
713                        cinput.m_collisionMargin0 = childShape.m_childMargin;
714
715                        handleCollisionPair(cinput, lsMem, spuContacts,                 
716                                (ppu_address_t)childShape.m_childShape, lsMem.compoundShapeData[0].gSubshapeShape[i], 
717                                collisionShape1Ptr, collisionShape1Loc, false);
718                }
719        }
720        else if (btBroadphaseProxy::isCompound(collisionPairInput.m_shapeType1) )
721        {
722                //snPause();
723               
724                dmaCollisionShape (collisionShape0Loc, collisionShape0Ptr, 1, collisionPairInput.m_shapeType0);
725                dmaCollisionShape (collisionShape1Loc, collisionShape1Ptr, 2, collisionPairInput.m_shapeType1);
726                cellDmaWaitTagStatusAll(DMA_MASK(1) | DMA_MASK(2));
727                // object 0 non-compound, object 1 compound
728                btCompoundShape* spuCompoundShape = (btCompoundShape*)collisionShape1Loc;
729                dmaCompoundShapeInfo (&lsMem.compoundShapeData[0], spuCompoundShape, 1);
730                cellDmaWaitTagStatusAll(DMA_MASK(1));
731               
732                int childShapeCount = spuCompoundShape->getNumChildShapes();
733
734                for (int i = 0; i < childShapeCount; ++i)
735                {
736                        btCompoundShapeChild& childShape = lsMem.compoundShapeData[0].gSubshapes[i];
737                        // Dma the child shape
738                        dmaCollisionShape (&lsMem.compoundShapeData[0].gSubshapeShape[i], (ppu_address_t)childShape.m_childShape, 1, childShape.m_childShapeType);
739                        cellDmaWaitTagStatusAll(DMA_MASK(1));
740
741                        SpuCollisionPairInput cinput (collisionPairInput);
742                        cinput.m_worldTransform1 = collisionPairInput.m_worldTransform1 * childShape.m_transform;
743                        cinput.m_shapeType1 = childShape.m_childShapeType;
744                        cinput.m_collisionMargin1 = childShape.m_childMargin;
745                        handleCollisionPair(cinput, lsMem, spuContacts,
746                                collisionShape0Ptr, collisionShape0Loc, 
747                                (ppu_address_t)childShape.m_childShape, lsMem.compoundShapeData[0].gSubshapeShape[i], false);
748                }
749               
750        }
751        else
752        {
753                //a non-convex shape is involved                                                                       
754                bool handleConvexConcave = false;
755
756                //snPause();
757
758                if (btBroadphaseProxy::isConcave(collisionPairInput.m_shapeType0) &&
759                        btBroadphaseProxy::isConvex(collisionPairInput.m_shapeType1))
760                {
761                        // Swap stuff
762                        DoSwap(collisionShape0Ptr, collisionShape1Ptr);
763                        DoSwap(collisionShape0Loc, collisionShape1Loc);
764                        DoSwap(collisionPairInput.m_shapeType0, collisionPairInput.m_shapeType1);
765                        DoSwap(collisionPairInput.m_worldTransform0, collisionPairInput.m_worldTransform1);
766                        DoSwap(collisionPairInput.m_collisionMargin0, collisionPairInput.m_collisionMargin1);
767                       
768                        collisionPairInput.m_isSwapped = true;
769                }
770               
771                if (btBroadphaseProxy::isConvex(collisionPairInput.m_shapeType0)&&
772                        btBroadphaseProxy::isConcave(collisionPairInput.m_shapeType1))
773                {
774                        handleConvexConcave = true;
775                }
776                if (handleConvexConcave)
777                {
778                        if (dmaShapes)
779                        {
780                                dmaCollisionShape (collisionShape0Loc, collisionShape0Ptr, 1, collisionPairInput.m_shapeType0);
781                                dmaCollisionShape (collisionShape1Loc, collisionShape1Ptr, 2, collisionPairInput.m_shapeType1);
782                                cellDmaWaitTagStatusAll(DMA_MASK(1) | DMA_MASK(2));
783                        }
784                       
785                        btConvexInternalShape* spuConvexShape0 = (btConvexInternalShape*)collisionShape0Loc;
786                        btBvhTriangleMeshShape* trimeshShape = (btBvhTriangleMeshShape*)collisionShape1Loc;
787
788                        btVector3 dim0 = spuConvexShape0->getImplicitShapeDimensions();
789                        collisionPairInput.m_primitiveDimensions0 = dim0;
790                        collisionPairInput.m_collisionShapes[0] = collisionShape0Ptr;
791                        collisionPairInput.m_collisionShapes[1] = collisionShape1Ptr;
792                        collisionPairInput.m_spuCollisionShapes[0] = spuConvexShape0;
793                        collisionPairInput.m_spuCollisionShapes[1] = trimeshShape;
794
795                        ProcessConvexConcaveSpuCollision(&collisionPairInput,&lsMem,spuContacts);
796                }
797
798        }
799
800        spuContacts.flush();
801}
802
803
804void    processCollisionTask(void* userPtr, void* lsMemPtr)
805{
806
807        SpuGatherAndProcessPairsTaskDesc* taskDescPtr = (SpuGatherAndProcessPairsTaskDesc*)userPtr;
808        SpuGatherAndProcessPairsTaskDesc& taskDesc = *taskDescPtr;
809        CollisionTask_LocalStoreMemory* colMemPtr = (CollisionTask_LocalStoreMemory*)lsMemPtr;
810        CollisionTask_LocalStoreMemory& lsMem = *(colMemPtr);
811
812        gUseEpa = taskDesc.m_useEpa;
813
814        //      spu_printf("taskDescPtr=%llx\n",taskDescPtr);
815
816        SpuContactResult spuContacts;
817
818        ////////////////////
819
820        ppu_address_t dmaInPtr = taskDesc.inPtr;
821        unsigned int numPages = taskDesc.numPages;
822        unsigned int numOnLastPage = taskDesc.numOnLastPage;
823
824        // prefetch first set of inputs and wait
825        lsMem.g_workUnitTaskBuffers.init();
826
827        unsigned int nextNumOnPage = (numPages > 1)? MIDPHASE_NUM_WORKUNITS_PER_PAGE : numOnLastPage;
828        lsMem.g_workUnitTaskBuffers.backBufferDmaGet(dmaInPtr, nextNumOnPage*sizeof(SpuGatherAndProcessWorkUnitInput), DMA_TAG(3));
829        dmaInPtr += MIDPHASE_WORKUNIT_PAGE_SIZE;
830
831       
832        register unsigned char *inputPtr;
833        register unsigned int numOnPage;
834        register unsigned int j;
835        SpuGatherAndProcessWorkUnitInput* wuInputs;     
836        register int dmaSize;
837        register ppu_address_t  dmaPpuAddress;
838        register ppu_address_t  dmaPpuAddress2;
839
840        int userInfo;
841        int numPairs;
842        register int p;
843        SpuCollisionPairInput collisionPairInput;
844       
845        for (unsigned int i = 0; btLikely(i < numPages); i++)
846        {
847
848                // wait for back buffer dma and swap buffers
849                inputPtr = lsMem.g_workUnitTaskBuffers.swapBuffers();
850
851                // number on current page is number prefetched last iteration
852                numOnPage = nextNumOnPage;
853
854
855                // prefetch next set of inputs
856#if MIDPHASE_NUM_WORKUNIT_PAGES > 2
857                if ( btLikely( i < numPages-1 ) )
858#else
859                if ( btUnlikely( i < numPages-1 ) )
860#endif
861                {
862                        nextNumOnPage = (i == numPages-2)? numOnLastPage : MIDPHASE_NUM_WORKUNITS_PER_PAGE;
863                        lsMem.g_workUnitTaskBuffers.backBufferDmaGet(dmaInPtr, nextNumOnPage*sizeof(SpuGatherAndProcessWorkUnitInput), DMA_TAG(3));
864                        dmaInPtr += MIDPHASE_WORKUNIT_PAGE_SIZE;
865                }
866
867                wuInputs = reinterpret_cast<SpuGatherAndProcessWorkUnitInput *>(inputPtr);
868               
869               
870                for (j = 0; btLikely( j < numOnPage ); j++)
871                {
872#ifdef DEBUG_SPU_COLLISION_DETECTION
873                //      printMidphaseInput(&wuInputs[j]);
874#endif //DEBUG_SPU_COLLISION_DETECTION
875
876
877                        numPairs = wuInputs[j].m_endIndex - wuInputs[j].m_startIndex;
878                       
879                        if ( btLikely( numPairs ) )
880                        {
881                                        dmaSize = numPairs*sizeof(btBroadphasePair);
882                                        dmaPpuAddress = wuInputs[j].m_pairArrayPtr+wuInputs[j].m_startIndex * sizeof(btBroadphasePair);
883                                        cellDmaGet(&lsMem.gBroadphasePairs, dmaPpuAddress  , dmaSize, DMA_TAG(1), 0, 0);
884                                        cellDmaWaitTagStatusAll(DMA_MASK(1));
885                               
886
887                                for (p=0;p<numPairs;p++)
888                                {
889
890                                        //for each broadphase pair, do something
891
892                                        btBroadphasePair& pair = lsMem.gBroadphasePairs[p];
893#ifdef DEBUG_SPU_COLLISION_DETECTION
894                                        spu_printf("pair->m_userInfo = %d\n",pair.m_userInfo);
895                                        spu_printf("pair->m_algorithm = %d\n",pair.m_algorithm);
896                                        spu_printf("pair->m_pProxy0 = %d\n",pair.m_pProxy0);
897                                        spu_printf("pair->m_pProxy1 = %d\n",pair.m_pProxy1);
898#endif //DEBUG_SPU_COLLISION_DETECTION
899
900                                        userInfo = int(pair.m_userInfo);
901
902                                        if (userInfo == 2 && pair.m_algorithm && pair.m_pProxy0 && pair.m_pProxy1)
903                                        {
904                                                dmaSize = sizeof(SpuContactManifoldCollisionAlgorithm);
905                                                dmaPpuAddress2 = (ppu_address_t)pair.m_algorithm;
906                                                cellDmaGet(&lsMem.gSpuContactManifoldAlgo, dmaPpuAddress2  , dmaSize, DMA_TAG(1), 0, 0);
907
908                                                //snPause();
909
910#ifdef DEBUG_SPU_COLLISION_DETECTION
911                                                //spu_printf("SPU: manifoldPtr: %llx",collisionPairInput->m_persistentManifoldPtr);
912#endif //DEBUG_SPU_COLLISION_DETECTION
913
914                                               
915                                                dmaSize = sizeof(btBroadphaseProxy);
916                                                dmaPpuAddress2 = (ppu_address_t)pair.m_pProxy0;
917                                                //stallingUnalignedDmaSmallGet(lsMem.gProxyPtr0, dmaPpuAddress2  , dmaSize);
918                                                void* tmpPtr = cellDmaSmallGetReadOnly(&lsMem.bufferProxy0, dmaPpuAddress2  , dmaSize,DMA_TAG(1), 0, 0);
919                                                lsMem.gProxyPtr0 = (btBroadphaseProxy*) tmpPtr;
920
921                                                dmaSize = sizeof(btBroadphaseProxy);
922                                                dmaPpuAddress2 = (ppu_address_t)pair.m_pProxy1;
923                                                tmpPtr  = cellDmaSmallGetReadOnly(&lsMem.bufferProxy1, dmaPpuAddress2  , dmaSize,DMA_TAG(1), 0, 0);
924
925                                                lsMem.gProxyPtr1 = (btBroadphaseProxy*)tmpPtr;
926
927                                                cellDmaWaitTagStatusAll(DMA_MASK(1));
928
929                                                collisionPairInput.m_persistentManifoldPtr = (ppu_address_t) lsMem.gSpuContactManifoldAlgo.getContactManifoldPtr();
930                                                collisionPairInput.m_isSwapped = false;
931
932                                                if (1)
933                                                {
934
935                                                        ///can wait on the combined DMA_MASK, or dma on the same tag
936
937
938#ifdef DEBUG_SPU_COLLISION_DETECTION
939                                        //              spu_printf("SPU collisionPairInput->m_shapeType0 = %d\n",collisionPairInput->m_shapeType0);
940                                        //              spu_printf("SPU collisionPairInput->m_shapeType1 = %d\n",collisionPairInput->m_shapeType1);
941#endif //DEBUG_SPU_COLLISION_DETECTION
942
943                                                       
944                                                        dmaSize = sizeof(btPersistentManifold);
945
946                                                        dmaPpuAddress2 = collisionPairInput.m_persistentManifoldPtr;
947                                                        cellDmaGet(&lsMem.gPersistentManifold, dmaPpuAddress2  , dmaSize, DMA_TAG(1), 0, 0);
948
949                                                        collisionPairInput.m_shapeType0 = lsMem.gSpuContactManifoldAlgo.getShapeType0();
950                                                        collisionPairInput.m_shapeType1 = lsMem.gSpuContactManifoldAlgo.getShapeType1();
951                                                        collisionPairInput.m_collisionMargin0 = lsMem.gSpuContactManifoldAlgo.getCollisionMargin0();
952                                                        collisionPairInput.m_collisionMargin1 = lsMem.gSpuContactManifoldAlgo.getCollisionMargin1();
953                                                       
954                                                       
955                                                       
956                                                        //??cellDmaWaitTagStatusAll(DMA_MASK(1));
957                                                       
958
959                                                        if (1)
960                                                        {
961                                                                //snPause();
962
963                                                                // Get the collision objects
964                                                                dmaAndSetupCollisionObjects(collisionPairInput, lsMem);
965
966                                                                if (lsMem.getColObj0()->isActive() || lsMem.getColObj1()->isActive())
967                                                                {
968                                                                        handleCollisionPair(collisionPairInput, lsMem, spuContacts, 
969                                                                                (ppu_address_t)lsMem.getColObj0()->getCollisionShape(), &lsMem.gCollisionShapes[0].collisionShape,
970                                                                                (ppu_address_t)lsMem.getColObj1()->getCollisionShape(), &lsMem.gCollisionShapes[1].collisionShape);
971                                                                }
972
973                                                        }
974                                                }
975
976                                        }
977                                }
978                        }
979                } //end for (j = 0; j < numOnPage; j++)
980
981        }//     for
982
983
984        return;
985}
Note: See TracBrowser for help on using the repository browser.