Bullet Collision Detection & Physics Library
SpuSampleTask.cpp
Go to the documentation of this file.
1 /*
2 Bullet Continuous Collision Detection and Physics Library, Copyright (c) 2007 Erwin Coumans
3 
4 This software is provided 'as-is', without any express or implied warranty.
5 In no event will the authors be held liable for any damages arising from the use of this software.
6 Permission is granted to anyone to use this software for any purpose,
7 including commercial applications, and to alter it and redistribute it freely,
8 subject to the following restrictions:
9 
10 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
11 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
12 3. This notice may not be removed or altered from any source distribution.
13 
14 */
15 
16 
17 #include "SpuSampleTask.h"
19 #include "../PlatformDefinitions.h"
20 #include "../SpuFakeDma.h"
21 #include "LinearMath/btMinMax.h"
22 
23 #ifdef __SPU__
24 #include <spu_printf.h>
25 #else
26 #include <stdio.h>
27 #define spu_printf printf
28 #endif
29 
30 #define MAX_NUM_BODIES 8192
31 
33 {
36 
37 };
38 
39 
40 
41 
42 //-- MAIN METHOD
43 void processSampleTask(void* userPtr, void* lsMemory)
44 {
45  // BT_PROFILE("processSampleTask");
46 
48 
49  SpuSampleTaskDesc* taskDescPtr = (SpuSampleTaskDesc*)userPtr;
50  SpuSampleTaskDesc& taskDesc = *taskDescPtr;
51 
52  switch (taskDesc.m_sampleCommand)
53  {
55  {
56  btTransform predictedTrans;
58 
59  int batchSize = taskDesc.m_sampleValue;
60  if (batchSize>MAX_NUM_BODIES)
61  {
62  spu_printf("SPU Error: exceed number of bodies, see MAX_NUM_BODIES in SpuSampleTask.cpp\n");
63  break;
64  }
65  int dmaArraySize = batchSize*sizeof(void*);
66 
67  uint64_t ppuArrayAddress = reinterpret_cast<uint64_t>(eaPtr);
68 
69  // spu_printf("array location is at %llx, batchSize = %d, DMA size = %d\n",ppuArrayAddress,batchSize,dmaArraySize);
70 
71  if (dmaArraySize>=16)
72  {
73  cellDmaLargeGet((void*)&localMemory->gPointerArray[0], ppuArrayAddress , dmaArraySize, DMA_TAG(1), 0, 0);
75  } else
76  {
77  stallingUnalignedDmaSmallGet((void*)&localMemory->gPointerArray[0], ppuArrayAddress , dmaArraySize);
78  }
79 
80 
81  for ( int i=0;i<batchSize;i++)
82  {
84 
85  void* localPtr = &localMemory->gLocalRigidBody[0];
86  void* shortAdd = localMemory->gPointerArray[i];
87  uint64_t ppuRigidBodyAddress = reinterpret_cast<uint64_t>(shortAdd);
88 
89  // spu_printf("cellDmaGet at CMD_SAMPLE_INTEGRATE_BODIES from %llx to %llx\n",ppuRigidBodyAddress,localPtr);
90 
91  int dmaBodySize = sizeof(btRigidBody);
92 
93  cellDmaGet((void*)localPtr, ppuRigidBodyAddress , dmaBodySize, DMA_TAG(1), 0, 0);
95 
96 
97  float timeStep = 1.f/60.f;
98 
99  btRigidBody* body = (btRigidBody*) localPtr;//btRigidBody::upcast(colObj);
100  if (body)
101  {
102  if (body->isActive() && (!body->isStaticOrKinematicObject()))
103  {
104  body->predictIntegratedTransform(timeStep, predictedTrans);
105  body->proceedToTransform( predictedTrans);
106  void* ptr = (void*)localPtr;
107  // spu_printf("cellDmaLargePut from %llx to LS %llx\n",ptr,ppuRigidBodyAddress);
108 
109  cellDmaLargePut(ptr, ppuRigidBodyAddress , dmaBodySize, DMA_TAG(1), 0, 0);
111 
112  }
113  }
114 
115  }
116  break;
117  }
118 
119 
121  {
122  btTransform predictedTrans;
124 
125  int batchSize = taskDesc.m_sampleValue;
126  int dmaArraySize = batchSize*sizeof(void*);
127 
128  if (batchSize>MAX_NUM_BODIES)
129  {
130  spu_printf("SPU Error: exceed number of bodies, see MAX_NUM_BODIES in SpuSampleTask.cpp\n");
131  break;
132  }
133 
134  uint64_t ppuArrayAddress = reinterpret_cast<uint64_t>(eaPtr);
135 
136  // spu_printf("array location is at %llx, batchSize = %d, DMA size = %d\n",ppuArrayAddress,batchSize,dmaArraySize);
137 
138  if (dmaArraySize>=16)
139  {
140  cellDmaLargeGet((void*)&localMemory->gPointerArray[0], ppuArrayAddress , dmaArraySize, DMA_TAG(1), 0, 0);
142  } else
143  {
144  stallingUnalignedDmaSmallGet((void*)&localMemory->gPointerArray[0], ppuArrayAddress , dmaArraySize);
145  }
146 
147 
148  for ( int i=0;i<batchSize;i++)
149  {
151 
152  void* localPtr = &localMemory->gLocalRigidBody[0];
153  void* shortAdd = localMemory->gPointerArray[i];
154  uint64_t ppuRigidBodyAddress = reinterpret_cast<uint64_t>(shortAdd);
155 
156  // spu_printf("cellDmaGet at CMD_SAMPLE_INTEGRATE_BODIES from %llx to %llx\n",ppuRigidBodyAddress,localPtr);
157 
158  int dmaBodySize = sizeof(btRigidBody);
159 
160  cellDmaGet((void*)localPtr, ppuRigidBodyAddress , dmaBodySize, DMA_TAG(1), 0, 0);
162 
163 
164  float timeStep = 1.f/60.f;
165 
166  btRigidBody* body = (btRigidBody*) localPtr;//btRigidBody::upcast(colObj);
167  if (body)
168  {
169  if (!body->isStaticOrKinematicObject())
170  {
171  if (body->isActive())
172  {
173  body->integrateVelocities( timeStep);
174  //damping
175  body->applyDamping(timeStep);
176 
178 
179  void* ptr = (void*)localPtr;
180  cellDmaLargePut(ptr, ppuRigidBodyAddress , dmaBodySize, DMA_TAG(1), 0, 0);
182  }
183  }
184  }
185 
186  }
187  break;
188  }
189 
190 
191 
192  default:
193  {
194 
195  }
196  };
197 }
198 
199 
200 #if defined(__CELLOS_LV2__) || defined (LIBSPE2)
201 
203 
205 {
206  return &gLocalStoreMemory;
207 }
208 #else
210 {
211  return new SampleTask_LocalStoreMemory;
212 };
213 
214 #endif
int cellDmaGet(void *ls, uint64_t ea, uint32_t size, uint32_t tag, uint32_t tid, uint32_t rid)
Definition: SpuFakeDma.cpp:173
unsigned long int uint64_t
void predictIntegratedTransform(btScalar step, btTransform &predictedTransform)
continuous collision detection needs prediction
void * createSampleLocalStoreMemory()
#define DMA_MASK(a)
Definition: SpuFakeDma.h:113
int cellDmaLargeGet(void *ls, uint64_t ea, uint32_t size, uint32_t tag, uint32_t tid, uint32_t rid)
cellDmaLargeGet Win32 replacements for Cell DMA to allow simulating most of the SPU code (just memcpy...
Definition: SpuFakeDma.cpp:157
#define MAX_NUM_BODIES
#define DMA_TAG(a)
Definition: SpuFakeDma.h:112
int stallingUnalignedDmaSmallGet(void *ls, uint64_t ea, uint32_t size)
this unalignedDma should not be frequently used, only for small data. It handles alignment and perfor...
Definition: SpuFakeDma.cpp:62
const btTransform & getInterpolationWorldTransform() const
int cellDmaLargePut(const void *ls, uint64_t ea, uint32_t size, uint32_t tag, uint32_t tid, uint32_t rid)
cellDmaLargePut Win32 replacements for Cell DMA to allow simulating most of the SPU code (just memcpy...
Definition: SpuFakeDma.cpp:192
void integrateVelocities(btScalar step)
#define spu_printf
bool isStaticOrKinematicObject() const
btCollisionObject can be used to manage collision detection objects.
The btRigidBody is the main class for rigid body objects.
Definition: btRigidBody.h:59
void cellDmaWaitTagStatusAll(int ignore)
cellDmaWaitTagStatusAll Win32 replacements for Cell DMA to allow simulating most of the SPU code (jus...
Definition: SpuFakeDma.cpp:210
void proceedToTransform(const btTransform &newTrans)
char gLocalRigidBody[sizeof(btRigidBody)+16]
#define ATTRIBUTE_ALIGNED16(a)
Definition: btScalar.h:59
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:34
void applyDamping(btScalar timeStep)
applyDamping damps the velocity, using the given m_linearDamping and m_angularDamping ...
uint64_t m_mainMemoryPtr
Definition: SpuSampleTask.h:42
void processSampleTask(void *userPtr, void *lsMemory)
uint32_t m_sampleCommand
Definition: SpuSampleTask.h:39
bool isActive() const