Home | History | Annotate | Download | only in CollisionDispatch
      1 /*
      2 Bullet Continuous Collision Detection and Physics Library
      3 Copyright (c) 2003-2008 Erwin Coumans  http://bulletphysics.com
      4 
      5 This software is provided 'as-is', without any express or implied warranty.
      6 In no event will the authors be held liable for any damages arising from the use of this software.
      7 Permission is granted to anyone to use this software for any purpose,
      8 including commercial applications, and to alter it and redistribute it freely,
      9 subject to the following restrictions:
     10 
     11 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.
     12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
     13 3. This notice may not be removed or altered from any source distribution.
     14 */
     15 
     16 #include "btGhostObject.h"
     17 #include "btCollisionWorld.h"
     18 #include "BulletCollision/CollisionShapes/btConvexShape.h"
     19 #include "LinearMath/btAabbUtil2.h"
     20 
     21 btGhostObject::btGhostObject()
     22 {
     23 	m_internalType = CO_GHOST_OBJECT;
     24 }
     25 
     26 btGhostObject::~btGhostObject()
     27 {
     28 	///btGhostObject should have been removed from the world, so no overlapping objects
     29 	btAssert(!m_overlappingObjects.size());
     30 }
     31 
     32 
     33 void btGhostObject::addOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btBroadphaseProxy* thisProxy)
     34 {
     35 	btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
     36 	btAssert(otherObject);
     37 	///if this linearSearch becomes too slow (too many overlapping objects) we should add a more appropriate data structure
     38 	int index = m_overlappingObjects.findLinearSearch(otherObject);
     39 	if (index==m_overlappingObjects.size())
     40 	{
     41 		//not found
     42 		m_overlappingObjects.push_back(otherObject);
     43 	}
     44 }
     45 
     46 void btGhostObject::removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher,btBroadphaseProxy* thisProxy)
     47 {
     48 	btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
     49 	btAssert(otherObject);
     50 	int index = m_overlappingObjects.findLinearSearch(otherObject);
     51 	if (index<m_overlappingObjects.size())
     52 	{
     53 		m_overlappingObjects[index] = m_overlappingObjects[m_overlappingObjects.size()-1];
     54 		m_overlappingObjects.pop_back();
     55 	}
     56 }
     57 
     58 
     59 btPairCachingGhostObject::btPairCachingGhostObject()
     60 {
     61 	m_hashPairCache = new (btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16)) btHashedOverlappingPairCache();
     62 }
     63 
     64 btPairCachingGhostObject::~btPairCachingGhostObject()
     65 {
     66 	m_hashPairCache->~btHashedOverlappingPairCache();
     67 	btAlignedFree( m_hashPairCache );
     68 }
     69 
     70 void btPairCachingGhostObject::addOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btBroadphaseProxy* thisProxy)
     71 {
     72 	btBroadphaseProxy*actualThisProxy = thisProxy ? thisProxy : getBroadphaseHandle();
     73 	btAssert(actualThisProxy);
     74 
     75 	btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
     76 	btAssert(otherObject);
     77 	int index = m_overlappingObjects.findLinearSearch(otherObject);
     78 	if (index==m_overlappingObjects.size())
     79 	{
     80 		m_overlappingObjects.push_back(otherObject);
     81 		m_hashPairCache->addOverlappingPair(actualThisProxy,otherProxy);
     82 	}
     83 }
     84 
     85 void btPairCachingGhostObject::removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher,btBroadphaseProxy* thisProxy1)
     86 {
     87 	btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
     88 	btBroadphaseProxy* actualThisProxy = thisProxy1 ? thisProxy1 : getBroadphaseHandle();
     89 	btAssert(actualThisProxy);
     90 
     91 	btAssert(otherObject);
     92 	int index = m_overlappingObjects.findLinearSearch(otherObject);
     93 	if (index<m_overlappingObjects.size())
     94 	{
     95 		m_overlappingObjects[index] = m_overlappingObjects[m_overlappingObjects.size()-1];
     96 		m_overlappingObjects.pop_back();
     97 		m_hashPairCache->removeOverlappingPair(actualThisProxy,otherProxy,dispatcher);
     98 	}
     99 }
    100 
    101 
    102 void	btGhostObject::convexSweepTest(const btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, btCollisionWorld::ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration) const
    103 {
    104 	btTransform	convexFromTrans,convexToTrans;
    105 	convexFromTrans = convexFromWorld;
    106 	convexToTrans = convexToWorld;
    107 	btVector3 castShapeAabbMin, castShapeAabbMax;
    108 	/* Compute AABB that encompasses angular movement */
    109 	{
    110 		btVector3 linVel, angVel;
    111 		btTransformUtil::calculateVelocity (convexFromTrans, convexToTrans, 1.0, linVel, angVel);
    112 		btTransform R;
    113 		R.setIdentity ();
    114 		R.setRotation (convexFromTrans.getRotation());
    115 		castShape->calculateTemporalAabb (R, linVel, angVel, 1.0, castShapeAabbMin, castShapeAabbMax);
    116 	}
    117 
    118 	/// go over all objects, and if the ray intersects their aabb + cast shape aabb,
    119 	// do a ray-shape query using convexCaster (CCD)
    120 	int i;
    121 	for (i=0;i<m_overlappingObjects.size();i++)
    122 	{
    123 		btCollisionObject*	collisionObject= m_overlappingObjects[i];
    124 		//only perform raycast if filterMask matches
    125 		if(resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) {
    126 			//RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
    127 			btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
    128 			collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
    129 			AabbExpand (collisionObjectAabbMin, collisionObjectAabbMax, castShapeAabbMin, castShapeAabbMax);
    130 			btScalar hitLambda = btScalar(1.); //could use resultCallback.m_closestHitFraction, but needs testing
    131 			btVector3 hitNormal;
    132 			if (btRayAabb(convexFromWorld.getOrigin(),convexToWorld.getOrigin(),collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,hitNormal))
    133 			{
    134 				btCollisionWorld::objectQuerySingle(castShape, convexFromTrans,convexToTrans,
    135 					collisionObject,
    136 						collisionObject->getCollisionShape(),
    137 						collisionObject->getWorldTransform(),
    138 						resultCallback,
    139 						allowedCcdPenetration);
    140 			}
    141 		}
    142 	}
    143 
    144 }
    145 
    146 void	btGhostObject::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const
    147 {
    148 	btTransform rayFromTrans;
    149 	rayFromTrans.setIdentity();
    150 	rayFromTrans.setOrigin(rayFromWorld);
    151 	btTransform  rayToTrans;
    152 	rayToTrans.setIdentity();
    153 	rayToTrans.setOrigin(rayToWorld);
    154 
    155 
    156 	int i;
    157 	for (i=0;i<m_overlappingObjects.size();i++)
    158 	{
    159 		btCollisionObject*	collisionObject= m_overlappingObjects[i];
    160 		//only perform raycast if filterMask matches
    161 		if(resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
    162 		{
    163 			btCollisionWorld::rayTestSingle(rayFromTrans,rayToTrans,
    164 							collisionObject,
    165 								collisionObject->getCollisionShape(),
    166 								collisionObject->getWorldTransform(),
    167 								resultCallback);
    168 		}
    169 	}
    170 }
    171 
    172