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