• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
setBroadphase(btBroadphaseInterface * pairCache)117 	void	setBroadphase(btBroadphaseInterface*	pairCache)
118 	{
119 		m_broadphasePairCache = pairCache;
120 	}
121 
getBroadphase()122 	const btBroadphaseInterface*	getBroadphase() const
123 	{
124 		return m_broadphasePairCache;
125 	}
126 
getBroadphase()127 	btBroadphaseInterface*	getBroadphase()
128 	{
129 		return m_broadphasePairCache;
130 	}
131 
getPairCache()132 	btOverlappingPairCache*	getPairCache()
133 	{
134 		return m_broadphasePairCache->getOverlappingPairCache();
135 	}
136 
137 
getDispatcher()138 	btDispatcher*	getDispatcher()
139 	{
140 		return m_dispatcher1;
141 	}
142 
getDispatcher()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 
setDebugDrawer(btIDebugDraw * debugDrawer)157 	virtual void	setDebugDrawer(btIDebugDraw*	debugDrawer)
158 	{
159 			m_debugDrawer = debugDrawer;
160 	}
161 
getDebugDrawer()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 	{
LocalRayResultLocalRayResult185 		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 
~RayResultCallbackRayResultCallback213 		virtual ~RayResultCallback()
214 		{
215 		}
hasHitRayResultCallback216 		bool	hasHit() const
217 		{
218 			return (m_collisionObject != 0);
219 		}
220 
RayResultCallbackRayResultCallback221 		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 
needsCollisionRayResultCallback231 		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 	{
ClosestRayResultCallbackClosestRayResultCallback244 		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 
addSingleResultClosestRayResultCallback256 		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 	{
AllHitsRayResultCallbackAllHitsRayResultCallback278 		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 
addSingleResultAllHitsRayResultCallback293 		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 	{
LocalConvexResultLocalConvexResult318 		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 
ConvexResultCallbackConvexResultCallback346 		ConvexResultCallback()
347 			:m_closestHitFraction(btScalar(1.)),
348 			m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter),
349 			m_collisionFilterMask(btBroadphaseProxy::AllFilter)
350 		{
351 		}
352 
~ConvexResultCallbackConvexResultCallback353 		virtual ~ConvexResultCallback()
354 		{
355 		}
356 
hasHitConvexResultCallback357 		bool	hasHit() const
358 		{
359 			return (m_closestHitFraction < btScalar(1.));
360 		}
361 
362 
363 
needsCollisionConvexResultCallback364 		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 	{
ClosestConvexResultCallbackClosestConvexResultCallback376 		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 
addSingleResultClosestConvexResultCallback390 		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 
ContactResultCallbackContactResultCallback416 		ContactResultCallback()
417 			:m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter),
418 			m_collisionFilterMask(btBroadphaseProxy::AllFilter)
419 		{
420 		}
421 
~ContactResultCallbackContactResultCallback422 		virtual ~ContactResultCallback()
423 		{
424 		}
425 
needsCollisionContactResultCallback426 		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 
getNumCollisionObjects()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 
getCollisionObjectArray()486 	btCollisionObjectArray& getCollisionObjectArray()
487 	{
488 		return m_collisionObjects;
489 	}
490 
getCollisionObjectArray()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 
getDispatchInfo()501 	btDispatcherInfo& getDispatchInfo()
502 	{
503 		return m_dispatchInfo;
504 	}
505 
getDispatchInfo()506 	const btDispatcherInfo& getDispatchInfo() const
507 	{
508 		return m_dispatchInfo;
509 	}
510 
getForceUpdateAllAabbs()511 	bool	getForceUpdateAllAabbs() const
512 	{
513 		return m_forceUpdateAllAabbs;
514 	}
setForceUpdateAllAabbs(bool forceUpdateAllAabbs)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