void btGImpactCollisionAlgorithm::collide_gjk_triangles(const btCollisionObjectWrapper* body0Wrap,
														const btCollisionObjectWrapper* body1Wrap,
														const btGImpactMeshShapePart* shape0,
														const btGImpactMeshShapePart* shape1,
														const int* pairs, int pair_count)
{
	btTriangleShapeEx tri0;
	btTriangleShapeEx tri1;

	shape0->lockChildShapes();
	shape1->lockChildShapes();

	const int* pair_pointer = pairs;

	while (pair_count--)
	{
		m_triface0 = *(pair_pointer);
		m_triface1 = *(pair_pointer + 1);
		pair_pointer += 2;

		shape0->getBulletTriangle(m_triface0, tri0);
		shape1->getBulletTriangle(m_triface1, tri1);

		//collide two convex shapes
		if (tri0.overlap_test_conservative(tri1))
		{
			convex_vs_convex_collision(body0Wrap, body1Wrap, &tri0, &tri1);
		}
	}

	shape0->unlockChildShapes();
	shape1->unlockChildShapes();
}
void btGImpactCollisionAlgorithm::gimpact_vs_gimpact(
						btCollisionObject * body0,
					   	btCollisionObject * body1,
					  	btGImpactShapeInterface * shape0,
					  	btGImpactShapeInterface * shape1)
{

	if(shape0->getGImpactShapeType()==CONST_GIMPACT_TRIMESH_SHAPE)
	{
		btGImpactMeshShape * meshshape0 = static_cast<btGImpactMeshShape *>(shape0);
		m_part0 = meshshape0->getMeshPartCount();

		while(m_part0--)
		{
			gimpact_vs_gimpact(body0,body1,meshshape0->getMeshPart(m_part0),shape1);
		}

		return;
	}

	if(shape1->getGImpactShapeType()==CONST_GIMPACT_TRIMESH_SHAPE)
	{
		btGImpactMeshShape * meshshape1 = static_cast<btGImpactMeshShape *>(shape1);
		m_part1 = meshshape1->getMeshPartCount();

		while(m_part1--)
		{

			gimpact_vs_gimpact(body0,body1,shape0,meshshape1->getMeshPart(m_part1));

		}

		return;
	}


	btTransform orgtrans0 = body0->getWorldTransform();
	btTransform orgtrans1 = body1->getWorldTransform();

	btPairSet pairset;

	gimpact_vs_gimpact_find_pairs(orgtrans0,orgtrans1,shape0,shape1,pairset);

	if(pairset.size()== 0) return;

	if(shape0->getGImpactShapeType() == CONST_GIMPACT_TRIMESH_SHAPE_PART &&
		shape1->getGImpactShapeType() == CONST_GIMPACT_TRIMESH_SHAPE_PART)
	{
		btGImpactMeshShapePart * shapepart0 = static_cast<btGImpactMeshShapePart * >(shape0);
		btGImpactMeshShapePart * shapepart1 = static_cast<btGImpactMeshShapePart * >(shape1);
		//specialized function
		#ifdef BULLET_TRIANGLE_COLLISION
		collide_gjk_triangles(body0,body1,shapepart0,shapepart1,&pairset[0].m_index1,pairset.size());
		#else
		collide_sat_triangles(body0,body1,shapepart0,shapepart1,&pairset[0].m_index1,pairset.size());
		#endif

		return;
	}

	//general function

	shape0->lockChildShapes();
	shape1->lockChildShapes();

	GIM_ShapeRetriever retriever0(shape0);
	GIM_ShapeRetriever retriever1(shape1);

	bool child_has_transform0 = shape0->childrenHasTransform();
	bool child_has_transform1 = shape1->childrenHasTransform();

	int i = pairset.size();
	while(i--)
	{
		GIM_PAIR * pair = &pairset[i];
		m_triface0 = pair->m_index1;
		m_triface1 = pair->m_index2;
		btCollisionShape * colshape0 = retriever0.getChildShape(m_triface0);
		btCollisionShape * colshape1 = retriever1.getChildShape(m_triface1);

		if(child_has_transform0)
		{
			body0->setWorldTransform(orgtrans0*shape0->getChildTransform(m_triface0));
		}

		if(child_has_transform1)
		{
			body1->setWorldTransform(orgtrans1*shape1->getChildTransform(m_triface1));
		}

		//collide two convex shapes
		convex_vs_convex_collision(body0,body1,colshape0,colshape1);


		if(child_has_transform0)
		{
			body0->setWorldTransform(orgtrans0);
		}

		if(child_has_transform1)
		{
			body1->setWorldTransform(orgtrans1);
		}

	}

	shape0->unlockChildShapes();
	shape1->unlockChildShapes();
}