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 #include "chrono/core/ChTimer.h" // ***CHRONO*** 85 #include "chrono/utils/ChProfiler.h" // ***CHRONO*** 86 87 ///CollisionWorld is interface and container for the collision detection 88 class btCollisionWorld 89 { 90 protected: 91 btAlignedObjectArray<btCollisionObject*> m_collisionObjects; 92 93 btDispatcher* m_dispatcher1; 94 95 btDispatcherInfo m_dispatchInfo; 96 97 btBroadphaseInterface* m_broadphasePairCache; 98 99 btIDebugDraw* m_debugDrawer; 100 101 ///m_forceUpdateAllAabbs can be set to false as an optimization to only update active object AABBs 102 ///it is true by default, because it is error-prone (setting the position of static objects wouldn't update their AABB) 103 bool m_forceUpdateAllAabbs; 104 105 void serializeCollisionObjects(btSerializer* serializer); 106 107 void serializeContactManifolds(btSerializer* serializer); 108 109 public: 110 //this constructor doesn't own the dispatcher and paircache/broadphase 111 btCollisionWorld(btDispatcher* dispatcher, btBroadphaseInterface* broadphasePairCache, btCollisionConfiguration* collisionConfiguration); 112 113 virtual ~btCollisionWorld(); 114 setBroadphase(btBroadphaseInterface * pairCache)115 void setBroadphase(btBroadphaseInterface* pairCache) 116 { 117 m_broadphasePairCache = pairCache; 118 } 119 getBroadphase()120 const btBroadphaseInterface* getBroadphase() const 121 { 122 return m_broadphasePairCache; 123 } 124 getBroadphase()125 btBroadphaseInterface* getBroadphase() 126 { 127 return m_broadphasePairCache; 128 } 129 getPairCache()130 btOverlappingPairCache* getPairCache() 131 { 132 return m_broadphasePairCache->getOverlappingPairCache(); 133 } 134 getDispatcher()135 btDispatcher* getDispatcher() 136 { 137 return m_dispatcher1; 138 } 139 getDispatcher()140 const btDispatcher* getDispatcher() const 141 { 142 return m_dispatcher1; 143 } 144 145 void updateSingleAabb(btCollisionObject* colObj); 146 147 virtual void updateAabbs(); 148 149 ///the computeOverlappingPairs is usually already called by performDiscreteCollisionDetection (or stepSimulation) 150 ///it can be useful to use if you perform ray tests without collision detection/simulation 151 virtual void computeOverlappingPairs(); 152 setDebugDrawer(btIDebugDraw * debugDrawer)153 virtual void setDebugDrawer(btIDebugDraw* debugDrawer) 154 { 155 m_debugDrawer = debugDrawer; 156 } 157 getDebugDrawer()158 virtual btIDebugDraw* getDebugDrawer() 159 { 160 return m_debugDrawer; 161 } 162 163 virtual void debugDrawWorld(); 164 165 virtual void debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color); 166 167 ///LocalShapeInfo gives extra information for complex shapes 168 ///Currently, only btTriangleMeshShape is available, so it just contains triangleIndex and subpart 169 struct LocalShapeInfo 170 { 171 int m_shapePart; 172 int m_triangleIndex; 173 174 //const btCollisionShape* m_shapeTemp; 175 //const btTransform* m_shapeLocalTransform; 176 }; 177 178 struct LocalRayResult 179 { LocalRayResultLocalRayResult180 LocalRayResult(const btCollisionObject* collisionObject, 181 LocalShapeInfo* localShapeInfo, 182 const btVector3& hitNormalLocal, 183 btScalar hitFraction) 184 : m_collisionObject(collisionObject), 185 m_localShapeInfo(localShapeInfo), 186 m_hitNormalLocal(hitNormalLocal), 187 m_hitFraction(hitFraction) 188 { 189 } 190 191 const btCollisionObject* m_collisionObject; 192 LocalShapeInfo* m_localShapeInfo; 193 btVector3 m_hitNormalLocal; 194 btScalar m_hitFraction; 195 }; 196 197 ///RayResultCallback is used to report new raycast results 198 struct RayResultCallback 199 { 200 btScalar m_closestHitFraction; 201 const btCollisionObject* m_collisionObject; 202 int m_collisionFilterGroup; 203 int m_collisionFilterMask; 204 //@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. 205 unsigned int m_flags; 206 ~RayResultCallbackRayResultCallback207 virtual ~RayResultCallback() 208 { 209 } hasHitRayResultCallback210 bool hasHit() const 211 { 212 return (m_collisionObject != 0); 213 } 214 RayResultCallbackRayResultCallback215 RayResultCallback() 216 : m_closestHitFraction(btScalar(1.)), 217 m_collisionObject(0), 218 m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter), 219 m_collisionFilterMask(btBroadphaseProxy::AllFilter), 220 //@BP Mod 221 m_flags(0) 222 { 223 } 224 needsCollisionRayResultCallback225 virtual bool needsCollision(btBroadphaseProxy* proxy0) const 226 { 227 bool collides = (proxy0->m_collisionFilterGroup & m_collisionFilterMask) != 0; 228 collides = collides && (m_collisionFilterGroup & proxy0->m_collisionFilterMask); 229 return collides; 230 } 231 232 virtual btScalar addSingleResult(LocalRayResult& rayResult, bool normalInWorldSpace) = 0; 233 }; 234 235 struct ClosestRayResultCallback : public RayResultCallback 236 { ClosestRayResultCallbackClosestRayResultCallback237 ClosestRayResultCallback(const btVector3& rayFromWorld, const btVector3& rayToWorld) 238 : m_rayFromWorld(rayFromWorld), 239 m_rayToWorld(rayToWorld) 240 { 241 } 242 243 btVector3 m_rayFromWorld; //used to calculate hitPointWorld from hitFraction 244 btVector3 m_rayToWorld; 245 246 btVector3 m_hitNormalWorld; 247 btVector3 m_hitPointWorld; 248 addSingleResultClosestRayResultCallback249 virtual btScalar addSingleResult(LocalRayResult& rayResult, bool normalInWorldSpace) 250 { 251 //caller already does the filter on the m_closestHitFraction 252 btAssert(rayResult.m_hitFraction <= m_closestHitFraction); 253 254 m_closestHitFraction = rayResult.m_hitFraction; 255 m_collisionObject = rayResult.m_collisionObject; 256 if (normalInWorldSpace) 257 { 258 m_hitNormalWorld = rayResult.m_hitNormalLocal; 259 } 260 else 261 { 262 ///need to transform normal into worldspace 263 m_hitNormalWorld = m_collisionObject->getWorldTransform().getBasis() * rayResult.m_hitNormalLocal; 264 } 265 m_hitPointWorld.setInterpolate3(m_rayFromWorld, m_rayToWorld, rayResult.m_hitFraction); 266 return rayResult.m_hitFraction; 267 } 268 }; 269 270 struct AllHitsRayResultCallback : public RayResultCallback 271 { AllHitsRayResultCallbackAllHitsRayResultCallback272 AllHitsRayResultCallback(const btVector3& rayFromWorld, const btVector3& rayToWorld) 273 : m_rayFromWorld(rayFromWorld), 274 m_rayToWorld(rayToWorld) 275 { 276 } 277 278 btAlignedObjectArray<const btCollisionObject*> m_collisionObjects; 279 280 btVector3 m_rayFromWorld; //used to calculate hitPointWorld from hitFraction 281 btVector3 m_rayToWorld; 282 283 btAlignedObjectArray<btVector3> m_hitNormalWorld; 284 btAlignedObjectArray<btVector3> m_hitPointWorld; 285 btAlignedObjectArray<btScalar> m_hitFractions; 286 addSingleResultAllHitsRayResultCallback287 virtual btScalar addSingleResult(LocalRayResult& rayResult, bool normalInWorldSpace) 288 { 289 m_collisionObject = rayResult.m_collisionObject; 290 m_collisionObjects.push_back(rayResult.m_collisionObject); 291 btVector3 hitNormalWorld; 292 if (normalInWorldSpace) 293 { 294 hitNormalWorld = rayResult.m_hitNormalLocal; 295 } 296 else 297 { 298 ///need to transform normal into worldspace 299 hitNormalWorld = m_collisionObject->getWorldTransform().getBasis() * rayResult.m_hitNormalLocal; 300 } 301 m_hitNormalWorld.push_back(hitNormalWorld); 302 btVector3 hitPointWorld; 303 hitPointWorld.setInterpolate3(m_rayFromWorld, m_rayToWorld, rayResult.m_hitFraction); 304 m_hitPointWorld.push_back(hitPointWorld); 305 m_hitFractions.push_back(rayResult.m_hitFraction); 306 return m_closestHitFraction; 307 } 308 }; 309 310 struct LocalConvexResult 311 { LocalConvexResultLocalConvexResult312 LocalConvexResult(const btCollisionObject* hitCollisionObject, 313 LocalShapeInfo* localShapeInfo, 314 const btVector3& hitNormalLocal, 315 const btVector3& hitPointLocal, 316 btScalar hitFraction) 317 : m_hitCollisionObject(hitCollisionObject), 318 m_localShapeInfo(localShapeInfo), 319 m_hitNormalLocal(hitNormalLocal), 320 m_hitPointLocal(hitPointLocal), 321 m_hitFraction(hitFraction) 322 { 323 } 324 325 const btCollisionObject* m_hitCollisionObject; 326 LocalShapeInfo* m_localShapeInfo; 327 btVector3 m_hitNormalLocal; 328 btVector3 m_hitPointLocal; 329 btScalar m_hitFraction; 330 }; 331 332 ///RayResultCallback is used to report new raycast results 333 struct ConvexResultCallback 334 { 335 btScalar m_closestHitFraction; 336 int m_collisionFilterGroup; 337 int m_collisionFilterMask; 338 ConvexResultCallbackConvexResultCallback339 ConvexResultCallback() 340 : m_closestHitFraction(btScalar(1.)), 341 m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter), 342 m_collisionFilterMask(btBroadphaseProxy::AllFilter) 343 { 344 } 345 ~ConvexResultCallbackConvexResultCallback346 virtual ~ConvexResultCallback() 347 { 348 } 349 hasHitConvexResultCallback350 bool hasHit() const 351 { 352 return (m_closestHitFraction < btScalar(1.)); 353 } 354 needsCollisionConvexResultCallback355 virtual bool needsCollision(btBroadphaseProxy* proxy0) const 356 { 357 bool collides = (proxy0->m_collisionFilterGroup & m_collisionFilterMask) != 0; 358 collides = collides && (m_collisionFilterGroup & proxy0->m_collisionFilterMask); 359 return collides; 360 } 361 362 virtual btScalar addSingleResult(LocalConvexResult& convexResult, bool normalInWorldSpace) = 0; 363 }; 364 365 struct ClosestConvexResultCallback : public ConvexResultCallback 366 { ClosestConvexResultCallbackClosestConvexResultCallback367 ClosestConvexResultCallback(const btVector3& convexFromWorld, const btVector3& convexToWorld) 368 : m_convexFromWorld(convexFromWorld), 369 m_convexToWorld(convexToWorld), 370 m_hitCollisionObject(0) 371 { 372 } 373 374 btVector3 m_convexFromWorld; //used to calculate hitPointWorld from hitFraction 375 btVector3 m_convexToWorld; 376 377 btVector3 m_hitNormalWorld; 378 btVector3 m_hitPointWorld; 379 const btCollisionObject* m_hitCollisionObject; 380 addSingleResultClosestConvexResultCallback381 virtual btScalar addSingleResult(LocalConvexResult& convexResult, bool normalInWorldSpace) 382 { 383 //caller already does the filter on the m_closestHitFraction 384 btAssert(convexResult.m_hitFraction <= m_closestHitFraction); 385 386 m_closestHitFraction = convexResult.m_hitFraction; 387 m_hitCollisionObject = convexResult.m_hitCollisionObject; 388 if (normalInWorldSpace) 389 { 390 m_hitNormalWorld = convexResult.m_hitNormalLocal; 391 } 392 else 393 { 394 ///need to transform normal into worldspace 395 m_hitNormalWorld = m_hitCollisionObject->getWorldTransform().getBasis() * convexResult.m_hitNormalLocal; 396 } 397 m_hitPointWorld = convexResult.m_hitPointLocal; 398 return convexResult.m_hitFraction; 399 } 400 }; 401 402 ///ContactResultCallback is used to report contact points 403 struct ContactResultCallback 404 { 405 int m_collisionFilterGroup; 406 int m_collisionFilterMask; 407 btScalar m_closestDistanceThreshold; 408 ContactResultCallbackContactResultCallback409 ContactResultCallback() 410 : m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter), 411 m_collisionFilterMask(btBroadphaseProxy::AllFilter), 412 m_closestDistanceThreshold(0) 413 { 414 } 415 ~ContactResultCallbackContactResultCallback416 virtual ~ContactResultCallback() 417 { 418 } 419 needsCollisionContactResultCallback420 virtual bool needsCollision(btBroadphaseProxy* proxy0) const 421 { 422 bool collides = (proxy0->m_collisionFilterGroup & m_collisionFilterMask) != 0; 423 collides = collides && (m_collisionFilterGroup & proxy0->m_collisionFilterMask); 424 return collides; 425 } 426 427 virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper* colObj1Wrap, int partId1, int index1) = 0; 428 }; 429 getNumCollisionObjects()430 int getNumCollisionObjects() const 431 { 432 return int(m_collisionObjects.size()); 433 } 434 435 /// rayTest performs a raycast on all objects in the btCollisionWorld, and calls the resultCallback 436 /// This allows for several queries: first hit, all hits, any hit, dependent on the value returned by the callback. 437 virtual void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const; 438 439 /// convexTest performs a swept convex cast on all objects in the btCollisionWorld, and calls the resultCallback 440 /// This allows for several queries: first hit, all hits, any hit, dependent on the value return by the callback. 441 void convexSweepTest(const btConvexShape* castShape, const btTransform& from, const btTransform& to, ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration = btScalar(0.)) const; 442 443 ///contactTest performs a discrete collision test between colObj against all objects in the btCollisionWorld, and calls the resultCallback. 444 ///it reports one or more contact points for every overlapping object (including the one with deepest penetration) 445 void contactTest(btCollisionObject* colObj, ContactResultCallback& resultCallback); 446 447 ///contactTest performs a discrete collision test between two collision objects and calls the resultCallback if overlap if detected. 448 ///it reports one or more contact points (including the one with deepest penetration) 449 void contactPairTest(btCollisionObject* colObjA, btCollisionObject* colObjB, ContactResultCallback& resultCallback); 450 451 /// rayTestSingle performs a raycast call and calls the resultCallback. It is used internally by rayTest. 452 /// In a future implementation, we consider moving the ray test as a virtual method in btCollisionShape. 453 /// This allows more customization. 454 static void rayTestSingle(const btTransform& rayFromTrans, const btTransform& rayToTrans, 455 btCollisionObject* collisionObject, 456 const btCollisionShape* collisionShape, 457 const btTransform& colObjWorldTransform, 458 RayResultCallback& resultCallback); 459 460 static void rayTestSingleInternal(const btTransform& rayFromTrans, const btTransform& rayToTrans, 461 const btCollisionObjectWrapper* collisionObjectWrap, 462 RayResultCallback& resultCallback); 463 464 /// objectQuerySingle performs a collision detection query and calls the resultCallback. It is used internally by rayTest. 465 static void objectQuerySingle(const btConvexShape* castShape, const btTransform& rayFromTrans, const btTransform& rayToTrans, 466 btCollisionObject* collisionObject, 467 const btCollisionShape* collisionShape, 468 const btTransform& colObjWorldTransform, 469 ConvexResultCallback& resultCallback, btScalar allowedPenetration); 470 471 static void objectQuerySingleInternal(const btConvexShape* castShape, const btTransform& convexFromTrans, const btTransform& convexToTrans, 472 const btCollisionObjectWrapper* colObjWrap, 473 ConvexResultCallback& resultCallback, btScalar allowedPenetration); 474 475 virtual void addCollisionObject(btCollisionObject* collisionObject, int collisionFilterGroup = btBroadphaseProxy::DefaultFilter, int collisionFilterMask = btBroadphaseProxy::AllFilter); 476 477 virtual void refreshBroadphaseProxy(btCollisionObject* collisionObject); 478 getCollisionObjectArray()479 btCollisionObjectArray& getCollisionObjectArray() 480 { 481 return m_collisionObjects; 482 } 483 getCollisionObjectArray()484 const btCollisionObjectArray& getCollisionObjectArray() const 485 { 486 return m_collisionObjects; 487 } 488 489 virtual void removeCollisionObject(btCollisionObject* collisionObject); 490 491 virtual void performDiscreteCollisionDetection(); 492 getDispatchInfo()493 btDispatcherInfo& getDispatchInfo() 494 { 495 return m_dispatchInfo; 496 } 497 getDispatchInfo()498 const btDispatcherInfo& getDispatchInfo() const 499 { 500 return m_dispatchInfo; 501 } 502 getForceUpdateAllAabbs()503 bool getForceUpdateAllAabbs() const 504 { 505 return m_forceUpdateAllAabbs; 506 } setForceUpdateAllAabbs(bool forceUpdateAllAabbs)507 void setForceUpdateAllAabbs(bool forceUpdateAllAabbs) 508 { 509 m_forceUpdateAllAabbs = forceUpdateAllAabbs; 510 } 511 512 ///Preliminary serialization test for Bullet 2.76. Loading those files requires a separate parser (Bullet/Demos/SerializeDemo) 513 virtual void serialize(btSerializer* serializer); 514 515 // ***CHRONO*** 516 chrono::ChTimer<double> timer_collision_broad; 517 chrono::ChTimer<double> timer_collision_narrow; 518 }; 519 520 #endif //BT_COLLISION_WORLD_H 521