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 
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
newContactManifold(btCollisionObject * body0,btCollisionObject * body1)68 	SIMD_FORCE_INLINE btPersistentManifold* newContactManifold(btCollisionObject* body0,btCollisionObject* body1)
69 	{
70 		m_manifoldPtr = m_dispatcher->getNewManifold(body0,body1);
71 		return m_manifoldPtr;
72 	}
73 
destroyConvexAlgorithm()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 
destroyContactManifolds()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 
clearCache()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 
getLastManifold()102 	SIMD_FORCE_INLINE btPersistentManifold* getLastManifold()
103 	{
104 		return m_manifoldPtr;
105 	}
106 
107 
108 	// Call before process collision
checkManifold(btCollisionObject * body0,btCollisionObject * body1)109 	SIMD_FORCE_INLINE void checkManifold(btCollisionObject* body0,btCollisionObject* body1)
110 	{
111 		if(getLastManifold() == 0)
112 		{
113 			newContactManifold(body0,body1);
114 		}
115 
116 		m_resultOut->setPersistentManifold(getLastManifold());
117 	}
118 
119 	// Call before process collision
newAlgorithm(btCollisionObject * body0,btCollisionObject * body1)120 	SIMD_FORCE_INLINE btCollisionAlgorithm * newAlgorithm(btCollisionObject* body0,btCollisionObject* body1)
121 	{
122 		checkManifold(body0,body1);
123 
124 		btCollisionAlgorithm * convex_algorithm = m_dispatcher->findAlgorithm(
125 				body0,body1,getLastManifold());
126 		return convex_algorithm ;
127 	}
128 
129 	// Call before process collision
checkConvexAlgorithm(btCollisionObject * body0,btCollisionObject * body1)130 	SIMD_FORCE_INLINE void checkConvexAlgorithm(btCollisionObject* body0,btCollisionObject* body1)
131 	{
132 		if(m_convex_algorithm) return;
133 		m_convex_algorithm = newAlgorithm(body0,body1);
134 	}
135 
136 
137 
138 
139 	void addContactPoint(btCollisionObject * body0,
140 					btCollisionObject * body1,
141 					const btVector3 & point,
142 					const btVector3 & normal,
143 					btScalar distance);
144 
145 //! Collision routines
146 //!@{
147 
148 	void collide_gjk_triangles(btCollisionObject * body0,
149 				  btCollisionObject * body1,
150 				  btGImpactMeshShapePart * shape0,
151 				  btGImpactMeshShapePart * shape1,
152 				  const int * pairs, int pair_count);
153 
154 	void collide_sat_triangles(btCollisionObject * body0,
155 					  btCollisionObject * body1,
156 					  btGImpactMeshShapePart * shape0,
157 					  btGImpactMeshShapePart * shape1,
158 					  const int * pairs, int pair_count);
159 
160 
161 
162 
163 	void shape_vs_shape_collision(
164 					  btCollisionObject * body0,
165 					  btCollisionObject * body1,
166 					  btCollisionShape * shape0,
167 					  btCollisionShape * shape1);
168 
169 	void convex_vs_convex_collision(btCollisionObject * body0,
170 					  btCollisionObject * body1,
171 					  btCollisionShape * shape0,
172 					  btCollisionShape * shape1);
173 
174 
175 
176 	void gimpact_vs_gimpact_find_pairs(
177 					  const btTransform & trans0,
178 					  const btTransform & trans1,
179 					  btGImpactShapeInterface * shape0,
180 					  btGImpactShapeInterface * shape1,btPairSet & pairset);
181 
182 	void gimpact_vs_shape_find_pairs(
183 					  const btTransform & trans0,
184 					  const btTransform & trans1,
185 					  btGImpactShapeInterface * shape0,
186 					  btCollisionShape * shape1,
187 					  btAlignedObjectArray<int> & collided_primitives);
188 
189 
190 	void gimpacttrimeshpart_vs_plane_collision(
191 					  btCollisionObject * body0,
192 					  btCollisionObject * body1,
193 					  btGImpactMeshShapePart * shape0,
194 					  btStaticPlaneShape * shape1,bool swapped);
195 
196 
197 public:
198 
199 	btGImpactCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1);
200 
201 	virtual ~btGImpactCollisionAlgorithm();
202 
203 	virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
204 
205 	btScalar	calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
206 
getAllContactManifolds(btManifoldArray & manifoldArray)207 	virtual	void	getAllContactManifolds(btManifoldArray&	manifoldArray)
208 	{
209 		if (m_manifoldPtr)
210 			manifoldArray.push_back(m_manifoldPtr);
211 	}
212 
213 
214 	struct CreateFunc :public 	btCollisionAlgorithmCreateFunc
215 	{
CreateCollisionAlgorithmCreateFunc216 		virtual	btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
217 		{
218 			void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btGImpactCollisionAlgorithm));
219 			return new(mem) btGImpactCollisionAlgorithm(ci,body0,body1);
220 		}
221 	};
222 
223 	//! Use this function for register the algorithm externally
224 	static void registerAlgorithm(btCollisionDispatcher * dispatcher);
225 #ifdef TRI_COLLISION_PROFILING
226 	//! Gets the average time in miliseconds of tree collisions
227 	static float getAverageTreeCollisionTime();
228 
229 	//! Gets the average time in miliseconds of triangle collisions
230 	static float getAverageTriangleCollisionTime();
231 #endif //TRI_COLLISION_PROFILING
232 
233 	//! Collides two gimpact shapes
234 	/*!
235 	\pre shape0 and shape1 couldn't be btGImpactMeshShape objects
236 	*/
237 
238 
239 	void gimpact_vs_gimpact(btCollisionObject * body0,
240 					  btCollisionObject * body1,
241 					  btGImpactShapeInterface * shape0,
242 					  btGImpactShapeInterface * shape1);
243 
244 	void gimpact_vs_shape(btCollisionObject * body0,
245 					  btCollisionObject * body1,
246 					  btGImpactShapeInterface * shape0,
247 					  btCollisionShape * shape1,bool swapped);
248 
249 	void gimpact_vs_compoundshape(btCollisionObject * body0,
250 					  btCollisionObject * body1,
251 					  btGImpactShapeInterface * shape0,
252 					  btCompoundShape * shape1,bool swapped);
253 
254 	void gimpact_vs_concave(
255 					  btCollisionObject * body0,
256 					  btCollisionObject * body1,
257 					  btGImpactShapeInterface * shape0,
258 					  btConcaveShape * shape1,bool swapped);
259 
260 
261 
262 
263 		/// Accessor/Mutator pairs for Part and triangleID
setFace0(int value)264     void 	setFace0(int value)
265     {
266     	m_triface0 = value;
267     }
getFace0()268     int getFace0()
269     {
270     	return m_triface0;
271     }
setFace1(int value)272     void setFace1(int value)
273     {
274     	m_triface1 = value;
275     }
getFace1()276     int getFace1()
277     {
278     	return m_triface1;
279     }
setPart0(int value)280     void setPart0(int value)
281     {
282     	m_part0 = value;
283     }
getPart0()284     int getPart0()
285     {
286     	return m_part0;
287     }
setPart1(int value)288     void setPart1(int value)
289     {
290     	m_part1 = value;
291 		}
getPart1()292     int getPart1()
293     {
294     	return m_part1;
295     }
296 
297 };
298 
299 
300 //algorithm details
301 //#define BULLET_TRIANGLE_COLLISION 1
302 #define GIMPACT_VS_PLANE_COLLISION 1
303 
304 
305 
306 #endif //BT_GIMPACT_BVH_CONCAVE_COLLISION_ALGORITHM_H
307