Home | History | Annotate | Download | only in Gimpact
      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 (at) 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
    311