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