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