Blender V2.61 - r43446

btGhostObject.cpp

Go to the documentation of this file.
00001 /*
00002 Bullet Continuous Collision Detection and Physics Library
00003 Copyright (c) 2003-2008 Erwin Coumans  http://bulletphysics.com
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 "btGhostObject.h"
00017 #include "btCollisionWorld.h"
00018 #include "BulletCollision/CollisionShapes/btConvexShape.h"
00019 #include "LinearMath/btAabbUtil2.h"
00020 
00021 btGhostObject::btGhostObject()
00022 {
00023     m_internalType = CO_GHOST_OBJECT;
00024 }
00025 
00026 btGhostObject::~btGhostObject()
00027 {
00029     btAssert(!m_overlappingObjects.size());
00030 }
00031 
00032 
00033 void btGhostObject::addOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btBroadphaseProxy* thisProxy)
00034 {
00035     btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
00036     btAssert(otherObject);
00038     int index = m_overlappingObjects.findLinearSearch(otherObject);
00039     if (index==m_overlappingObjects.size())
00040     {
00041         //not found
00042         m_overlappingObjects.push_back(otherObject);
00043     }
00044 }
00045 
00046 void btGhostObject::removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher,btBroadphaseProxy* thisProxy)
00047 {
00048     btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
00049     btAssert(otherObject);
00050     int index = m_overlappingObjects.findLinearSearch(otherObject);
00051     if (index<m_overlappingObjects.size())
00052     {
00053         m_overlappingObjects[index] = m_overlappingObjects[m_overlappingObjects.size()-1];
00054         m_overlappingObjects.pop_back();
00055     }
00056 }
00057 
00058 
00059 btPairCachingGhostObject::btPairCachingGhostObject()
00060 {
00061     m_hashPairCache = new (btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16)) btHashedOverlappingPairCache();
00062 }
00063 
00064 btPairCachingGhostObject::~btPairCachingGhostObject()
00065 {
00066     m_hashPairCache->~btHashedOverlappingPairCache();
00067     btAlignedFree( m_hashPairCache );
00068 }
00069 
00070 void btPairCachingGhostObject::addOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btBroadphaseProxy* thisProxy)
00071 {
00072     btBroadphaseProxy*actualThisProxy = thisProxy ? thisProxy : getBroadphaseHandle();
00073     btAssert(actualThisProxy);
00074 
00075     btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
00076     btAssert(otherObject);
00077     int index = m_overlappingObjects.findLinearSearch(otherObject);
00078     if (index==m_overlappingObjects.size())
00079     {
00080         m_overlappingObjects.push_back(otherObject);
00081         m_hashPairCache->addOverlappingPair(actualThisProxy,otherProxy);
00082     }
00083 }
00084 
00085 void btPairCachingGhostObject::removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher,btBroadphaseProxy* thisProxy1)
00086 {
00087     btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
00088     btBroadphaseProxy* actualThisProxy = thisProxy1 ? thisProxy1 : getBroadphaseHandle();
00089     btAssert(actualThisProxy);
00090 
00091     btAssert(otherObject);
00092     int index = m_overlappingObjects.findLinearSearch(otherObject);
00093     if (index<m_overlappingObjects.size())
00094     {
00095         m_overlappingObjects[index] = m_overlappingObjects[m_overlappingObjects.size()-1];
00096         m_overlappingObjects.pop_back();
00097         m_hashPairCache->removeOverlappingPair(actualThisProxy,otherProxy,dispatcher);
00098     }
00099 }
00100 
00101 
00102 void    btGhostObject::convexSweepTest(const btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, btCollisionWorld::ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration) const
00103 {
00104     btTransform convexFromTrans,convexToTrans;
00105     convexFromTrans = convexFromWorld;
00106     convexToTrans = convexToWorld;
00107     btVector3 castShapeAabbMin, castShapeAabbMax;
00108     /* Compute AABB that encompasses angular movement */
00109     {
00110         btVector3 linVel, angVel;
00111         btTransformUtil::calculateVelocity (convexFromTrans, convexToTrans, 1.0, linVel, angVel);
00112         btTransform R;
00113         R.setIdentity ();
00114         R.setRotation (convexFromTrans.getRotation());
00115         castShape->calculateTemporalAabb (R, linVel, angVel, 1.0, castShapeAabbMin, castShapeAabbMax);
00116     }
00117 
00119     // do a ray-shape query using convexCaster (CCD)
00120     int i;
00121     for (i=0;i<m_overlappingObjects.size();i++)
00122     {
00123         btCollisionObject*  collisionObject= m_overlappingObjects[i];
00124         //only perform raycast if filterMask matches
00125         if(resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) {
00126             //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
00127             btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
00128             collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
00129             AabbExpand (collisionObjectAabbMin, collisionObjectAabbMax, castShapeAabbMin, castShapeAabbMax);
00130             btScalar hitLambda = btScalar(1.); //could use resultCallback.m_closestHitFraction, but needs testing
00131             btVector3 hitNormal;
00132             if (btRayAabb(convexFromWorld.getOrigin(),convexToWorld.getOrigin(),collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,hitNormal))
00133             {
00134                 btCollisionWorld::objectQuerySingle(castShape, convexFromTrans,convexToTrans,
00135                     collisionObject,
00136                         collisionObject->getCollisionShape(),
00137                         collisionObject->getWorldTransform(),
00138                         resultCallback,
00139                         allowedCcdPenetration);
00140             }
00141         }
00142     }
00143 
00144 }
00145 
00146 void    btGhostObject::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const
00147 {
00148     btTransform rayFromTrans;
00149     rayFromTrans.setIdentity();
00150     rayFromTrans.setOrigin(rayFromWorld);
00151     btTransform  rayToTrans;
00152     rayToTrans.setIdentity();
00153     rayToTrans.setOrigin(rayToWorld);
00154 
00155 
00156     int i;
00157     for (i=0;i<m_overlappingObjects.size();i++)
00158     {
00159         btCollisionObject*  collisionObject= m_overlappingObjects[i];
00160         //only perform raycast if filterMask matches
00161         if(resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) 
00162         {
00163             btCollisionWorld::rayTestSingle(rayFromTrans,rayToTrans,
00164                             collisionObject,
00165                                 collisionObject->getCollisionShape(),
00166                                 collisionObject->getWorldTransform(),
00167                                 resultCallback);
00168         }
00169     }
00170 }
00171