Blender V2.61 - r43446
|
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