Home | History | Annotate | Download | only in CollisionDispatch
      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