SpuContactResult.cpp

Go to the documentation of this file.
00001 /*
00002 Bullet Continuous Collision Detection and Physics Library
00003 Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
00004 
00005 This software is provided 'as-is', without any express or implied warranty.
00006 In no event will the authors be held liable for any damages arising from the use of this software.
00007 Permission is granted to anyone to use this software for any purpose, 
00008 including commercial applications, and to alter it and redistribute it freely, 
00009 subject to the following restrictions:
00010 
00011 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
00012 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
00013 3. This notice may not be removed or altered from any source distribution.
00014 */
00015 
00016 #include "SpuContactResult.h"
00017 
00018 //#define DEBUG_SPU_COLLISION_DETECTION 1
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         //spu_printf("SpuContactResult::setContactInfo ManifoldAddress: %lu\n", manifoldAddress);
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 //      float contactTreshold = manifoldPtr->getContactBreakingThreshold();
00093 
00094         //spu_printf("SPU: add contactpoint, depth:%f, contactTreshold %f, manifoldPtr %llx\n",depth,contactTreshold,manifoldPtr);
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         //provide inverses or just calculate?
00103         btTransform transAInv = transA.inverse();//m_body0->m_cachedInvertedWorldTransform;
00104         btTransform transBInv= transB.inverse();//m_body1->m_cachedInvertedWorldTransform;
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                 /*localA = transBInv(pointA );
00118                 localB = transAInv(pointInWorld);*/
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 //              manifoldPtr->replaceContactPoint(newPt,insertIndex);
00134 //              return true;
00135 
00136 #ifdef DEBUG_SPU_COLLISION_DETECTION
00137                 spu_printf("SPU: same contact detected, nothing done\n");
00138 #endif //DEBUG_SPU_COLLISION_DETECTION
00139                 // This is not needed, just use the old info! saves a DMA transfer as well
00140         } else
00141         {
00142 
00143                 newPt.m_combinedFriction = combinedFriction;
00144                 newPt.m_combinedRestitution = combinedRestitution;
00145 
00146                 /*
00148                 //User can override friction and/or restitution
00149                 if (gContactAddedCallback &&
00150                         //and if either of the two bodies requires custom material
00151                          ((m_body0->m_collisionFlags & btCollisionObject::customMaterialCallback) ||
00152                            (m_body1->m_collisionFlags & btCollisionObject::customMaterialCallback)))
00153                 {
00154                         //experimental feature info, for per-triangle material etc.
00155                         (*gContactAddedCallback)(newPt,m_body0,m_partId0,m_index0,m_body1,m_partId1,m_index1);
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         // Should there be any kind of wait here?  What if somebody tries to use this tag again?  What if we call this function again really soon?
00178         //no, the swapBuffers does the wait
00179 #endif
00180 }
00181 
00182 void SpuContactResult::addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)
00183 {
00184         //spu_printf("*** SpuContactResult::addContactPoint: depth = %f\n",depth);
00185 
00186 #ifdef DEBUG_SPU_COLLISION_DETECTION
00187  //   int sman = sizeof(rage::phManifold);
00188 //      spu_printf("sizeof_manifold = %i\n",sman);
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         //process the contact point
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         //      spu_printf("writeDoubleBufferedManifold\n");
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 

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