bullet: Update to current svn, r2636
[blender.git] / extern / bullet2 / src / BulletCollision / Gimpact / btGImpactCollisionAlgorithm.h
1 /*! \file btGImpactShape.h
2 \author Francisco Leon Najera
3 */
4 /*
5 This source file is part of GIMPACT Library.
6
7 For the latest info, see http://gimpact.sourceforge.net/
8
9 Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371.
10 email: projectileman@yahoo.com
11
12
13 This software is provided 'as-is', without any express or implied warranty.
14 In no event will the authors be held liable for any damages arising from the use of this software.
15 Permission is granted to anyone to use this software for any purpose,
16 including commercial applications, and to alter it and redistribute it freely,
17 subject to the following restrictions:
18
19 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.
20 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
21 3. This notice may not be removed or altered from any source distribution.
22 */
23
24 #ifndef BT_GIMPACT_BVH_CONCAVE_COLLISION_ALGORITHM_H
25 #define BT_GIMPACT_BVH_CONCAVE_COLLISION_ALGORITHM_H
26
27 #include "BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h"
28 #include "BulletCollision/BroadphaseCollision/btDispatcher.h"
29 #include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
30 #include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
31 class btDispatcher;
32 #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
33 #include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
34 #include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
35
36 #include "LinearMath/btAlignedObjectArray.h"
37
38 #include "btGImpactShape.h"
39 #include "BulletCollision/CollisionShapes/btStaticPlaneShape.h"
40 #include "BulletCollision/CollisionShapes/btCompoundShape.h"
41 #include "BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h"
42 #include "LinearMath/btIDebugDraw.h"
43 #include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
44
45
46 //! Collision Algorithm for GImpact Shapes
47 /*!
48 For register this algorithm in Bullet, proceed as following:
49  \code
50 btCollisionDispatcher * dispatcher = static_cast<btCollisionDispatcher *>(m_dynamicsWorld ->getDispatcher());
51 btGImpactCollisionAlgorithm::registerAlgorithm(dispatcher);
52  \endcode
53 */
54 class btGImpactCollisionAlgorithm : public btActivatingCollisionAlgorithm
55 {
56 protected:
57         btCollisionAlgorithm * m_convex_algorithm;
58     btPersistentManifold * m_manifoldPtr;
59         btManifoldResult* m_resultOut;
60         const btDispatcherInfo * m_dispatchInfo;
61         int m_triface0;
62         int m_part0;
63         int m_triface1;
64         int m_part1;
65
66
67         //! Creates a new contact point
68         SIMD_FORCE_INLINE btPersistentManifold* newContactManifold(const btCollisionObject* body0,const btCollisionObject* body1)
69         {
70                 m_manifoldPtr = m_dispatcher->getNewManifold(body0,body1);
71                 return m_manifoldPtr;
72         }
73
74         SIMD_FORCE_INLINE void destroyConvexAlgorithm()
75         {
76                 if(m_convex_algorithm)
77                 {
78                         m_convex_algorithm->~btCollisionAlgorithm();
79                         m_dispatcher->freeCollisionAlgorithm( m_convex_algorithm);
80                         m_convex_algorithm = NULL;
81                 }
82         }
83
84         SIMD_FORCE_INLINE void destroyContactManifolds()
85         {
86                 if(m_manifoldPtr == NULL) return;
87                 m_dispatcher->releaseManifold(m_manifoldPtr);
88                 m_manifoldPtr = NULL;
89         }
90
91         SIMD_FORCE_INLINE void clearCache()
92         {
93                 destroyContactManifolds();
94                 destroyConvexAlgorithm();
95
96                 m_triface0 = -1;
97                 m_part0 = -1;
98                 m_triface1 = -1;
99                 m_part1 = -1;
100         }
101
102         SIMD_FORCE_INLINE btPersistentManifold* getLastManifold()
103         {
104                 return m_manifoldPtr;
105         }
106
107
108         // Call before process collision
109         SIMD_FORCE_INLINE void checkManifold(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
110         {
111                 if(getLastManifold() == 0)
112                 {
113                         newContactManifold(body0Wrap->getCollisionObject(),body1Wrap->getCollisionObject());
114                 }
115
116                 m_resultOut->setPersistentManifold(getLastManifold());
117         }
118
119         // Call before process collision
120         SIMD_FORCE_INLINE btCollisionAlgorithm * newAlgorithm(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
121         {
122                 checkManifold(body0Wrap,body1Wrap);
123
124                 btCollisionAlgorithm * convex_algorithm = m_dispatcher->findAlgorithm(
125                                 body0Wrap,body1Wrap,getLastManifold());
126                 return convex_algorithm ;
127         }
128
129         // Call before process collision
130         SIMD_FORCE_INLINE void checkConvexAlgorithm(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
131         {
132                 if(m_convex_algorithm) return;
133                 m_convex_algorithm = newAlgorithm(body0Wrap,body1Wrap);
134         }
135
136
137
138
139         void addContactPoint(const btCollisionObjectWrapper * body0Wrap,
140                                         const btCollisionObjectWrapper * body1Wrap,
141                                         const btVector3 & point,
142                                         const btVector3 & normal,
143                                         btScalar distance);
144
145 //! Collision routines
146 //!@{
147
148         void collide_gjk_triangles(const btCollisionObjectWrapper* body0Wrap,
149                                   const btCollisionObjectWrapper* body1Wrap,
150                                   const btGImpactMeshShapePart * shape0,
151                                   const btGImpactMeshShapePart * shape1,
152                                   const int * pairs, int pair_count);
153
154         void collide_sat_triangles(const btCollisionObjectWrapper* body0Wrap,
155                                           const btCollisionObjectWrapper* body1Wrap,
156                                           const btGImpactMeshShapePart * shape0,
157                                           const btGImpactMeshShapePart * shape1,
158                                           const int * pairs, int pair_count);
159
160
161
162
163         void shape_vs_shape_collision(
164                                           const btCollisionObjectWrapper* body0,
165                                           const btCollisionObjectWrapper* body1,
166                                           const btCollisionShape * shape0,
167                                           const btCollisionShape * shape1);
168
169         void convex_vs_convex_collision(const btCollisionObjectWrapper* body0Wrap,
170                                           const btCollisionObjectWrapper* body1Wrap,
171                                           const btCollisionShape* shape0,
172                                           const btCollisionShape* shape1);
173
174
175
176         void gimpact_vs_gimpact_find_pairs(
177                                           const btTransform & trans0,
178                                           const btTransform & trans1,
179                                           const btGImpactShapeInterface * shape0,
180                                           const btGImpactShapeInterface * shape1,btPairSet & pairset);
181
182         void gimpact_vs_shape_find_pairs(
183                                           const btTransform & trans0,
184                                           const btTransform & trans1,
185                                           const btGImpactShapeInterface * shape0,
186                                           const btCollisionShape * shape1,
187                                           btAlignedObjectArray<int> & collided_primitives);
188
189
190         void gimpacttrimeshpart_vs_plane_collision(
191                                           const btCollisionObjectWrapper * body0Wrap,
192                                           const btCollisionObjectWrapper * body1Wrap,
193                                           const btGImpactMeshShapePart * shape0,
194                                           const btStaticPlaneShape * shape1,bool swapped);
195
196
197 public:
198
199         btGImpactCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap);
200
201         virtual ~btGImpactCollisionAlgorithm();
202
203         virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
204
205         btScalar        calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
206
207         virtual void    getAllContactManifolds(btManifoldArray& manifoldArray)
208         {
209                 if (m_manifoldPtr)
210                         manifoldArray.push_back(m_manifoldPtr);
211         }
212
213         btManifoldResult*       internalGetResultOut()
214         {
215                 return m_resultOut;
216         }
217
218         struct CreateFunc :public       btCollisionAlgorithmCreateFunc
219         {
220                 virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
221                 {
222                         void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btGImpactCollisionAlgorithm));
223                         return new(mem) btGImpactCollisionAlgorithm(ci,body0Wrap,body1Wrap);
224                 }
225         };
226
227         //! Use this function for register the algorithm externally
228         static void registerAlgorithm(btCollisionDispatcher * dispatcher);
229 #ifdef TRI_COLLISION_PROFILING
230         //! Gets the average time in miliseconds of tree collisions
231         static float getAverageTreeCollisionTime();
232
233         //! Gets the average time in miliseconds of triangle collisions
234         static float getAverageTriangleCollisionTime();
235 #endif //TRI_COLLISION_PROFILING
236
237         //! Collides two gimpact shapes
238         /*!
239         \pre shape0 and shape1 couldn't be btGImpactMeshShape objects
240         */
241
242
243         void gimpact_vs_gimpact(const btCollisionObjectWrapper* body0Wrap,
244                                           const btCollisionObjectWrapper * body1Wrap,
245                                           const btGImpactShapeInterface * shape0,
246                                           const btGImpactShapeInterface * shape1);
247
248         void gimpact_vs_shape(const btCollisionObjectWrapper* body0Wrap,
249                                           const btCollisionObjectWrapper* body1Wrap,
250                                           const btGImpactShapeInterface * shape0,
251                                           const btCollisionShape * shape1,bool swapped);
252
253         void gimpact_vs_compoundshape(const btCollisionObjectWrapper * body0Wrap,
254                                           const btCollisionObjectWrapper * body1Wrap,
255                                           const btGImpactShapeInterface * shape0,
256                                           const btCompoundShape * shape1,bool swapped);
257
258         void gimpact_vs_concave(
259                                           const btCollisionObjectWrapper * body0Wrap,
260                                           const btCollisionObjectWrapper * body1Wrap,
261                                           const btGImpactShapeInterface * shape0,
262                                           const btConcaveShape * shape1,bool swapped);
263
264
265
266
267                 /// Accessor/Mutator pairs for Part and triangleID
268     void        setFace0(int value) 
269     { 
270         m_triface0 = value; 
271     }
272     int getFace0() 
273     { 
274         return m_triface0; 
275     }
276     void setFace1(int value) 
277     { 
278         m_triface1 = value; 
279     }
280     int getFace1() 
281     { 
282         return m_triface1; 
283     }
284     void setPart0(int value) 
285     { 
286         m_part0 = value; 
287     }
288     int getPart0() 
289     { 
290         return m_part0; 
291     }
292     void setPart1(int value) 
293     { 
294         m_part1 = value; 
295                 }
296     int getPart1() 
297     { 
298         return m_part1; 
299     }
300
301 };
302
303
304 //algorithm details
305 //#define BULLET_TRIANGLE_COLLISION 1
306 #define GIMPACT_VS_PLANE_COLLISION 1
307
308
309
310 #endif //BT_GIMPACT_BVH_CONCAVE_COLLISION_ALGORITHM_H