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