[dali_2.3.21] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-physics / third-party / bullet3 / 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 //! Collision Algorithm for GImpact Shapes
46 /*!
47 For register this algorithm in Bullet, proceed as following:
48  \code
49 btCollisionDispatcher * dispatcher = static_cast<btCollisionDispatcher *>(m_dynamicsWorld ->getDispatcher());
50 btGImpactCollisionAlgorithm::registerAlgorithm(dispatcher);
51  \endcode
52 */
53 class btGImpactCollisionAlgorithm : public btActivatingCollisionAlgorithm
54 {
55 protected:
56         btCollisionAlgorithm* m_convex_algorithm;
57         btPersistentManifold* m_manifoldPtr;
58         btManifoldResult* m_resultOut;
59         const btDispatcherInfo* m_dispatchInfo;
60         int m_triface0;
61         int m_part0;
62         int m_triface1;
63         int m_part1;
64
65         //! Creates a new contact point
66         SIMD_FORCE_INLINE btPersistentManifold* newContactManifold(const btCollisionObject* body0, const btCollisionObject* body1)
67         {
68                 m_manifoldPtr = m_dispatcher->getNewManifold(body0, body1);
69                 return m_manifoldPtr;
70         }
71
72         SIMD_FORCE_INLINE void destroyConvexAlgorithm()
73         {
74                 if (m_convex_algorithm)
75                 {
76                         m_convex_algorithm->~btCollisionAlgorithm();
77                         m_dispatcher->freeCollisionAlgorithm(m_convex_algorithm);
78                         m_convex_algorithm = NULL;
79                 }
80         }
81
82         SIMD_FORCE_INLINE void destroyContactManifolds()
83         {
84                 if (m_manifoldPtr == NULL) return;
85                 m_dispatcher->releaseManifold(m_manifoldPtr);
86                 m_manifoldPtr = NULL;
87         }
88
89         SIMD_FORCE_INLINE void clearCache()
90         {
91                 destroyContactManifolds();
92                 destroyConvexAlgorithm();
93
94                 m_triface0 = -1;
95                 m_part0 = -1;
96                 m_triface1 = -1;
97                 m_part1 = -1;
98         }
99
100         SIMD_FORCE_INLINE btPersistentManifold* getLastManifold()
101         {
102                 return m_manifoldPtr;
103         }
104
105         // Call before process collision
106         SIMD_FORCE_INLINE void checkManifold(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap)
107         {
108                 if (getLastManifold() == 0)
109                 {
110                         newContactManifold(body0Wrap->getCollisionObject(), body1Wrap->getCollisionObject());
111                 }
112
113                 m_resultOut->setPersistentManifold(getLastManifold());
114         }
115
116         // Call before process collision
117         SIMD_FORCE_INLINE btCollisionAlgorithm* newAlgorithm(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap)
118         {
119                 checkManifold(body0Wrap, body1Wrap);
120
121                 btCollisionAlgorithm* convex_algorithm = m_dispatcher->findAlgorithm(
122                         body0Wrap, body1Wrap, getLastManifold(), BT_CONTACT_POINT_ALGORITHMS);
123                 return convex_algorithm;
124         }
125
126         // Call before process collision
127         SIMD_FORCE_INLINE void checkConvexAlgorithm(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap)
128         {
129                 if (m_convex_algorithm) return;
130                 m_convex_algorithm = newAlgorithm(body0Wrap, body1Wrap);
131         }
132
133         void addContactPoint(const btCollisionObjectWrapper* body0Wrap,
134                                                  const btCollisionObjectWrapper* body1Wrap,
135                                                  const btVector3& point,
136                                                  const btVector3& normal,
137                                                  btScalar distance);
138
139         //! Collision routines
140         //!@{
141
142         void collide_gjk_triangles(const btCollisionObjectWrapper* body0Wrap,
143                                                            const btCollisionObjectWrapper* body1Wrap,
144                                                            const btGImpactMeshShapePart* shape0,
145                                                            const btGImpactMeshShapePart* shape1,
146                                                            const int* pairs, int pair_count);
147
148         void collide_sat_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 shape_vs_shape_collision(
155                 const btCollisionObjectWrapper* body0,
156                 const btCollisionObjectWrapper* body1,
157                 const btCollisionShape* shape0,
158                 const btCollisionShape* shape1);
159
160         void convex_vs_convex_collision(const btCollisionObjectWrapper* body0Wrap,
161                                                                         const btCollisionObjectWrapper* body1Wrap,
162                                                                         const btCollisionShape* shape0,
163                                                                         const btCollisionShape* shape1);
164
165         void gimpact_vs_gimpact_find_pairs(
166                 const btTransform& trans0,
167                 const btTransform& trans1,
168                 const btGImpactShapeInterface* shape0,
169                 const btGImpactShapeInterface* shape1, btPairSet& pairset);
170
171         void gimpact_vs_shape_find_pairs(
172                 const btTransform& trans0,
173                 const btTransform& trans1,
174                 const btGImpactShapeInterface* shape0,
175                 const btCollisionShape* shape1,
176                 btAlignedObjectArray<int>& collided_primitives);
177
178         void gimpacttrimeshpart_vs_plane_collision(
179                 const btCollisionObjectWrapper* body0Wrap,
180                 const btCollisionObjectWrapper* body1Wrap,
181                 const btGImpactMeshShapePart* shape0,
182                 const btStaticPlaneShape* shape1, bool swapped);
183
184 public:
185         btGImpactCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap);
186
187         virtual ~btGImpactCollisionAlgorithm();
188
189         virtual void processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut);
190
191         btScalar calculateTimeOfImpact(btCollisionObject* body0, btCollisionObject* body1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut);
192
193         virtual void getAllContactManifolds(btManifoldArray& manifoldArray)
194         {
195                 if (m_manifoldPtr)
196                         manifoldArray.push_back(m_manifoldPtr);
197         }
198
199         btManifoldResult* internalGetResultOut()
200         {
201                 return m_resultOut;
202         }
203
204         struct CreateFunc : public btCollisionAlgorithmCreateFunc
205         {
206                 virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap)
207                 {
208                         void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btGImpactCollisionAlgorithm));
209                         return new (mem) btGImpactCollisionAlgorithm(ci, body0Wrap, body1Wrap);
210                 }
211         };
212
213         //! Use this function for register the algorithm externally
214         static void registerAlgorithm(btCollisionDispatcher* dispatcher);
215 #ifdef TRI_COLLISION_PROFILING
216         //! Gets the average time in miliseconds of tree collisions
217         static float getAverageTreeCollisionTime();
218
219         //! Gets the average time in miliseconds of triangle collisions
220         static float getAverageTriangleCollisionTime();
221 #endif  //TRI_COLLISION_PROFILING
222
223         //! Collides two gimpact shapes
224         /*!
225         \pre shape0 and shape1 couldn't be btGImpactMeshShape objects
226         */
227
228         void gimpact_vs_gimpact(const btCollisionObjectWrapper* body0Wrap,
229                                                         const btCollisionObjectWrapper* body1Wrap,
230                                                         const btGImpactShapeInterface* shape0,
231                                                         const btGImpactShapeInterface* shape1);
232
233         void gimpact_vs_shape(const btCollisionObjectWrapper* body0Wrap,
234                                                   const btCollisionObjectWrapper* body1Wrap,
235                                                   const btGImpactShapeInterface* shape0,
236                                                   const btCollisionShape* shape1, bool swapped);
237
238         void gimpact_vs_compoundshape(const btCollisionObjectWrapper* body0Wrap,
239                                                                   const btCollisionObjectWrapper* body1Wrap,
240                                                                   const btGImpactShapeInterface* shape0,
241                                                                   const btCompoundShape* shape1, bool swapped);
242
243         void gimpact_vs_concave(
244                 const btCollisionObjectWrapper* body0Wrap,
245                 const btCollisionObjectWrapper* body1Wrap,
246                 const btGImpactShapeInterface* shape0,
247                 const btConcaveShape* shape1, bool swapped);
248
249         /// Accessor/Mutator pairs for Part and triangleID
250         void setFace0(int value)
251         {
252                 m_triface0 = value;
253         }
254         int getFace0()
255         {
256                 return m_triface0;
257         }
258         void setFace1(int value)
259         {
260                 m_triface1 = value;
261         }
262         int getFace1()
263         {
264                 return m_triface1;
265         }
266         void setPart0(int value)
267         {
268                 m_part0 = value;
269         }
270         int getPart0()
271         {
272                 return m_part0;
273         }
274         void setPart1(int value)
275         {
276                 m_part1 = value;
277         }
278         int getPart1()
279         {
280                 return m_part1;
281         }
282 };
283
284 //algorithm details
285 //#define BULLET_TRIANGLE_COLLISION 1
286 #define GIMPACT_VS_PLANE_COLLISION 1
287
288 #endif  //BT_GIMPACT_BVH_CONCAVE_COLLISION_ALGORITHM_H