btManifoldResult.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 
00017 #include "btManifoldResult.h"
00018 #include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
00019 #include "BulletCollision/CollisionDispatch/btCollisionObject.h"
00020 #include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
00021 
00023 ContactAddedCallback            gContactAddedCallback=0;
00024 
00025 
00026 
00028 inline btScalar calculateCombinedRollingFriction(const btCollisionObject* body0,const btCollisionObject* body1)
00029 {
00030         btScalar friction = body0->getRollingFriction() * body1->getRollingFriction();
00031 
00032         const btScalar MAX_FRICTION  = btScalar(10.);
00033         if (friction < -MAX_FRICTION)
00034                 friction = -MAX_FRICTION;
00035         if (friction > MAX_FRICTION)
00036                 friction = MAX_FRICTION;
00037         return friction;
00038 
00039 }
00040 
00041 
00043 btScalar        btManifoldResult::calculateCombinedFriction(const btCollisionObject* body0,const btCollisionObject* body1)
00044 {
00045         btScalar friction = body0->getFriction() * body1->getFriction();
00046 
00047         const btScalar MAX_FRICTION  = btScalar(10.);
00048         if (friction < -MAX_FRICTION)
00049                 friction = -MAX_FRICTION;
00050         if (friction > MAX_FRICTION)
00051                 friction = MAX_FRICTION;
00052         return friction;
00053 
00054 }
00055 
00056 btScalar        btManifoldResult::calculateCombinedRestitution(const btCollisionObject* body0,const btCollisionObject* body1)
00057 {
00058         return body0->getRestitution() * body1->getRestitution();
00059 }
00060 
00061 
00062 
00063 btManifoldResult::btManifoldResult(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
00064                 :m_manifoldPtr(0),
00065                 m_body0Wrap(body0Wrap),
00066                 m_body1Wrap(body1Wrap)
00067 #ifdef DEBUG_PART_INDEX
00068                 ,m_partId0(-1),
00069         m_partId1(-1),
00070         m_index0(-1),
00071         m_index1(-1)
00072 #endif //DEBUG_PART_INDEX
00073 {
00074 }
00075 
00076 
00077 void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)
00078 {
00079         btAssert(m_manifoldPtr);
00080         //order in manifold needs to match
00081 
00082         if (depth > m_manifoldPtr->getContactBreakingThreshold())
00083 //      if (depth > m_manifoldPtr->getContactProcessingThreshold())
00084                 return;
00085 
00086         bool isSwapped = m_manifoldPtr->getBody0() != m_body0Wrap->getCollisionObject();
00087 
00088         btVector3 pointA = pointInWorld + normalOnBInWorld * depth;
00089 
00090         btVector3 localA;
00091         btVector3 localB;
00092         
00093         if (isSwapped)
00094         {
00095                 localA = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointA );
00096                 localB = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld);
00097         } else
00098         {
00099                 localA = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointA );
00100                 localB = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld);
00101         }
00102 
00103         btManifoldPoint newPt(localA,localB,normalOnBInWorld,depth);
00104         newPt.m_positionWorldOnA = pointA;
00105         newPt.m_positionWorldOnB = pointInWorld;
00106         
00107         int insertIndex = m_manifoldPtr->getCacheEntry(newPt);
00108 
00109         newPt.m_combinedFriction = calculateCombinedFriction(m_body0Wrap->getCollisionObject(),m_body1Wrap->getCollisionObject());
00110         newPt.m_combinedRestitution = calculateCombinedRestitution(m_body0Wrap->getCollisionObject(),m_body1Wrap->getCollisionObject());
00111         newPt.m_combinedRollingFriction = calculateCombinedRollingFriction(m_body0Wrap->getCollisionObject(),m_body1Wrap->getCollisionObject());
00112         btPlaneSpace1(newPt.m_normalWorldOnB,newPt.m_lateralFrictionDir1,newPt.m_lateralFrictionDir2);
00113         
00114 
00115         
00116    //BP mod, store contact triangles.
00117         if (isSwapped)
00118         {
00119                 newPt.m_partId0 = m_partId1;
00120                 newPt.m_partId1 = m_partId0;
00121                 newPt.m_index0  = m_index1;
00122                 newPt.m_index1  = m_index0;
00123         } else
00124         {
00125                 newPt.m_partId0 = m_partId0;
00126                 newPt.m_partId1 = m_partId1;
00127                 newPt.m_index0  = m_index0;
00128                 newPt.m_index1  = m_index1;
00129         }
00130         //printf("depth=%f\n",depth);
00132         if (insertIndex >= 0)
00133         {
00134                 //const btManifoldPoint& oldPoint = m_manifoldPtr->getContactPoint(insertIndex);
00135                 m_manifoldPtr->replaceContactPoint(newPt,insertIndex);
00136         } else
00137         {
00138                 insertIndex = m_manifoldPtr->addManifoldPoint(newPt);
00139         }
00140         
00141         //User can override friction and/or restitution
00142         if (gContactAddedCallback &&
00143                 //and if either of the two bodies requires custom material
00144                  ((m_body0Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) ||
00145                    (m_body1Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK)))
00146         {
00147                 //experimental feature info, for per-triangle material etc.
00148                 const btCollisionObjectWrapper* obj0Wrap = isSwapped? m_body1Wrap : m_body0Wrap;
00149                 const btCollisionObjectWrapper* obj1Wrap = isSwapped? m_body0Wrap : m_body1Wrap;
00150                 (*gContactAddedCallback)(m_manifoldPtr->getContactPoint(insertIndex),obj0Wrap,newPt.m_partId0,newPt.m_index0,obj1Wrap,newPt.m_partId1,newPt.m_index1);
00151         }
00152 
00153 }
00154