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 | |
---|
56 | int g_CacheMisses=0; |
---|
57 | int 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 | |
---|
86 | bool 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 |
---|
102 | struct 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 | |
---|
153 | ATTRIBUTE_ALIGNED16(CollisionTask_LocalStoreMemory gLocalStoreMemory); |
---|
154 | |
---|
155 | void* createCollisionLocalStoreMemory() |
---|
156 | { |
---|
157 | return &gLocalStoreMemory; |
---|
158 | } |
---|
159 | #else |
---|
160 | void* createCollisionLocalStoreMemory() |
---|
161 | { |
---|
162 | return new CollisionTask_LocalStoreMemory; |
---|
163 | }; |
---|
164 | |
---|
165 | #endif |
---|
166 | |
---|
167 | void ProcessSpuConvexConvexCollision(SpuCollisionPairInput* wuInput, CollisionTask_LocalStoreMemory* lsMemPtr, SpuContactResult& spuContacts); |
---|
168 | |
---|
169 | |
---|
170 | SIMD_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 | |
---|
184 | SIMD_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 | |
---|
242 | class 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 | |
---|
253 | public: |
---|
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 | /////////////////// |
---|
349 | void 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 | /////////////////// |
---|
456 | void 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 | |
---|
572 | template<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 | |
---|
580 | SIMD_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 | |
---|
601 | void 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 | |
---|
804 | void 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 | } |
---|