Blender V2.61 - r43446

btConvexPlaneCollisionAlgorithm.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 "btConvexPlaneCollisionAlgorithm.h"
00017 
00018 #include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
00019 #include "BulletCollision/CollisionDispatch/btCollisionObject.h"
00020 #include "BulletCollision/CollisionShapes/btConvexShape.h"
00021 #include "BulletCollision/CollisionShapes/btStaticPlaneShape.h"
00022 
00023 //#include <stdio.h>
00024 
00025 btConvexPlaneCollisionAlgorithm::btConvexPlaneCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped, int numPerturbationIterations,int minimumPointsPerturbationThreshold)
00026 : btCollisionAlgorithm(ci),
00027 m_ownManifold(false),
00028 m_manifoldPtr(mf),
00029 m_isSwapped(isSwapped),
00030 m_numPerturbationIterations(numPerturbationIterations),
00031 m_minimumPointsPerturbationThreshold(minimumPointsPerturbationThreshold)
00032 {
00033     btCollisionObject* convexObj = m_isSwapped? col1 : col0;
00034     btCollisionObject* planeObj = m_isSwapped? col0 : col1;
00035 
00036     if (!m_manifoldPtr && m_dispatcher->needsCollision(convexObj,planeObj))
00037     {
00038         m_manifoldPtr = m_dispatcher->getNewManifold(convexObj,planeObj);
00039         m_ownManifold = true;
00040     }
00041 }
00042 
00043 
00044 btConvexPlaneCollisionAlgorithm::~btConvexPlaneCollisionAlgorithm()
00045 {
00046     if (m_ownManifold)
00047     {
00048         if (m_manifoldPtr)
00049             m_dispatcher->releaseManifold(m_manifoldPtr);
00050     }
00051 }
00052 
00053 void btConvexPlaneCollisionAlgorithm::collideSingleContact (const btQuaternion& perturbeRot, btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
00054 {
00055     btCollisionObject* convexObj = m_isSwapped? body1 : body0;
00056     btCollisionObject* planeObj = m_isSwapped? body0: body1;
00057 
00058     btConvexShape* convexShape = (btConvexShape*) convexObj->getCollisionShape();
00059     btStaticPlaneShape* planeShape = (btStaticPlaneShape*) planeObj->getCollisionShape();
00060 
00061     bool hasCollision = false;
00062     const btVector3& planeNormal = planeShape->getPlaneNormal();
00063     const btScalar& planeConstant = planeShape->getPlaneConstant();
00064     
00065     btTransform convexWorldTransform = convexObj->getWorldTransform();
00066     btTransform convexInPlaneTrans;
00067     convexInPlaneTrans= planeObj->getWorldTransform().inverse() * convexWorldTransform;
00068     //now perturbe the convex-world transform
00069     convexWorldTransform.getBasis()*=btMatrix3x3(perturbeRot);
00070     btTransform planeInConvex;
00071     planeInConvex= convexWorldTransform.inverse() * planeObj->getWorldTransform();
00072     
00073     btVector3 vtx = convexShape->localGetSupportingVertex(planeInConvex.getBasis()*-planeNormal);
00074 
00075     btVector3 vtxInPlane = convexInPlaneTrans(vtx);
00076     btScalar distance = (planeNormal.dot(vtxInPlane) - planeConstant);
00077 
00078     btVector3 vtxInPlaneProjected = vtxInPlane - distance*planeNormal;
00079     btVector3 vtxInPlaneWorld = planeObj->getWorldTransform() * vtxInPlaneProjected;
00080 
00081     hasCollision = distance < m_manifoldPtr->getContactBreakingThreshold();
00082     resultOut->setPersistentManifold(m_manifoldPtr);
00083     if (hasCollision)
00084     {
00086         btVector3 normalOnSurfaceB = planeObj->getWorldTransform().getBasis() * planeNormal;
00087         btVector3 pOnB = vtxInPlaneWorld;
00088         resultOut->addContactPoint(normalOnSurfaceB,pOnB,distance);
00089     }
00090 }
00091 
00092 
00093 void btConvexPlaneCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
00094 {
00095     (void)dispatchInfo;
00096     if (!m_manifoldPtr)
00097         return;
00098 
00099     btCollisionObject* convexObj = m_isSwapped? body1 : body0;
00100     btCollisionObject* planeObj = m_isSwapped? body0: body1;
00101 
00102     btConvexShape* convexShape = (btConvexShape*) convexObj->getCollisionShape();
00103     btStaticPlaneShape* planeShape = (btStaticPlaneShape*) planeObj->getCollisionShape();
00104 
00105     
00106     const btVector3& planeNormal = planeShape->getPlaneNormal();
00107     //const btScalar& planeConstant = planeShape->getPlaneConstant();
00108 
00109     //first perform a collision query with the non-perturbated collision objects
00110     {
00111         btQuaternion rotq(0,0,0,1);
00112         collideSingleContact(rotq,body0,body1,dispatchInfo,resultOut);
00113     }
00114 
00115     if (resultOut->getPersistentManifold()->getNumContacts()<m_minimumPointsPerturbationThreshold)
00116     {
00117         btVector3 v0,v1;
00118         btPlaneSpace1(planeNormal,v0,v1);
00119         //now perform 'm_numPerturbationIterations' collision queries with the perturbated collision objects
00120 
00121         const btScalar angleLimit = 0.125f * SIMD_PI;
00122         btScalar perturbeAngle;
00123         btScalar radius = convexShape->getAngularMotionDisc();
00124         perturbeAngle = gContactBreakingThreshold / radius;
00125         if ( perturbeAngle > angleLimit ) 
00126                 perturbeAngle = angleLimit;
00127 
00128         btQuaternion perturbeRot(v0,perturbeAngle);
00129         for (int i=0;i<m_numPerturbationIterations;i++)
00130         {
00131             btScalar iterationAngle = i*(SIMD_2_PI/btScalar(m_numPerturbationIterations));
00132             btQuaternion rotq(planeNormal,iterationAngle);
00133             collideSingleContact(rotq.inverse()*perturbeRot*rotq,body0,body1,dispatchInfo,resultOut);
00134         }
00135     }
00136 
00137     if (m_ownManifold)
00138     {
00139         if (m_manifoldPtr->getNumContacts())
00140         {
00141             resultOut->refreshContactPoints();
00142         }
00143     }
00144 }
00145 
00146 btScalar btConvexPlaneCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
00147 {
00148     (void)resultOut;
00149     (void)dispatchInfo;
00150     (void)col0;
00151     (void)col1;
00152 
00153     //not yet
00154     return btScalar(1.);
00155 }