Blender V2.61 - r43446
|
00001 /* 00002 Bullet Continuous Collision Detection and Physics Library 00003 Copyright (c) 2003-2006 Erwin Coumans http://bulletphysics.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 00065 #ifndef COLLISION_WORLD_H 00066 #define COLLISION_WORLD_H 00067 00068 class btStackAlloc; 00069 class btCollisionShape; 00070 class btConvexShape; 00071 class btBroadphaseInterface; 00072 class btSerializer; 00073 00074 #include "LinearMath/btVector3.h" 00075 #include "LinearMath/btTransform.h" 00076 #include "btCollisionObject.h" 00077 #include "btCollisionDispatcher.h" 00078 #include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h" 00079 #include "LinearMath/btAlignedObjectArray.h" 00080 00082 class btCollisionWorld 00083 { 00084 00085 00086 protected: 00087 00088 btAlignedObjectArray<btCollisionObject*> m_collisionObjects; 00089 00090 btDispatcher* m_dispatcher1; 00091 00092 btDispatcherInfo m_dispatchInfo; 00093 00094 btStackAlloc* m_stackAlloc; 00095 00096 btBroadphaseInterface* m_broadphasePairCache; 00097 00098 btIDebugDraw* m_debugDrawer; 00099 00102 bool m_forceUpdateAllAabbs; 00103 00104 void serializeCollisionObjects(btSerializer* serializer); 00105 00106 public: 00107 00108 //this constructor doesn't own the dispatcher and paircache/broadphase 00109 btCollisionWorld(btDispatcher* dispatcher,btBroadphaseInterface* broadphasePairCache, btCollisionConfiguration* collisionConfiguration); 00110 00111 virtual ~btCollisionWorld(); 00112 00113 void setBroadphase(btBroadphaseInterface* pairCache) 00114 { 00115 m_broadphasePairCache = pairCache; 00116 } 00117 00118 const btBroadphaseInterface* getBroadphase() const 00119 { 00120 return m_broadphasePairCache; 00121 } 00122 00123 btBroadphaseInterface* getBroadphase() 00124 { 00125 return m_broadphasePairCache; 00126 } 00127 00128 btOverlappingPairCache* getPairCache() 00129 { 00130 return m_broadphasePairCache->getOverlappingPairCache(); 00131 } 00132 00133 00134 btDispatcher* getDispatcher() 00135 { 00136 return m_dispatcher1; 00137 } 00138 00139 const btDispatcher* getDispatcher() const 00140 { 00141 return m_dispatcher1; 00142 } 00143 00144 void updateSingleAabb(btCollisionObject* colObj); 00145 00146 virtual void updateAabbs(); 00147 00148 virtual void setDebugDrawer(btIDebugDraw* debugDrawer) 00149 { 00150 m_debugDrawer = debugDrawer; 00151 } 00152 00153 virtual btIDebugDraw* getDebugDrawer() 00154 { 00155 return m_debugDrawer; 00156 } 00157 00158 virtual void debugDrawWorld(); 00159 00160 virtual void debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color); 00161 00162 00165 struct LocalShapeInfo 00166 { 00167 int m_shapePart; 00168 int m_triangleIndex; 00169 00170 //const btCollisionShape* m_shapeTemp; 00171 //const btTransform* m_shapeLocalTransform; 00172 }; 00173 00174 struct LocalRayResult 00175 { 00176 LocalRayResult(btCollisionObject* collisionObject, 00177 LocalShapeInfo* localShapeInfo, 00178 const btVector3& hitNormalLocal, 00179 btScalar hitFraction) 00180 :m_collisionObject(collisionObject), 00181 m_localShapeInfo(localShapeInfo), 00182 m_hitNormalLocal(hitNormalLocal), 00183 m_hitFraction(hitFraction) 00184 { 00185 } 00186 00187 btCollisionObject* m_collisionObject; 00188 LocalShapeInfo* m_localShapeInfo; 00189 btVector3 m_hitNormalLocal; 00190 btScalar m_hitFraction; 00191 00192 }; 00193 00195 struct RayResultCallback 00196 { 00197 btScalar m_closestHitFraction; 00198 btCollisionObject* m_collisionObject; 00199 short int m_collisionFilterGroup; 00200 short int m_collisionFilterMask; 00201 //@BP Mod - Custom flags, currently used to enable backface culling on tri-meshes, see btRaycastCallback 00202 unsigned int m_flags; 00203 00204 virtual ~RayResultCallback() 00205 { 00206 } 00207 bool hasHit() const 00208 { 00209 return (m_collisionObject != 0); 00210 } 00211 00212 RayResultCallback() 00213 :m_closestHitFraction(btScalar(1.)), 00214 m_collisionObject(0), 00215 m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter), 00216 m_collisionFilterMask(btBroadphaseProxy::AllFilter), 00217 //@BP Mod 00218 m_flags(0) 00219 { 00220 } 00221 00222 virtual bool needsCollision(btBroadphaseProxy* proxy0) const 00223 { 00224 bool collides = (proxy0->m_collisionFilterGroup & m_collisionFilterMask) != 0; 00225 collides = collides && (m_collisionFilterGroup & proxy0->m_collisionFilterMask); 00226 return collides; 00227 } 00228 00229 00230 virtual btScalar addSingleResult(LocalRayResult& rayResult,bool normalInWorldSpace) = 0; 00231 }; 00232 00233 struct ClosestRayResultCallback : public RayResultCallback 00234 { 00235 ClosestRayResultCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld) 00236 :m_rayFromWorld(rayFromWorld), 00237 m_rayToWorld(rayToWorld) 00238 { 00239 } 00240 00241 btVector3 m_rayFromWorld;//used to calculate hitPointWorld from hitFraction 00242 btVector3 m_rayToWorld; 00243 00244 btVector3 m_hitNormalWorld; 00245 btVector3 m_hitPointWorld; 00246 00247 virtual btScalar addSingleResult(LocalRayResult& rayResult,bool normalInWorldSpace) 00248 { 00249 //caller already does the filter on the m_closestHitFraction 00250 btAssert(rayResult.m_hitFraction <= m_closestHitFraction); 00251 00252 m_closestHitFraction = rayResult.m_hitFraction; 00253 m_collisionObject = rayResult.m_collisionObject; 00254 if (normalInWorldSpace) 00255 { 00256 m_hitNormalWorld = rayResult.m_hitNormalLocal; 00257 } else 00258 { 00260 m_hitNormalWorld = m_collisionObject->getWorldTransform().getBasis()*rayResult.m_hitNormalLocal; 00261 } 00262 m_hitPointWorld.setInterpolate3(m_rayFromWorld,m_rayToWorld,rayResult.m_hitFraction); 00263 return rayResult.m_hitFraction; 00264 } 00265 }; 00266 00267 struct AllHitsRayResultCallback : public RayResultCallback 00268 { 00269 AllHitsRayResultCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld) 00270 :m_rayFromWorld(rayFromWorld), 00271 m_rayToWorld(rayToWorld) 00272 { 00273 } 00274 00275 btAlignedObjectArray<btCollisionObject*> m_collisionObjects; 00276 00277 btVector3 m_rayFromWorld;//used to calculate hitPointWorld from hitFraction 00278 btVector3 m_rayToWorld; 00279 00280 btAlignedObjectArray<btVector3> m_hitNormalWorld; 00281 btAlignedObjectArray<btVector3> m_hitPointWorld; 00282 btAlignedObjectArray<btScalar> m_hitFractions; 00283 00284 virtual btScalar addSingleResult(LocalRayResult& rayResult,bool normalInWorldSpace) 00285 { 00286 m_collisionObject = rayResult.m_collisionObject; 00287 m_collisionObjects.push_back(rayResult.m_collisionObject); 00288 btVector3 hitNormalWorld; 00289 if (normalInWorldSpace) 00290 { 00291 hitNormalWorld = rayResult.m_hitNormalLocal; 00292 } else 00293 { 00295 hitNormalWorld = m_collisionObject->getWorldTransform().getBasis()*rayResult.m_hitNormalLocal; 00296 } 00297 m_hitNormalWorld.push_back(hitNormalWorld); 00298 btVector3 hitPointWorld; 00299 hitPointWorld.setInterpolate3(m_rayFromWorld,m_rayToWorld,rayResult.m_hitFraction); 00300 m_hitPointWorld.push_back(hitPointWorld); 00301 m_hitFractions.push_back(rayResult.m_hitFraction); 00302 return m_closestHitFraction; 00303 } 00304 }; 00305 00306 00307 struct LocalConvexResult 00308 { 00309 LocalConvexResult(btCollisionObject* hitCollisionObject, 00310 LocalShapeInfo* localShapeInfo, 00311 const btVector3& hitNormalLocal, 00312 const btVector3& hitPointLocal, 00313 btScalar hitFraction 00314 ) 00315 :m_hitCollisionObject(hitCollisionObject), 00316 m_localShapeInfo(localShapeInfo), 00317 m_hitNormalLocal(hitNormalLocal), 00318 m_hitPointLocal(hitPointLocal), 00319 m_hitFraction(hitFraction) 00320 { 00321 } 00322 00323 btCollisionObject* m_hitCollisionObject; 00324 LocalShapeInfo* m_localShapeInfo; 00325 btVector3 m_hitNormalLocal; 00326 btVector3 m_hitPointLocal; 00327 btScalar m_hitFraction; 00328 }; 00329 00331 struct ConvexResultCallback 00332 { 00333 btScalar m_closestHitFraction; 00334 short int m_collisionFilterGroup; 00335 short int m_collisionFilterMask; 00336 00337 ConvexResultCallback() 00338 :m_closestHitFraction(btScalar(1.)), 00339 m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter), 00340 m_collisionFilterMask(btBroadphaseProxy::AllFilter) 00341 { 00342 } 00343 00344 virtual ~ConvexResultCallback() 00345 { 00346 } 00347 00348 bool hasHit() const 00349 { 00350 return (m_closestHitFraction < btScalar(1.)); 00351 } 00352 00353 00354 00355 virtual bool needsCollision(btBroadphaseProxy* proxy0) const 00356 { 00357 bool collides = (proxy0->m_collisionFilterGroup & m_collisionFilterMask) != 0; 00358 collides = collides && (m_collisionFilterGroup & proxy0->m_collisionFilterMask); 00359 return collides; 00360 } 00361 00362 virtual btScalar addSingleResult(LocalConvexResult& convexResult,bool normalInWorldSpace) = 0; 00363 }; 00364 00365 struct ClosestConvexResultCallback : public ConvexResultCallback 00366 { 00367 ClosestConvexResultCallback(const btVector3& convexFromWorld,const btVector3& convexToWorld) 00368 :m_convexFromWorld(convexFromWorld), 00369 m_convexToWorld(convexToWorld), 00370 m_hitCollisionObject(0) 00371 { 00372 } 00373 00374 btVector3 m_convexFromWorld;//used to calculate hitPointWorld from hitFraction 00375 btVector3 m_convexToWorld; 00376 00377 btVector3 m_hitNormalWorld; 00378 btVector3 m_hitPointWorld; 00379 btCollisionObject* m_hitCollisionObject; 00380 00381 virtual btScalar addSingleResult(LocalConvexResult& convexResult,bool normalInWorldSpace) 00382 { 00383 //caller already does the filter on the m_closestHitFraction 00384 btAssert(convexResult.m_hitFraction <= m_closestHitFraction); 00385 00386 m_closestHitFraction = convexResult.m_hitFraction; 00387 m_hitCollisionObject = convexResult.m_hitCollisionObject; 00388 if (normalInWorldSpace) 00389 { 00390 m_hitNormalWorld = convexResult.m_hitNormalLocal; 00391 } else 00392 { 00394 m_hitNormalWorld = m_hitCollisionObject->getWorldTransform().getBasis()*convexResult.m_hitNormalLocal; 00395 } 00396 m_hitPointWorld = convexResult.m_hitPointLocal; 00397 return convexResult.m_hitFraction; 00398 } 00399 }; 00400 00402 struct ContactResultCallback 00403 { 00404 short int m_collisionFilterGroup; 00405 short int m_collisionFilterMask; 00406 00407 ContactResultCallback() 00408 :m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter), 00409 m_collisionFilterMask(btBroadphaseProxy::AllFilter) 00410 { 00411 } 00412 00413 virtual ~ContactResultCallback() 00414 { 00415 } 00416 00417 virtual bool needsCollision(btBroadphaseProxy* proxy0) const 00418 { 00419 bool collides = (proxy0->m_collisionFilterGroup & m_collisionFilterMask) != 0; 00420 collides = collides && (m_collisionFilterGroup & proxy0->m_collisionFilterMask); 00421 return collides; 00422 } 00423 00424 virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1) = 0; 00425 }; 00426 00427 00428 00429 int getNumCollisionObjects() const 00430 { 00431 return int(m_collisionObjects.size()); 00432 } 00433 00436 virtual void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const; 00437 00440 void convexSweepTest (const btConvexShape* castShape, const btTransform& from, const btTransform& to, ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration = btScalar(0.)) const; 00441 00444 void contactTest(btCollisionObject* colObj, ContactResultCallback& resultCallback); 00445 00448 void contactPairTest(btCollisionObject* colObjA, btCollisionObject* colObjB, ContactResultCallback& resultCallback); 00449 00450 00454 static void rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans, 00455 btCollisionObject* collisionObject, 00456 const btCollisionShape* collisionShape, 00457 const btTransform& colObjWorldTransform, 00458 RayResultCallback& resultCallback); 00459 00461 static void objectQuerySingle(const btConvexShape* castShape, const btTransform& rayFromTrans,const btTransform& rayToTrans, 00462 btCollisionObject* collisionObject, 00463 const btCollisionShape* collisionShape, 00464 const btTransform& colObjWorldTransform, 00465 ConvexResultCallback& resultCallback, btScalar allowedPenetration); 00466 00467 virtual void addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup=btBroadphaseProxy::DefaultFilter,short int collisionFilterMask=btBroadphaseProxy::AllFilter); 00468 00469 btCollisionObjectArray& getCollisionObjectArray() 00470 { 00471 return m_collisionObjects; 00472 } 00473 00474 const btCollisionObjectArray& getCollisionObjectArray() const 00475 { 00476 return m_collisionObjects; 00477 } 00478 00479 00480 virtual void removeCollisionObject(btCollisionObject* collisionObject); 00481 00482 virtual void performDiscreteCollisionDetection(); 00483 00484 btDispatcherInfo& getDispatchInfo() 00485 { 00486 return m_dispatchInfo; 00487 } 00488 00489 const btDispatcherInfo& getDispatchInfo() const 00490 { 00491 return m_dispatchInfo; 00492 } 00493 00494 bool getForceUpdateAllAabbs() const 00495 { 00496 return m_forceUpdateAllAabbs; 00497 } 00498 void setForceUpdateAllAabbs( bool forceUpdateAllAabbs) 00499 { 00500 m_forceUpdateAllAabbs = forceUpdateAllAabbs; 00501 } 00502 00504 virtual void serialize(btSerializer* serializer); 00505 00506 }; 00507 00508 00509 #endif //COLLISION_WORLD_H