1 /* 2 Bullet Continuous Collision Detection and Physics Library 3 Copyright (c) 2003-2006 Erwin Coumans http://bulletphysics.com/Bullet/ 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 17 /** 18 * @mainpage Bullet Documentation 19 * 20 * @section intro_sec Introduction 21 * Bullet Collision Detection & Physics SDK 22 * 23 * Bullet is a Collision Detection and Rigid Body Dynamics Library. The Library is Open Source and free for commercial use, under the ZLib license ( http://opensource.org/licenses/zlib-license.php ). 24 * 25 * The main documentation is Bullet_User_Manual.pdf, included in the source code distribution. 26 * There is the Physics Forum for feedback and general Collision Detection and Physics discussions. 27 * Please visit http://www.bulletphysics.com 28 * 29 * @section install_sec Installation 30 * 31 * @subsection step1 Step 1: Download 32 * You can download the Bullet Physics Library from the Google Code repository: http://code.google.com/p/bullet/downloads/list 33 * 34 * @subsection step2 Step 2: Building 35 * Bullet main build system for all platforms is cmake, you can download http://www.cmake.org 36 * cmake can autogenerate projectfiles for Microsoft Visual Studio, Apple Xcode, KDevelop and Unix Makefiles. 37 * The easiest is to run the CMake cmake-gui graphical user interface and choose the options and generate projectfiles. 38 * You can also use cmake in the command-line. Here are some examples for various platforms: 39 * cmake . -G "Visual Studio 9 2008" 40 * cmake . -G Xcode 41 * cmake . -G "Unix Makefiles" 42 * Although cmake is recommended, you can also use autotools for UNIX: ./autogen.sh ./configure to create a Makefile and then run make. 43 * 44 * @subsection step3 Step 3: Testing demos 45 * Try to run and experiment with BasicDemo executable as a starting point. 46 * Bullet can be used in several ways, as Full Rigid Body simulation, as Collision Detector Library or Low Level / Snippets like the GJK Closest Point calculation. 47 * The Dependencies can be seen in this documentation under Directories 48 * 49 * @subsection step4 Step 4: Integrating in your application, full Rigid Body and Soft Body simulation 50 * Check out BasicDemo how to create a btDynamicsWorld, btRigidBody and btCollisionShape, Stepping the simulation and synchronizing your graphics object transform. 51 * Check out SoftDemo how to use soft body dynamics, using btSoftRigidDynamicsWorld. 52 * @subsection step5 Step 5 : Integrate the Collision Detection Library (without Dynamics and other Extras) 53 * Bullet Collision Detection can also be used without the Dynamics/Extras. 54 * Check out btCollisionWorld and btCollisionObject, and the CollisionInterfaceDemo. 55 * @subsection step6 Step 6 : Use Snippets like the GJK Closest Point calculation. 56 * Bullet has been designed in a modular way keeping dependencies to a minimum. The ConvexHullDistance demo demonstrates direct use of btGjkPairDetector. 57 * 58 * @section copyright Copyright 59 * For up-to-data information and copyright and contributors list check out the Bullet_User_Manual.pdf 60 * 61 */ 62 63 64 65 #ifndef COLLISION_WORLD_H 66 #define COLLISION_WORLD_H 67 68 class btStackAlloc; 69 class btCollisionShape; 70 class btConvexShape; 71 class btBroadphaseInterface; 72 class btSerializer; 73 74 #include "LinearMath/btVector3.h" 75 #include "LinearMath/btTransform.h" 76 #include "btCollisionObject.h" 77 #include "btCollisionDispatcher.h" 78 #include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h" 79 #include "LinearMath/btAlignedObjectArray.h" 80 81 ///CollisionWorld is interface and container for the collision detection 82 class btCollisionWorld 83 { 84 85 86 protected: 87 88 btAlignedObjectArray<btCollisionObject*> m_collisionObjects; 89 90 btDispatcher* m_dispatcher1; 91 92 btDispatcherInfo m_dispatchInfo; 93 94 btStackAlloc* m_stackAlloc; 95 96 btBroadphaseInterface* m_broadphasePairCache; 97 98 btIDebugDraw* m_debugDrawer; 99 100 ///m_forceUpdateAllAabbs can be set to false as an optimization to only update active object AABBs 101 ///it is true by default, because it is error-prone (setting the position of static objects wouldn't update their AABB) 102 bool m_forceUpdateAllAabbs; 103 104 void serializeCollisionObjects(btSerializer* serializer); 105 106 public: 107 108 //this constructor doesn't own the dispatcher and paircache/broadphase 109 btCollisionWorld(btDispatcher* dispatcher,btBroadphaseInterface* broadphasePairCache, btCollisionConfiguration* collisionConfiguration); 110 111 virtual ~btCollisionWorld(); 112 setBroadphase(btBroadphaseInterface * pairCache)113 void setBroadphase(btBroadphaseInterface* pairCache) 114 { 115 m_broadphasePairCache = pairCache; 116 } 117 getBroadphase()118 const btBroadphaseInterface* getBroadphase() const 119 { 120 return m_broadphasePairCache; 121 } 122 getBroadphase()123 btBroadphaseInterface* getBroadphase() 124 { 125 return m_broadphasePairCache; 126 } 127 getPairCache()128 btOverlappingPairCache* getPairCache() 129 { 130 return m_broadphasePairCache->getOverlappingPairCache(); 131 } 132 133 getDispatcher()134 btDispatcher* getDispatcher() 135 { 136 return m_dispatcher1; 137 } 138 getDispatcher()139 const btDispatcher* getDispatcher() const 140 { 141 return m_dispatcher1; 142 } 143 144 void updateSingleAabb(btCollisionObject* colObj); 145 146 virtual void updateAabbs(); 147 setDebugDrawer(btIDebugDraw * debugDrawer)148 virtual void setDebugDrawer(btIDebugDraw* debugDrawer) 149 { 150 m_debugDrawer = debugDrawer; 151 } 152 getDebugDrawer()153 virtual btIDebugDraw* getDebugDrawer() 154 { 155 return m_debugDrawer; 156 } 157 158 virtual void debugDrawWorld(); 159 160 virtual void debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color); 161 162 163 ///LocalShapeInfo gives extra information for complex shapes 164 ///Currently, only btTriangleMeshShape is available, so it just contains triangleIndex and subpart 165 struct LocalShapeInfo 166 { 167 int m_shapePart; 168 int m_triangleIndex; 169 170 //const btCollisionShape* m_shapeTemp; 171 //const btTransform* m_shapeLocalTransform; 172 }; 173 174 struct LocalRayResult 175 { LocalRayResultLocalRayResult176 LocalRayResult(btCollisionObject* collisionObject, 177 LocalShapeInfo* localShapeInfo, 178 const btVector3& hitNormalLocal, 179 btScalar hitFraction) 180 :m_collisionObject(collisionObject), 181 m_localShapeInfo(localShapeInfo), 182 m_hitNormalLocal(hitNormalLocal), 183 m_hitFraction(hitFraction) 184 { 185 } 186 187 btCollisionObject* m_collisionObject; 188 LocalShapeInfo* m_localShapeInfo; 189 btVector3 m_hitNormalLocal; 190 btScalar m_hitFraction; 191 192 }; 193 194 ///RayResultCallback is used to report new raycast results 195 struct RayResultCallback 196 { 197 btScalar m_closestHitFraction; 198 btCollisionObject* m_collisionObject; 199 short int m_collisionFilterGroup; 200 short int m_collisionFilterMask; 201 //@BP Mod - Custom flags, currently used to enable backface culling on tri-meshes, see btRaycastCallback 202 unsigned int m_flags; 203 ~RayResultCallbackRayResultCallback204 virtual ~RayResultCallback() 205 { 206 } hasHitRayResultCallback207 bool hasHit() const 208 { 209 return (m_collisionObject != 0); 210 } 211 RayResultCallbackRayResultCallback212 RayResultCallback() 213 :m_closestHitFraction(btScalar(1.)), 214 m_collisionObject(0), 215 m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter), 216 m_collisionFilterMask(btBroadphaseProxy::AllFilter), 217 //@BP Mod 218 m_flags(0) 219 { 220 } 221 needsCollisionRayResultCallback222 virtual bool needsCollision(btBroadphaseProxy* proxy0) const 223 { 224 bool collides = (proxy0->m_collisionFilterGroup & m_collisionFilterMask) != 0; 225 collides = collides && (m_collisionFilterGroup & proxy0->m_collisionFilterMask); 226 return collides; 227 } 228 229 230 virtual btScalar addSingleResult(LocalRayResult& rayResult,bool normalInWorldSpace) = 0; 231 }; 232 233 struct ClosestRayResultCallback : public RayResultCallback 234 { ClosestRayResultCallbackClosestRayResultCallback235 ClosestRayResultCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld) 236 :m_rayFromWorld(rayFromWorld), 237 m_rayToWorld(rayToWorld) 238 { 239 } 240 241 btVector3 m_rayFromWorld;//used to calculate hitPointWorld from hitFraction 242 btVector3 m_rayToWorld; 243 244 btVector3 m_hitNormalWorld; 245 btVector3 m_hitPointWorld; 246 addSingleResultClosestRayResultCallback247 virtual btScalar addSingleResult(LocalRayResult& rayResult,bool normalInWorldSpace) 248 { 249 //caller already does the filter on the m_closestHitFraction 250 btAssert(rayResult.m_hitFraction <= m_closestHitFraction); 251 252 m_closestHitFraction = rayResult.m_hitFraction; 253 m_collisionObject = rayResult.m_collisionObject; 254 if (normalInWorldSpace) 255 { 256 m_hitNormalWorld = rayResult.m_hitNormalLocal; 257 } else 258 { 259 ///need to transform normal into worldspace 260 m_hitNormalWorld = m_collisionObject->getWorldTransform().getBasis()*rayResult.m_hitNormalLocal; 261 } 262 m_hitPointWorld.setInterpolate3(m_rayFromWorld,m_rayToWorld,rayResult.m_hitFraction); 263 return rayResult.m_hitFraction; 264 } 265 }; 266 267 268 struct LocalConvexResult 269 { LocalConvexResultLocalConvexResult270 LocalConvexResult(btCollisionObject* hitCollisionObject, 271 LocalShapeInfo* localShapeInfo, 272 const btVector3& hitNormalLocal, 273 const btVector3& hitPointLocal, 274 btScalar hitFraction 275 ) 276 :m_hitCollisionObject(hitCollisionObject), 277 m_localShapeInfo(localShapeInfo), 278 m_hitNormalLocal(hitNormalLocal), 279 m_hitPointLocal(hitPointLocal), 280 m_hitFraction(hitFraction) 281 { 282 } 283 284 btCollisionObject* m_hitCollisionObject; 285 LocalShapeInfo* m_localShapeInfo; 286 btVector3 m_hitNormalLocal; 287 btVector3 m_hitPointLocal; 288 btScalar m_hitFraction; 289 }; 290 291 ///RayResultCallback is used to report new raycast results 292 struct ConvexResultCallback 293 { 294 btScalar m_closestHitFraction; 295 short int m_collisionFilterGroup; 296 short int m_collisionFilterMask; 297 ConvexResultCallbackConvexResultCallback298 ConvexResultCallback() 299 :m_closestHitFraction(btScalar(1.)), 300 m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter), 301 m_collisionFilterMask(btBroadphaseProxy::AllFilter) 302 { 303 } 304 ~ConvexResultCallbackConvexResultCallback305 virtual ~ConvexResultCallback() 306 { 307 } 308 hasHitConvexResultCallback309 bool hasHit() const 310 { 311 return (m_closestHitFraction < btScalar(1.)); 312 } 313 314 315 needsCollisionConvexResultCallback316 virtual bool needsCollision(btBroadphaseProxy* proxy0) const 317 { 318 bool collides = (proxy0->m_collisionFilterGroup & m_collisionFilterMask) != 0; 319 collides = collides && (m_collisionFilterGroup & proxy0->m_collisionFilterMask); 320 return collides; 321 } 322 323 virtual btScalar addSingleResult(LocalConvexResult& convexResult,bool normalInWorldSpace) = 0; 324 }; 325 326 struct ClosestConvexResultCallback : public ConvexResultCallback 327 { ClosestConvexResultCallbackClosestConvexResultCallback328 ClosestConvexResultCallback(const btVector3& convexFromWorld,const btVector3& convexToWorld) 329 :m_convexFromWorld(convexFromWorld), 330 m_convexToWorld(convexToWorld), 331 m_hitCollisionObject(0) 332 { 333 } 334 335 btVector3 m_convexFromWorld;//used to calculate hitPointWorld from hitFraction 336 btVector3 m_convexToWorld; 337 338 btVector3 m_hitNormalWorld; 339 btVector3 m_hitPointWorld; 340 btCollisionObject* m_hitCollisionObject; 341 addSingleResultClosestConvexResultCallback342 virtual btScalar addSingleResult(LocalConvexResult& convexResult,bool normalInWorldSpace) 343 { 344 //caller already does the filter on the m_closestHitFraction 345 btAssert(convexResult.m_hitFraction <= m_closestHitFraction); 346 347 m_closestHitFraction = convexResult.m_hitFraction; 348 m_hitCollisionObject = convexResult.m_hitCollisionObject; 349 if (normalInWorldSpace) 350 { 351 m_hitNormalWorld = convexResult.m_hitNormalLocal; 352 } else 353 { 354 ///need to transform normal into worldspace 355 m_hitNormalWorld = m_hitCollisionObject->getWorldTransform().getBasis()*convexResult.m_hitNormalLocal; 356 } 357 m_hitPointWorld = convexResult.m_hitPointLocal; 358 return convexResult.m_hitFraction; 359 } 360 }; 361 362 ///ContactResultCallback is used to report contact points 363 struct ContactResultCallback 364 { 365 short int m_collisionFilterGroup; 366 short int m_collisionFilterMask; 367 ContactResultCallbackContactResultCallback368 ContactResultCallback() 369 :m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter), 370 m_collisionFilterMask(btBroadphaseProxy::AllFilter) 371 { 372 } 373 ~ContactResultCallbackContactResultCallback374 virtual ~ContactResultCallback() 375 { 376 } 377 needsCollisionContactResultCallback378 virtual bool needsCollision(btBroadphaseProxy* proxy0) const 379 { 380 bool collides = (proxy0->m_collisionFilterGroup & m_collisionFilterMask) != 0; 381 collides = collides && (m_collisionFilterGroup & proxy0->m_collisionFilterMask); 382 return collides; 383 } 384 385 virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1) = 0; 386 }; 387 388 389 getNumCollisionObjects()390 int getNumCollisionObjects() const 391 { 392 return int(m_collisionObjects.size()); 393 } 394 395 /// rayTest performs a raycast on all objects in the btCollisionWorld, and calls the resultCallback 396 /// This allows for several queries: first hit, all hits, any hit, dependent on the value returned by the callback. 397 virtual void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const; 398 399 /// convexTest performs a swept convex cast on all objects in the btCollisionWorld, and calls the resultCallback 400 /// This allows for several queries: first hit, all hits, any hit, dependent on the value return by the callback. 401 void convexSweepTest (const btConvexShape* castShape, const btTransform& from, const btTransform& to, ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration = btScalar(0.)) const; 402 403 ///contactTest performs a discrete collision test between colObj against all objects in the btCollisionWorld, and calls the resultCallback. 404 ///it reports one or more contact points for every overlapping object (including the one with deepest penetration) 405 void contactTest(btCollisionObject* colObj, ContactResultCallback& resultCallback); 406 407 ///contactTest performs a discrete collision test between two collision objects and calls the resultCallback if overlap if detected. 408 ///it reports one or more contact points (including the one with deepest penetration) 409 void contactPairTest(btCollisionObject* colObjA, btCollisionObject* colObjB, ContactResultCallback& resultCallback); 410 411 412 /// rayTestSingle performs a raycast call and calls the resultCallback. It is used internally by rayTest. 413 /// In a future implementation, we consider moving the ray test as a virtual method in btCollisionShape. 414 /// This allows more customization. 415 static void rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans, 416 btCollisionObject* collisionObject, 417 const btCollisionShape* collisionShape, 418 const btTransform& colObjWorldTransform, 419 RayResultCallback& resultCallback); 420 421 /// objectQuerySingle performs a collision detection query and calls the resultCallback. It is used internally by rayTest. 422 static void objectQuerySingle(const btConvexShape* castShape, const btTransform& rayFromTrans,const btTransform& rayToTrans, 423 btCollisionObject* collisionObject, 424 const btCollisionShape* collisionShape, 425 const btTransform& colObjWorldTransform, 426 ConvexResultCallback& resultCallback, btScalar allowedPenetration); 427 428 virtual void addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup=btBroadphaseProxy::DefaultFilter,short int collisionFilterMask=btBroadphaseProxy::AllFilter); 429 getCollisionObjectArray()430 btCollisionObjectArray& getCollisionObjectArray() 431 { 432 return m_collisionObjects; 433 } 434 getCollisionObjectArray()435 const btCollisionObjectArray& getCollisionObjectArray() const 436 { 437 return m_collisionObjects; 438 } 439 440 441 virtual void removeCollisionObject(btCollisionObject* collisionObject); 442 443 virtual void performDiscreteCollisionDetection(); 444 getDispatchInfo()445 btDispatcherInfo& getDispatchInfo() 446 { 447 return m_dispatchInfo; 448 } 449 getDispatchInfo()450 const btDispatcherInfo& getDispatchInfo() const 451 { 452 return m_dispatchInfo; 453 } 454 getForceUpdateAllAabbs()455 bool getForceUpdateAllAabbs() const 456 { 457 return m_forceUpdateAllAabbs; 458 } setForceUpdateAllAabbs(bool forceUpdateAllAabbs)459 void setForceUpdateAllAabbs( bool forceUpdateAllAabbs) 460 { 461 m_forceUpdateAllAabbs = forceUpdateAllAabbs; 462 } 463 464 ///Preliminary serialization test for Bullet 2.76. Loading those files requires a separate parser (Bullet/Demos/SerializeDemo) 465 virtual void serialize(btSerializer* serializer); 466 467 }; 468 469 470 #endif //COLLISION_WORLD_H 471