0a92d2d6e158d2bcba926ec734553fb37923e44c
[blender.git] / extern / bullet2 / src / BulletCollision / CollisionDispatch / btCollisionWorld.h
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2006 Erwin Coumans  http://bulletphysics.com/Bullet/
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 Collision Detection & Physics SDK
22  *
23  * 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 ).
24  *
25  * The main documentation is Bullet_User_Manual.pdf, included in the source code distribution.
26  * There is the Physics Forum for feedback and general Collision Detection and Physics discussions.
27  * Please visit http://www.bulletphysics.com
28  *
29  * @section install_sec Installation
30  *
31  * @subsection step1 Step 1: Download
32  * You can download the Bullet Physics Library from the Google Code repository: http://code.google.com/p/bullet/downloads/list
33  *
34  * @subsection step2 Step 2: Building
35  * Bullet main build system for all platforms is cmake, you can download http://www.cmake.org
36  * cmake can autogenerate projectfiles for Microsoft Visual Studio, Apple Xcode, KDevelop and Unix Makefiles.
37  * The easiest is to run the CMake cmake-gui graphical user interface and choose the options and generate projectfiles.
38  * You can also use cmake in the command-line. Here are some examples for various platforms:
39  * cmake . -G "Visual Studio 9 2008"
40  * cmake . -G Xcode
41  * cmake . -G "Unix Makefiles"
42  * Although cmake is recommended, you can also use autotools for UNIX: ./autogen.sh ./configure to create a Makefile and then run make.
43  * 
44  * @subsection step3 Step 3: Testing demos
45  * Try to run and experiment with BasicDemo executable as a starting point.
46  * 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.
47  * The Dependencies can be seen in this documentation under Directories
48  * 
49  * @subsection step4 Step 4: Integrating in your application, full Rigid Body and Soft Body simulation
50  * Check out BasicDemo how to create a btDynamicsWorld, btRigidBody and btCollisionShape, Stepping the simulation and synchronizing your graphics object transform.
51  * Check out SoftDemo how to use soft body dynamics, using btSoftRigidDynamicsWorld.
52  * @subsection step5 Step 5 : Integrate the Collision Detection Library (without Dynamics and other Extras)
53  * Bullet Collision Detection can also be used without the Dynamics/Extras.
54  * Check out btCollisionWorld and btCollisionObject, and the CollisionInterfaceDemo.
55  * @subsection step6 Step 6 : Use Snippets like the GJK Closest Point calculation.
56  * Bullet has been designed in a modular way keeping dependencies to a minimum. The ConvexHullDistance demo demonstrates direct use of btGjkPairDetector.
57  *
58  * @section copyright Copyright
59  * For up-to-data information and copyright and contributors list check out the Bullet_User_Manual.pdf
60  * 
61  */
62  
63  
64
65 #ifndef BT_COLLISION_WORLD_H
66 #define BT_COLLISION_WORLD_H
67
68 class btStackAlloc;
69 class btCollisionShape;
70 class btConvexShape;
71 class btBroadphaseInterface;
72 class btSerializer;
73
74 #include "LinearMath/btVector3.h"
75 #include "LinearMath/btTransform.h"
76 #include "btCollisionObject.h"
77 #include "btCollisionDispatcher.h"
78 #include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
79 #include "LinearMath/btAlignedObjectArray.h"
80
81 ///CollisionWorld is interface and container for the collision detection
82 class btCollisionWorld
83 {
84
85         
86 protected:
87
88         btAlignedObjectArray<btCollisionObject*>        m_collisionObjects;
89         
90         btDispatcher*   m_dispatcher1;
91
92         btDispatcherInfo        m_dispatchInfo;
93
94         btStackAlloc*   m_stackAlloc;
95
96         btBroadphaseInterface*  m_broadphasePairCache;
97
98         btIDebugDraw*   m_debugDrawer;
99
100         ///m_forceUpdateAllAabbs can be set to false as an optimization to only update active object AABBs
101         ///it is true by default, because it is error-prone (setting the position of static objects wouldn't update their AABB)
102         bool m_forceUpdateAllAabbs;
103
104         void    serializeCollisionObjects(btSerializer* serializer);
105
106 public:
107
108         //this constructor doesn't own the dispatcher and paircache/broadphase
109         btCollisionWorld(btDispatcher* dispatcher,btBroadphaseInterface* broadphasePairCache, btCollisionConfiguration* collisionConfiguration);
110
111         virtual ~btCollisionWorld();
112
113         void    setBroadphase(btBroadphaseInterface*    pairCache)
114         {
115                 m_broadphasePairCache = pairCache;
116         }
117
118         const btBroadphaseInterface*    getBroadphase() const
119         {
120                 return m_broadphasePairCache;
121         }
122
123         btBroadphaseInterface*  getBroadphase()
124         {
125                 return m_broadphasePairCache;
126         }
127
128         btOverlappingPairCache* getPairCache()
129         {
130                 return m_broadphasePairCache->getOverlappingPairCache();
131         }
132
133
134         btDispatcher*   getDispatcher()
135         {
136                 return m_dispatcher1;
137         }
138
139         const btDispatcher*     getDispatcher() const
140         {
141                 return m_dispatcher1;
142         }
143
144         void    updateSingleAabb(btCollisionObject* colObj);
145
146         virtual void    updateAabbs();
147         
148         virtual void    setDebugDrawer(btIDebugDraw*    debugDrawer)
149         {
150                         m_debugDrawer = debugDrawer;
151         }
152
153         virtual btIDebugDraw*   getDebugDrawer()
154         {
155                 return m_debugDrawer;
156         }
157
158         virtual void    debugDrawWorld();
159
160         virtual void debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color);
161
162
163         ///LocalShapeInfo gives extra information for complex shapes
164         ///Currently, only btTriangleMeshShape is available, so it just contains triangleIndex and subpart
165         struct  LocalShapeInfo
166         {
167                 int     m_shapePart;
168                 int     m_triangleIndex;
169                 
170                 //const btCollisionShape*       m_shapeTemp;
171                 //const btTransform*    m_shapeLocalTransform;
172         };
173
174         struct  LocalRayResult
175         {
176                 LocalRayResult(btCollisionObject*       collisionObject, 
177                         LocalShapeInfo* localShapeInfo,
178                         const btVector3&                hitNormalLocal,
179                         btScalar hitFraction)
180                 :m_collisionObject(collisionObject),
181                 m_localShapeInfo(localShapeInfo),
182                 m_hitNormalLocal(hitNormalLocal),
183                 m_hitFraction(hitFraction)
184                 {
185                 }
186
187                 btCollisionObject*              m_collisionObject;
188                 LocalShapeInfo*                 m_localShapeInfo;
189                 btVector3                               m_hitNormalLocal;
190                 btScalar                                m_hitFraction;
191
192         };
193
194         ///RayResultCallback is used to report new raycast results
195         struct  RayResultCallback
196         {
197                 btScalar        m_closestHitFraction;
198                 btCollisionObject*              m_collisionObject;
199                 short int       m_collisionFilterGroup;
200                 short int       m_collisionFilterMask;
201       //@BP Mod - Custom flags, currently used to enable backface culling on tri-meshes, see btRaycastCallback
202       unsigned int m_flags;
203
204                 virtual ~RayResultCallback()
205                 {
206                 }
207                 bool    hasHit() const
208                 {
209                         return (m_collisionObject != 0);
210                 }
211
212                 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
222                 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
230                 virtual btScalar        addSingleResult(LocalRayResult& rayResult,bool normalInWorldSpace) = 0;
231         };
232
233         struct  ClosestRayResultCallback : public RayResultCallback
234         {
235                 ClosestRayResultCallback(const btVector3&       rayFromWorld,const btVector3&   rayToWorld)
236                 :m_rayFromWorld(rayFromWorld),
237                 m_rayToWorld(rayToWorld)
238                 {
239                 }
240
241                 btVector3       m_rayFromWorld;//used to calculate hitPointWorld from hitFraction
242                 btVector3       m_rayToWorld;
243
244                 btVector3       m_hitNormalWorld;
245                 btVector3       m_hitPointWorld;
246                         
247                 virtual btScalar        addSingleResult(LocalRayResult& rayResult,bool normalInWorldSpace)
248                 {
249                         //caller already does the filter on the m_closestHitFraction
250                         btAssert(rayResult.m_hitFraction <= m_closestHitFraction);
251                         
252                         m_closestHitFraction = rayResult.m_hitFraction;
253                         m_collisionObject = rayResult.m_collisionObject;
254                         if (normalInWorldSpace)
255                         {
256                                 m_hitNormalWorld = rayResult.m_hitNormalLocal;
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         {
269                 AllHitsRayResultCallback(const btVector3&       rayFromWorld,const btVector3&   rayToWorld)
270                 :m_rayFromWorld(rayFromWorld),
271                 m_rayToWorld(rayToWorld)
272                 {
273                 }
274
275                 btAlignedObjectArray<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                         
284                 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                         } else
293                         {
294                                 ///need to transform normal into worldspace
295                                 hitNormalWorld = m_collisionObject->getWorldTransform().getBasis()*rayResult.m_hitNormalLocal;
296                         }
297                         m_hitNormalWorld.push_back(hitNormalWorld);
298                         btVector3 hitPointWorld;
299                         hitPointWorld.setInterpolate3(m_rayFromWorld,m_rayToWorld,rayResult.m_hitFraction);
300                         m_hitPointWorld.push_back(hitPointWorld);
301                         m_hitFractions.push_back(rayResult.m_hitFraction);
302                         return m_closestHitFraction;
303                 }
304         };
305
306
307         struct LocalConvexResult
308         {
309                 LocalConvexResult(btCollisionObject*    hitCollisionObject, 
310                         LocalShapeInfo* localShapeInfo,
311                         const btVector3&                hitNormalLocal,
312                         const btVector3&                hitPointLocal,
313                         btScalar hitFraction
314                         )
315                 :m_hitCollisionObject(hitCollisionObject),
316                 m_localShapeInfo(localShapeInfo),
317                 m_hitNormalLocal(hitNormalLocal),
318                 m_hitPointLocal(hitPointLocal),
319                 m_hitFraction(hitFraction)
320                 {
321                 }
322
323                 btCollisionObject*              m_hitCollisionObject;
324                 LocalShapeInfo*                 m_localShapeInfo;
325                 btVector3                               m_hitNormalLocal;
326                 btVector3                               m_hitPointLocal;
327                 btScalar                                m_hitFraction;
328         };
329
330         ///RayResultCallback is used to report new raycast results
331         struct  ConvexResultCallback
332         {
333                 btScalar        m_closestHitFraction;
334                 short int       m_collisionFilterGroup;
335                 short int       m_collisionFilterMask;
336                 
337                 ConvexResultCallback()
338                         :m_closestHitFraction(btScalar(1.)),
339                         m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter),
340                         m_collisionFilterMask(btBroadphaseProxy::AllFilter)
341                 {
342                 }
343
344                 virtual ~ConvexResultCallback()
345                 {
346                 }
347                 
348                 bool    hasHit() const
349                 {
350                         return (m_closestHitFraction < btScalar(1.));
351                 }
352
353                 
354
355                 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         {
367                 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                 btCollisionObject*      m_hitCollisionObject;
380                 
381                 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                         } else
392                         {
393                                 ///need to transform normal into worldspace
394                                 m_hitNormalWorld = m_hitCollisionObject->getWorldTransform().getBasis()*convexResult.m_hitNormalLocal;
395                         }
396                         m_hitPointWorld = convexResult.m_hitPointLocal;
397                         return convexResult.m_hitFraction;
398                 }
399         };
400
401         ///ContactResultCallback is used to report contact points
402         struct  ContactResultCallback
403         {
404                 short int       m_collisionFilterGroup;
405                 short int       m_collisionFilterMask;
406                 
407                 ContactResultCallback()
408                         :m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter),
409                         m_collisionFilterMask(btBroadphaseProxy::AllFilter)
410                 {
411                 }
412
413                 virtual ~ContactResultCallback()
414                 {
415                 }
416                 
417                 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 btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1) = 0;
425         };
426
427
428
429         int     getNumCollisionObjects() const
430         {
431                 return int(m_collisionObjects.size());
432         }
433
434         /// rayTest performs a raycast on all objects in the btCollisionWorld, and calls the resultCallback
435         /// This allows for several queries: first hit, all hits, any hit, dependent on the value returned by the callback.
436         virtual void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const; 
437
438         /// convexTest performs a swept convex cast on all objects in the btCollisionWorld, and calls the resultCallback
439         /// This allows for several queries: first hit, all hits, any hit, dependent on the value return by the callback.
440         void    convexSweepTest (const btConvexShape* castShape, const btTransform& from, const btTransform& to, ConvexResultCallback& resultCallback,  btScalar allowedCcdPenetration = btScalar(0.)) const;
441
442         ///contactTest performs a discrete collision test between colObj against all objects in the btCollisionWorld, and calls the resultCallback.
443         ///it reports one or more contact points for every overlapping object (including the one with deepest penetration)
444         void    contactTest(btCollisionObject* colObj, ContactResultCallback& resultCallback);
445
446         ///contactTest performs a discrete collision test between two collision objects and calls the resultCallback if overlap if detected.
447         ///it reports one or more contact points (including the one with deepest penetration)
448         void    contactPairTest(btCollisionObject* colObjA, btCollisionObject* colObjB, ContactResultCallback& resultCallback);
449
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         /// objectQuerySingle performs a collision detection query and calls the resultCallback. It is used internally by rayTest.
461         static void     objectQuerySingle(const btConvexShape* castShape, const btTransform& rayFromTrans,const btTransform& rayToTrans,
462                                           btCollisionObject* collisionObject,
463                                           const btCollisionShape* collisionShape,
464                                           const btTransform& colObjWorldTransform,
465                                           ConvexResultCallback& resultCallback, btScalar        allowedPenetration);
466
467         virtual void    addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup=btBroadphaseProxy::DefaultFilter,short int collisionFilterMask=btBroadphaseProxy::AllFilter);
468
469         btCollisionObjectArray& getCollisionObjectArray()
470         {
471                 return m_collisionObjects;
472         }
473
474         const btCollisionObjectArray& getCollisionObjectArray() const
475         {
476                 return m_collisionObjects;
477         }
478
479
480         virtual void    removeCollisionObject(btCollisionObject* collisionObject);
481
482         virtual void    performDiscreteCollisionDetection();
483
484         btDispatcherInfo& getDispatchInfo()
485         {
486                 return m_dispatchInfo;
487         }
488
489         const btDispatcherInfo& getDispatchInfo() const
490         {
491                 return m_dispatchInfo;
492         }
493         
494         bool    getForceUpdateAllAabbs() const
495         {
496                 return m_forceUpdateAllAabbs;
497         }
498         void setForceUpdateAllAabbs( bool forceUpdateAllAabbs)
499         {
500                 m_forceUpdateAllAabbs = forceUpdateAllAabbs;
501         }
502
503         ///Preliminary serialization test for Bullet 2.76. Loading those files requires a separate parser (Bullet/Demos/SerializeDemo)
504         virtual void    serialize(btSerializer* serializer);
505
506 };
507
508
509 #endif //BT_COLLISION_WORLD_H