Back to index

supertuxkart  0.5+dfsg1
btCompoundCollisionAlgorithm.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 "BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h"
00017 #include "BulletCollision/CollisionDispatch/btCollisionObject.h"
00018 #include "BulletCollision/CollisionShapes/btCompoundShape.h"
00019 
00020 
00021 btCompoundCollisionAlgorithm::btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped)
00022 :btCollisionAlgorithm(ci),
00023 m_isSwapped(isSwapped)
00024 {
00025        btCollisionObject* colObj = m_isSwapped? body1 : body0;
00026        btCollisionObject* otherObj = m_isSwapped? body0 : body1;
00027        assert (colObj->getCollisionShape()->isCompound());
00028        
00029        btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->getCollisionShape());
00030        int numChildren = compoundShape->getNumChildShapes();
00031        int i;
00032        
00033        m_childCollisionAlgorithms.resize(numChildren);
00034        for (i=0;i<numChildren;i++)
00035        {
00036               btCollisionShape* childShape = compoundShape->getChildShape(i);
00037               btCollisionShape* orgShape = colObj->getCollisionShape();
00038               colObj->setCollisionShape( childShape );
00039               m_childCollisionAlgorithms[i] = ci.m_dispatcher1->findAlgorithm(colObj,otherObj);
00040               colObj->setCollisionShape( orgShape );
00041        }
00042 }
00043 
00044 
00045 btCompoundCollisionAlgorithm::~btCompoundCollisionAlgorithm()
00046 {
00047        int numChildren = m_childCollisionAlgorithms.size();
00048        int i;
00049        for (i=0;i<numChildren;i++)
00050        {
00051               m_childCollisionAlgorithms[i]->~btCollisionAlgorithm();
00052               m_dispatcher->freeCollisionAlgorithm(m_childCollisionAlgorithms[i]);
00053        }
00054 }
00055 
00056 void btCompoundCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
00057 {
00058        btCollisionObject* colObj = m_isSwapped? body1 : body0;
00059        btCollisionObject* otherObj = m_isSwapped? body0 : body1;
00060 
00061        assert (colObj->getCollisionShape()->isCompound());
00062        btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->getCollisionShape());
00063 
00064        //We will use the OptimizedBVH, AABB tree to cull potential child-overlaps
00065        //If both proxies are Compound, we will deal with that directly, by performing sequential/parallel tree traversals
00066        //given Proxy0 and Proxy1, if both have a tree, Tree0 and Tree1, this means:
00067        //determine overlapping nodes of Proxy1 using Proxy0 AABB against Tree1
00068        //then use each overlapping node AABB against Tree0
00069        //and vise versa.
00070 
00071        int numChildren = m_childCollisionAlgorithms.size();
00072        int i;
00073        for (i=0;i<numChildren;i++)
00074        {
00075               //temporarily exchange parent btCollisionShape with childShape, and recurse
00076               btCollisionShape* childShape = compoundShape->getChildShape(i);
00077 
00078               //backup
00079               btTransform   orgTrans = colObj->getWorldTransform();
00080               btCollisionShape* orgShape = colObj->getCollisionShape();
00081 
00082               const btTransform& childTrans = compoundShape->getChildTransform(i);
00083               //btTransform newChildWorldTrans = orgTrans*childTrans ;
00084               colObj->setWorldTransform( orgTrans*childTrans );
00085               //the contactpoint is still projected back using the original inverted worldtrans
00086               colObj->setCollisionShape( childShape );
00087               m_childCollisionAlgorithms[i]->processCollision(colObj,otherObj,dispatchInfo,resultOut);
00088               //revert back
00089               colObj->setCollisionShape( orgShape);
00090               colObj->setWorldTransform(  orgTrans );
00091        }
00092 }
00093 
00094 btScalar      btCompoundCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
00095 {
00096 
00097        btCollisionObject* colObj = m_isSwapped? body1 : body0;
00098        btCollisionObject* otherObj = m_isSwapped? body0 : body1;
00099 
00100        assert (colObj->getCollisionShape()->isCompound());
00101        
00102        btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->getCollisionShape());
00103 
00104        //We will use the OptimizedBVH, AABB tree to cull potential child-overlaps
00105        //If both proxies are Compound, we will deal with that directly, by performing sequential/parallel tree traversals
00106        //given Proxy0 and Proxy1, if both have a tree, Tree0 and Tree1, this means:
00107        //determine overlapping nodes of Proxy1 using Proxy0 AABB against Tree1
00108        //then use each overlapping node AABB against Tree0
00109        //and vise versa.
00110 
00111        btScalar hitFraction = btScalar(1.);
00112 
00113        int numChildren = m_childCollisionAlgorithms.size();
00114        int i;
00115        for (i=0;i<numChildren;i++)
00116        {
00117               //temporarily exchange parent btCollisionShape with childShape, and recurse
00118               btCollisionShape* childShape = compoundShape->getChildShape(i);
00119 
00120               //backup
00121               btTransform   orgTrans = colObj->getWorldTransform();
00122               btCollisionShape* orgShape = colObj->getCollisionShape();
00123 
00124               const btTransform& childTrans = compoundShape->getChildTransform(i);
00125               //btTransform newChildWorldTrans = orgTrans*childTrans ;
00126               colObj->setWorldTransform( orgTrans*childTrans );
00127 
00128               colObj->setCollisionShape( childShape );
00129               btScalar frac = m_childCollisionAlgorithms[i]->calculateTimeOfImpact(colObj,otherObj,dispatchInfo,resultOut);
00130               if (frac<hitFraction)
00131               {
00132                      hitFraction = frac;
00133               }
00134               //revert back
00135               colObj->setCollisionShape( orgShape);
00136               colObj->setWorldTransform( orgTrans);
00137        }
00138        return hitFraction;
00139 
00140 }
00141 
00142