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