00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "SpuContactResult.h"
00017
00018
00019
00020
00021 SpuContactResult::SpuContactResult()
00022 {
00023 m_manifoldAddress = 0;
00024 m_spuManifold = NULL;
00025 m_RequiresWriteBack = false;
00026 }
00027
00028 SpuContactResult::~SpuContactResult()
00029 {
00030 g_manifoldDmaExport.swapBuffers();
00031 }
00032
00034 inline btScalar calculateCombinedFriction(btScalar friction0,btScalar friction1)
00035 {
00036 btScalar friction = friction0*friction1;
00037
00038 const btScalar MAX_FRICTION = btScalar(10.);
00039
00040 if (friction < -MAX_FRICTION)
00041 friction = -MAX_FRICTION;
00042 if (friction > MAX_FRICTION)
00043 friction = MAX_FRICTION;
00044 return friction;
00045
00046 }
00047
00048 inline btScalar calculateCombinedRestitution(btScalar restitution0,btScalar restitution1)
00049 {
00050 return restitution0*restitution1;
00051 }
00052
00053
00054
00055 void SpuContactResult::setContactInfo(btPersistentManifold* spuManifold, ppu_address_t manifoldAddress,const btTransform& worldTrans0,const btTransform& worldTrans1, btScalar restitution0,btScalar restitution1, btScalar friction0,btScalar friction1, bool isSwapped)
00056 {
00057
00058 m_rootWorldTransform0 = worldTrans0;
00059 m_rootWorldTransform1 = worldTrans1;
00060 m_manifoldAddress = manifoldAddress;
00061 m_spuManifold = spuManifold;
00062
00063 m_combinedFriction = calculateCombinedFriction(friction0,friction1);
00064 m_combinedRestitution = calculateCombinedRestitution(restitution0,restitution1);
00065 m_isSwapped = isSwapped;
00066 }
00067
00068 void SpuContactResult::setShapeIdentifiersA(int partId0,int index0)
00069 {
00070
00071 }
00072
00073 void SpuContactResult::setShapeIdentifiersB(int partId1,int index1)
00074 {
00075
00076 }
00077
00078
00079
00081 bool ManifoldResultAddContactPoint(const btVector3& normalOnBInWorld,
00082 const btVector3& pointInWorld,
00083 float depth,
00084 btPersistentManifold* manifoldPtr,
00085 btTransform& transA,
00086 btTransform& transB,
00087 btScalar combinedFriction,
00088 btScalar combinedRestitution,
00089 bool isSwapped)
00090 {
00091
00092
00093
00094
00095
00096 #ifdef DEBUG_SPU_COLLISION_DETECTION
00097 spu_printf("SPU: contactTreshold %f\n",contactTreshold);
00098 #endif //DEBUG_SPU_COLLISION_DETECTION
00099 if (depth > manifoldPtr->getContactBreakingThreshold())
00100 return false;
00101
00102
00103 btTransform transAInv = transA.inverse();
00104 btTransform transBInv= transB.inverse();
00105
00106 btVector3 pointA;
00107 btVector3 localA;
00108 btVector3 localB;
00109 btVector3 normal;
00110
00111 if (isSwapped)
00112 {
00113 normal = normalOnBInWorld * -1;
00114 pointA = pointInWorld + normal * depth;
00115 localA = transAInv(pointA );
00116 localB = transBInv(pointInWorld);
00117
00118
00119 }
00120 else
00121 {
00122 normal = normalOnBInWorld;
00123 pointA = pointInWorld + normal * depth;
00124 localA = transAInv(pointA );
00125 localB = transBInv(pointInWorld);
00126 }
00127
00128 btManifoldPoint newPt(localA,localB,normal,depth);
00129
00130 int insertIndex = manifoldPtr->getCacheEntry(newPt);
00131 if (insertIndex >= 0)
00132 {
00133
00134
00135
00136 #ifdef DEBUG_SPU_COLLISION_DETECTION
00137 spu_printf("SPU: same contact detected, nothing done\n");
00138 #endif //DEBUG_SPU_COLLISION_DETECTION
00139
00140 } else
00141 {
00142
00143 newPt.m_combinedFriction = combinedFriction;
00144 newPt.m_combinedRestitution = combinedRestitution;
00145
00146
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158 manifoldPtr->addManifoldPoint(newPt);
00159 return true;
00160
00161 }
00162 return false;
00163
00164 }
00165
00166
00167 void SpuContactResult::writeDoubleBufferedManifold(btPersistentManifold* lsManifold, btPersistentManifold* mmManifold)
00168 {
00171 #if defined (__SPU__) || defined (USE_LIBSPE2)
00172 memcpy(g_manifoldDmaExport.getFront(),lsManifold,sizeof(btPersistentManifold));
00173
00174 g_manifoldDmaExport.swapBuffers();
00175 ppu_address_t mmAddr = (ppu_address_t)mmManifold;
00176 g_manifoldDmaExport.backBufferDmaPut(mmAddr, sizeof(btPersistentManifold), DMA_TAG(9));
00177
00178
00179 #endif
00180 }
00181
00182 void SpuContactResult::addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)
00183 {
00184
00185
00186 #ifdef DEBUG_SPU_COLLISION_DETECTION
00187
00188
00189 #endif //DEBUG_SPU_COLLISION_DETECTION
00190
00191 btPersistentManifold* localManifold = m_spuManifold;
00192
00193 btVector3 normalB(normalOnBInWorld.getX(),normalOnBInWorld.getY(),normalOnBInWorld.getZ());
00194 btVector3 pointWrld(pointInWorld.getX(),pointInWorld.getY(),pointInWorld.getZ());
00195
00196
00197 const bool retVal = ManifoldResultAddContactPoint(normalB,
00198 pointWrld,
00199 depth,
00200 localManifold,
00201 m_rootWorldTransform0,
00202 m_rootWorldTransform1,
00203 m_combinedFriction,
00204 m_combinedRestitution,
00205 m_isSwapped);
00206 m_RequiresWriteBack = m_RequiresWriteBack || retVal;
00207 }
00208
00209 void SpuContactResult::flush()
00210 {
00211
00212 if (m_spuManifold && m_spuManifold->getNumContacts())
00213 {
00214 m_spuManifold->refreshContactPoints(m_rootWorldTransform0,m_rootWorldTransform1);
00215 m_RequiresWriteBack = true;
00216 }
00217
00218
00219 if (m_RequiresWriteBack)
00220 {
00221 #ifdef DEBUG_SPU_COLLISION_DETECTION
00222 spu_printf("SPU: Start SpuContactResult::flush (Put) DMA\n");
00223 spu_printf("Num contacts:%d\n", m_spuManifold->getNumContacts());
00224 spu_printf("Manifold address: %llu\n", m_manifoldAddress);
00225 #endif //DEBUG_SPU_COLLISION_DETECTION
00226
00227 writeDoubleBufferedManifold(m_spuManifold, (btPersistentManifold*)m_manifoldAddress);
00228 #ifdef DEBUG_SPU_COLLISION_DETECTION
00229 spu_printf("SPU: Finished (Put) DMA\n");
00230 #endif //DEBUG_SPU_COLLISION_DETECTION
00231 }
00232 m_spuManifold = NULL;
00233 m_RequiresWriteBack = false;
00234 }
00235
00236