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