diff --git a/include/hpp/fcl/collision.h b/include/hpp/fcl/collision.h
index cc68c88bd9371631ba1ca93d210d9a92be494da0..89897e66b8b218ce2358e5bc1a4203a0d5fc9fae 100644
--- a/include/hpp/fcl/collision.h
+++ b/include/hpp/fcl/collision.h
@@ -42,6 +42,7 @@
 #include <hpp/fcl/data_types.h>
 #include <hpp/fcl/collision_object.h>
 #include <hpp/fcl/collision_data.h>
+#include <hpp/fcl/narrowphase/narrowphase.h>
 
 namespace hpp
 {
@@ -54,13 +55,22 @@ namespace fcl
 /// Return value is the number of contacts generated between the two objects.
 
 std::size_t collide(const CollisionObject* o1, const CollisionObject* o2,
+                    const GJKSolver* nsolver,
                     const CollisionRequest& request,
                     CollisionResult& result);
 
 std::size_t collide(const CollisionGeometry* o1, const Transform3f& tf1,
                     const CollisionGeometry* o2, const Transform3f& tf2,
+                    const GJKSolver* nsolver_,
                     const CollisionRequest& request,
                     CollisionResult& result);
+
+std::size_t collide(const CollisionObject* o1, const CollisionObject* o2,
+                    const CollisionRequest& request, CollisionResult& result);
+
+std::size_t collide(const CollisionGeometry* o1, const Transform3f& tf1,
+                    const CollisionGeometry* o2, const Transform3f& tf2,
+                    const CollisionRequest& request, CollisionResult& result);
 }
 
 } // namespace hpp
diff --git a/include/hpp/fcl/collision_func_matrix.h b/include/hpp/fcl/collision_func_matrix.h
index af0355bd5849bf2ddb3044f44c7119c5247e75d8..892ea4013d870af3a8be510593454934f3931f6f 100644
--- a/include/hpp/fcl/collision_func_matrix.h
+++ b/include/hpp/fcl/collision_func_matrix.h
@@ -42,6 +42,7 @@
 
 #include <hpp/fcl/collision_object.h>
 #include <hpp/fcl/collision_data.h>
+#include <hpp/fcl/narrowphase/narrowphase.h>
 
 namespace hpp
 {
@@ -49,7 +50,7 @@ namespace fcl
 {
 
 /// @brief collision matrix stores the functions for collision between different types of objects and provides a uniform call interface
-template<typename GJKSolver>
+
 struct CollisionFunctionMatrix
 {
   /// @brief the uniform call interface for collision: for collision, we need know
diff --git a/include/hpp/fcl/distance.h b/include/hpp/fcl/distance.h
index 87216ce6df8a1621f7bf885f94fd243ece3c64e0..9244674d40bd7e6abb352061cccbbd14833d2211 100644
--- a/include/hpp/fcl/distance.h
+++ b/include/hpp/fcl/distance.h
@@ -40,6 +40,7 @@
 
 #include <hpp/fcl/collision_object.h>
 #include <hpp/fcl/collision_data.h>
+#include <hpp/fcl/narrowphase/narrowphase.h>
 
 namespace hpp
 {
@@ -50,12 +51,19 @@ namespace fcl
 /// Return value is the minimum distance generated between the two objects.
 
 FCL_REAL distance(const CollisionObject* o1, const CollisionObject* o2,
+                  const GJKSolver* nsolver,
                   const DistanceRequest& request, DistanceResult& result);
 
-FCL_REAL distance(const CollisionGeometry* o1, const Transform3f& tf1,
+FCL_REAL distance(const CollisionGeometry* o1, const Transform3f& tf1, 
                   const CollisionGeometry* o2, const Transform3f& tf2,
+                  const GJKSolver* nsolver_,
                   const DistanceRequest& request, DistanceResult& result);
 
+FCL_REAL distance(const CollisionObject* o1, const CollisionObject* o2, const DistanceRequest& request, DistanceResult& result);
+
+FCL_REAL distance(const CollisionGeometry* o1, const Transform3f& tf1,
+                  const CollisionGeometry* o2, const Transform3f& tf2,
+                  const DistanceRequest& request, DistanceResult& result);
 }
 
 } // namespace hpp
diff --git a/include/hpp/fcl/distance_func_matrix.h b/include/hpp/fcl/distance_func_matrix.h
index 89ee2d549135e2e62320847a4a75e0ae5af0619b..1f0ea6d26e573f065a6a97cc6552fff40ba31a20 100644
--- a/include/hpp/fcl/distance_func_matrix.h
+++ b/include/hpp/fcl/distance_func_matrix.h
@@ -40,6 +40,7 @@
 
 #include <hpp/fcl/collision_object.h>
 #include <hpp/fcl/collision_data.h>
+#include <hpp/fcl/narrowphase/narrowphase.h>
 
 namespace hpp
 {
@@ -47,7 +48,6 @@ namespace fcl
 {
 
 /// @brief distance matrix stores the functions for distance between different types of objects and provides a uniform call interface
-template<typename GJKSolver>
 struct DistanceFunctionMatrix
 {
   /// @brief the uniform call interface for distance: for distance, we need know
diff --git a/src/collision.cpp b/src/collision.cpp
index b6a45e8301499083696e1cb48ff2e4aa51671f86..fd1bc5c6cbf068a2f89b1eac4afc3f5f8a6e6010 100644
--- a/src/collision.cpp
+++ b/src/collision.cpp
@@ -47,21 +47,18 @@ namespace hpp
 namespace fcl
 {
 
-template<typename GJKSolver>
-CollisionFunctionMatrix<GJKSolver>& getCollisionFunctionLookTable()
+CollisionFunctionMatrix& getCollisionFunctionLookTable()
 {
-  static CollisionFunctionMatrix<GJKSolver> table;
+  static CollisionFunctionMatrix table;
   return table;
 }
 
-template<typename GJKSolver>
 std::size_t collide(const CollisionObject* o1, const CollisionObject* o2,
                     const GJKSolver* nsolver,
                     const CollisionRequest& request,
                     CollisionResult& result)
 {
-  return collide(o1->collisionGeometry().get(), o1->getTransform(), o2->collisionGeometry().get(), o2->getTransform(),
-                 nsolver, request, result);
+  return collide(o1->collisionGeometry().get(), o1->getTransform(), o2->collisionGeometry().get(), o2->getTransform(), nsolver, request, result);
 }
 
 // reorder collision results in the order the call has been made.
@@ -81,7 +78,6 @@ void invertResults(CollisionResult& result)
     }
 }
 
-template<typename GJKSolver>
 std::size_t collide(const CollisionGeometry* o1, const Transform3f& tf1,
                     const CollisionGeometry* o2, const Transform3f& tf2,
                     const GJKSolver* nsolver_,
@@ -92,7 +88,7 @@ std::size_t collide(const CollisionGeometry* o1, const Transform3f& tf1,
   if(!nsolver_)
     nsolver = new GJKSolver();  
 
-  const CollisionFunctionMatrix<GJKSolver>& looktable = getCollisionFunctionLookTable<GJKSolver>();
+  const CollisionFunctionMatrix& looktable = getCollisionFunctionLookTable();
   result.distance_lower_bound = -1;
   std::size_t res; 
   if(request.num_max_contacts == 0)
@@ -146,7 +142,7 @@ std::size_t collide(const CollisionObject* o1, const CollisionObject* o2,
   case GST_INDEP:
     {
       GJKSolver solver;
-      return collide<GJKSolver>(o1, o2, &solver, request, result);
+      return collide(o1, o2, &solver, request, result);
     }
   default:
     return -1; // error
@@ -162,7 +158,7 @@ std::size_t collide(const CollisionGeometry* o1, const Transform3f& tf1,
   case GST_INDEP:
     {
       GJKSolver solver;
-      return collide<GJKSolver>(o1, tf1, o2, tf2, &solver, request, result);
+      return collide(o1, tf1, o2, tf2, &solver, request, result);
     }
   default:
     std::cerr << "Warning! Invalid GJK solver" << std::endl;
diff --git a/src/collision_func_matrix.cpp b/src/collision_func_matrix.cpp
index 5dbcc9181a6988fb65898c55fcc03d66ba42e2d1..a1abe2a6975ba19c75d139f9fd763ded82c6142f 100644
--- a/src/collision_func_matrix.cpp
+++ b/src/collision_func_matrix.cpp
@@ -49,17 +49,17 @@ namespace fcl
 {
 
 #ifdef HPP_FCL_HAVE_OCTOMAP
-template<typename T_SH, typename GJKSolver>
+template<typename T_SH>
 std::size_t ShapeOcTreeCollide(const CollisionGeometry* o1, const Transform3f& tf1, const CollisionGeometry* o2, const Transform3f& tf2,
                                const GJKSolver* nsolver,
                                const CollisionRequest& request, CollisionResult& result)
 {
   if(request.isSatisfied(result)) return result.numContacts();
 
-  ShapeOcTreeCollisionTraversalNode<T_SH, GJKSolver> node (request);
+  ShapeOcTreeCollisionTraversalNode<T_SH> node (request);
   const T_SH* obj1 = static_cast<const T_SH*>(o1);
   const OcTree* obj2 = static_cast<const OcTree*>(o2);
-  OcTreeSolver<GJKSolver> otsolver(nsolver);
+  OcTreeSolver otsolver(nsolver);
 
   initialize(node, *obj1, tf1, *obj2, tf2, &otsolver, result);
   collide(&node, request, result);
@@ -67,17 +67,17 @@ std::size_t ShapeOcTreeCollide(const CollisionGeometry* o1, const Transform3f& t
   return result.numContacts();
 }
 
-template<typename T_SH, typename GJKSolver>
+template<typename T_SH>
 std::size_t OcTreeShapeCollide(const CollisionGeometry* o1, const Transform3f& tf1, const CollisionGeometry* o2, const Transform3f& tf2,
                                const GJKSolver* nsolver,
                                const CollisionRequest& request, CollisionResult& result)
 {
   if(request.isSatisfied(result)) return result.numContacts();
 
-  OcTreeShapeCollisionTraversalNode<T_SH, GJKSolver> node (request);
+  OcTreeShapeCollisionTraversalNode<T_SH> node (request);
   const OcTree* obj1 = static_cast<const OcTree*>(o1);
   const T_SH* obj2 = static_cast<const T_SH*>(o2);
-  OcTreeSolver<GJKSolver> otsolver(nsolver);
+  OcTreeSolver otsolver(nsolver);
 
   initialize(node, *obj1, tf1, *obj2, tf2, &otsolver, result);
   collide(&node, request, result);
@@ -85,17 +85,16 @@ std::size_t OcTreeShapeCollide(const CollisionGeometry* o1, const Transform3f& t
   return result.numContacts();
 }
 
-template<typename GJKSolver>
 std::size_t OcTreeCollide(const CollisionGeometry* o1, const Transform3f& tf1, const CollisionGeometry* o2, const Transform3f& tf2,
                           const GJKSolver* nsolver,
                           const CollisionRequest& request, CollisionResult& result)
 {
   if(request.isSatisfied(result)) return result.numContacts();
 
-  OcTreeCollisionTraversalNode<GJKSolver> node (request);
+  OcTreeCollisionTraversalNode node (request);
   const OcTree* obj1 = static_cast<const OcTree*>(o1);
   const OcTree* obj2 = static_cast<const OcTree*>(o2);
-  OcTreeSolver<GJKSolver> otsolver(nsolver);
+  OcTreeSolver otsolver(nsolver);
 
   initialize(node, *obj1, tf1, *obj2, tf2, &otsolver, result);
   collide(&node, request, result);
@@ -103,34 +102,34 @@ std::size_t OcTreeCollide(const CollisionGeometry* o1, const Transform3f& tf1, c
   return result.numContacts();
 }
 
-template<typename T_BVH, typename GJKSolver>
+template<typename T_BVH>
 std::size_t OcTreeBVHCollide(const CollisionGeometry* o1, const Transform3f& tf1, const CollisionGeometry* o2, const Transform3f& tf2,
                              const GJKSolver* nsolver,
                              const CollisionRequest& request, CollisionResult& result)
 {
   if(request.isSatisfied(result)) return result.numContacts();
 
-  OcTreeMeshCollisionTraversalNode<T_BVH, GJKSolver> node (request);
+  OcTreeMeshCollisionTraversalNode<T_BVH> node (request);
   const OcTree* obj1 = static_cast<const OcTree*>(o1);
   const BVHModel<T_BVH>* obj2 = static_cast<const BVHModel<T_BVH>*>(o2);
-  OcTreeSolver<GJKSolver> otsolver(nsolver);
+  OcTreeSolver otsolver(nsolver);
 
   initialize(node, *obj1, tf1, *obj2, tf2, &otsolver, result);
   collide(&node, request, result);
   return result.numContacts();
 }
 
-template<typename T_BVH, typename GJKSolver>
+template<typename T_BVH>
 std::size_t BVHOcTreeCollide(const CollisionGeometry* o1, const Transform3f& tf1, const CollisionGeometry* o2, const Transform3f& tf2,
                              const GJKSolver* nsolver,
                              const CollisionRequest& request, CollisionResult& result)
 {
   if(request.isSatisfied(result)) return result.numContacts();
  
-  MeshOcTreeCollisionTraversalNode<T_BVH, GJKSolver> node (request);
+  MeshOcTreeCollisionTraversalNode<T_BVH> node (request);
   const BVHModel<T_BVH>* obj1 = static_cast<const BVHModel<T_BVH>*>(o1);
   const OcTree* obj2 = static_cast<const OcTree*>(o2);
-  OcTreeSolver<GJKSolver> otsolver(nsolver);
+  OcTreeSolver otsolver(nsolver);
 
   initialize(node, *obj1, tf1, *obj2, tf2, &otsolver, result);
   collide(&node, request, result);
@@ -139,7 +138,7 @@ std::size_t BVHOcTreeCollide(const CollisionGeometry* o1, const Transform3f& tf1
 
 #endif
 
-template<typename T_SH1, typename T_SH2, typename GJKSolver>
+template<typename T_SH1, typename T_SH2>
 std::size_t ShapeShapeCollide(const CollisionGeometry* o1, const Transform3f& tf1, const CollisionGeometry* o2, const Transform3f& tf2, 
                               const GJKSolver* nsolver,
                               const CollisionRequest& request, CollisionResult& result)
@@ -148,7 +147,7 @@ std::size_t ShapeShapeCollide(const CollisionGeometry* o1, const Transform3f& tf
 
   DistanceResult distanceResult;
   DistanceRequest distanceRequest (request.enable_contact);
-  FCL_REAL distance = ShapeShapeDistance <T_SH1, T_SH2, GJKSolver>
+  FCL_REAL distance = ShapeShapeDistance <T_SH1, T_SH2>
     (o1, tf1, o2, tf2, nsolver, distanceRequest, distanceResult);
 
   if (distance <= 0) {
@@ -179,7 +178,7 @@ std::size_t ShapeShapeCollide(const CollisionGeometry* o1, const Transform3f& tf
   return 0;
 }
 
-template<typename T_BVH, typename T_SH, typename GJKSolver>
+template<typename T_BVH, typename T_SH>
 struct BVHShapeCollider
 {
   static std::size_t collide(const CollisionGeometry* o1, const Transform3f& tf1, const CollisionGeometry* o2, const Transform3f& tf2, 
@@ -188,7 +187,7 @@ struct BVHShapeCollider
   {
     if(request.isSatisfied(result)) return result.numContacts();
 
-    MeshShapeCollisionTraversalNode<T_BVH, T_SH, GJKSolver> node (request);
+    MeshShapeCollisionTraversalNode<T_BVH, T_SH> node (request);
     const BVHModel<T_BVH>* obj1 = static_cast<const BVHModel<T_BVH>* >(o1);
     BVHModel<T_BVH>* obj1_tmp = new BVHModel<T_BVH>(*obj1);
     Transform3f tf1_tmp = tf1;
@@ -205,7 +204,7 @@ struct BVHShapeCollider
 namespace details
 {
 
-template<typename OrientMeshShapeCollisionTraveralNode, typename T_BVH, typename T_SH, typename GJKSolver>
+template<typename OrientMeshShapeCollisionTraveralNode, typename T_BVH, typename T_SH>
 std::size_t orientedBVHShapeCollide(const CollisionGeometry* o1, const Transform3f& tf1, const CollisionGeometry* o2, const Transform3f& tf2, 
                                     const GJKSolver* nsolver,
                                     const CollisionRequest& request, CollisionResult& result)
@@ -224,50 +223,50 @@ std::size_t orientedBVHShapeCollide(const CollisionGeometry* o1, const Transform
 }
 
 
-template<typename T_SH, typename GJKSolver>
-struct BVHShapeCollider<OBB, T_SH, GJKSolver>
+template<typename T_SH>
+struct BVHShapeCollider<OBB, T_SH>
 {
   static std::size_t collide(const CollisionGeometry* o1, const Transform3f& tf1, const CollisionGeometry* o2, const Transform3f& tf2, 
                              const GJKSolver* nsolver,
                              const CollisionRequest& request, CollisionResult& result)
   {
-    return details::orientedBVHShapeCollide<MeshShapeCollisionTraversalNodeOBB<T_SH, GJKSolver>, OBB, T_SH, GJKSolver>(o1, tf1, o2, tf2, nsolver, request, result);
+    return details::orientedBVHShapeCollide<MeshShapeCollisionTraversalNodeOBB<T_SH>, OBB, T_SH>(o1, tf1, o2, tf2, nsolver, request, result);
   } 
 };
 
 
-template<typename T_SH, typename GJKSolver>
-struct BVHShapeCollider<RSS, T_SH, GJKSolver>
+template<typename T_SH>
+struct BVHShapeCollider<RSS, T_SH>
 {
   static std::size_t collide(const CollisionGeometry* o1, const Transform3f& tf1, const CollisionGeometry* o2, const Transform3f& tf2, 
                              const GJKSolver* nsolver,
                              const CollisionRequest& request, CollisionResult& result)
   {
-    return details::orientedBVHShapeCollide<MeshShapeCollisionTraversalNodeRSS<T_SH, GJKSolver>, RSS, T_SH, GJKSolver>(o1, tf1, o2, tf2, nsolver, request, result);
+    return details::orientedBVHShapeCollide<MeshShapeCollisionTraversalNodeRSS<T_SH>, RSS, T_SH>(o1, tf1, o2, tf2, nsolver, request, result);
   } 
 };
 
 
-template<typename T_SH, typename GJKSolver>
-struct BVHShapeCollider<kIOS, T_SH, GJKSolver>
+template<typename T_SH>
+struct BVHShapeCollider<kIOS, T_SH>
 {
   static std::size_t collide(const CollisionGeometry* o1, const Transform3f& tf1, const CollisionGeometry* o2, const Transform3f& tf2, 
                              const GJKSolver* nsolver,
                              const CollisionRequest& request, CollisionResult& result)
   {
-    return details::orientedBVHShapeCollide<MeshShapeCollisionTraversalNodekIOS<T_SH, GJKSolver>, kIOS, T_SH, GJKSolver>(o1, tf1, o2, tf2, nsolver, request, result);
+    return details::orientedBVHShapeCollide<MeshShapeCollisionTraversalNodekIOS<T_SH>, kIOS, T_SH>(o1, tf1, o2, tf2, nsolver, request, result);
   } 
 };
 
 
-template<typename T_SH, typename GJKSolver>
-struct BVHShapeCollider<OBBRSS, T_SH, GJKSolver>
+template<typename T_SH>
+struct BVHShapeCollider<OBBRSS, T_SH>
 {
   static std::size_t collide(const CollisionGeometry* o1, const Transform3f& tf1, const CollisionGeometry* o2, const Transform3f& tf2, 
                              const GJKSolver* nsolver,
                              const CollisionRequest& request, CollisionResult& result)
   {
-    return details::orientedBVHShapeCollide<MeshShapeCollisionTraversalNodeOBBRSS<T_SH, GJKSolver>, OBBRSS, T_SH, GJKSolver>(o1, tf1, o2, tf2, nsolver, request, result);
+    return details::orientedBVHShapeCollide<MeshShapeCollisionTraversalNodeOBBRSS<T_SH>, OBBRSS, T_SH>(o1, tf1, o2, tf2, nsolver, request, result);
   } 
 };
 
@@ -333,7 +332,7 @@ std::size_t BVHCollide<kIOS>(const CollisionGeometry* o1, const Transform3f& tf1
 }
 
 
-template<typename T_BVH, typename GJKSolver>
+template<typename T_BVH>
 std::size_t BVHCollide(const CollisionGeometry* o1, const Transform3f& tf1, const CollisionGeometry* o2, const Transform3f& tf2, 
                        const GJKSolver* /*nsolver*/,
                        const CollisionRequest& request, CollisionResult& result)
@@ -342,8 +341,7 @@ std::size_t BVHCollide(const CollisionGeometry* o1, const Transform3f& tf1, cons
 }
 
 
-template<typename GJKSolver>
-CollisionFunctionMatrix<GJKSolver>::CollisionFunctionMatrix()
+CollisionFunctionMatrix::CollisionFunctionMatrix()
 {
   for(int i = 0; i < NODE_COUNT; ++i)
   {
@@ -351,200 +349,200 @@ CollisionFunctionMatrix<GJKSolver>::CollisionFunctionMatrix()
       collision_matrix[i][j] = NULL;
   }
 
-  collision_matrix[GEOM_BOX][GEOM_BOX] = &ShapeShapeCollide<Box, Box, GJKSolver>;
-  collision_matrix[GEOM_BOX][GEOM_SPHERE] = &ShapeShapeCollide<Box, Sphere, GJKSolver>;
-  collision_matrix[GEOM_BOX][GEOM_CAPSULE] = &ShapeShapeCollide<Box, Capsule, GJKSolver>;
-  collision_matrix[GEOM_BOX][GEOM_CONE] = &ShapeShapeCollide<Box, Cone, GJKSolver>;
-  collision_matrix[GEOM_BOX][GEOM_CYLINDER] = &ShapeShapeCollide<Box, Cylinder, GJKSolver>;
-  collision_matrix[GEOM_BOX][GEOM_CONVEX] = &ShapeShapeCollide<Box, Convex, GJKSolver>;
-  collision_matrix[GEOM_BOX][GEOM_PLANE] = &ShapeShapeCollide<Box, Plane, GJKSolver>;
-  collision_matrix[GEOM_BOX][GEOM_HALFSPACE] = &ShapeShapeCollide<Box, Halfspace, GJKSolver>;
-
-  collision_matrix[GEOM_SPHERE][GEOM_BOX] = &ShapeShapeCollide<Sphere, Box, GJKSolver>;
-  collision_matrix[GEOM_SPHERE][GEOM_SPHERE] = &ShapeShapeCollide<Sphere, Sphere, GJKSolver>;
-  collision_matrix[GEOM_SPHERE][GEOM_CAPSULE] = &ShapeShapeCollide<Sphere, Capsule, GJKSolver>;
-  collision_matrix[GEOM_SPHERE][GEOM_CONE] = &ShapeShapeCollide<Sphere, Cone, GJKSolver>;
-  collision_matrix[GEOM_SPHERE][GEOM_CYLINDER] = &ShapeShapeCollide<Sphere, Cylinder, GJKSolver>;
-  collision_matrix[GEOM_SPHERE][GEOM_CONVEX] = &ShapeShapeCollide<Sphere, Convex, GJKSolver>;
-  collision_matrix[GEOM_SPHERE][GEOM_PLANE] = &ShapeShapeCollide<Sphere, Plane, GJKSolver>;
-  collision_matrix[GEOM_SPHERE][GEOM_HALFSPACE] = &ShapeShapeCollide<Sphere, Halfspace, GJKSolver>;
-
-  collision_matrix[GEOM_CAPSULE][GEOM_BOX] = &ShapeShapeCollide<Capsule, Box, GJKSolver>;
-  collision_matrix[GEOM_CAPSULE][GEOM_SPHERE] = &ShapeShapeCollide<Capsule, Sphere, GJKSolver>;
-  collision_matrix[GEOM_CAPSULE][GEOM_CAPSULE] = &ShapeShapeCollide<Capsule, Capsule, GJKSolver>;
-  collision_matrix[GEOM_CAPSULE][GEOM_CONE] = &ShapeShapeCollide<Capsule, Cone, GJKSolver>;
-  collision_matrix[GEOM_CAPSULE][GEOM_CYLINDER] = &ShapeShapeCollide<Capsule, Cylinder, GJKSolver>;
-  collision_matrix[GEOM_CAPSULE][GEOM_CONVEX] = &ShapeShapeCollide<Capsule, Convex, GJKSolver>;
-  collision_matrix[GEOM_CAPSULE][GEOM_PLANE] = &ShapeShapeCollide<Capsule, Plane, GJKSolver>;
-  collision_matrix[GEOM_CAPSULE][GEOM_HALFSPACE] = &ShapeShapeCollide<Capsule, Halfspace, GJKSolver>;
-
-  collision_matrix[GEOM_CONE][GEOM_BOX] = &ShapeShapeCollide<Cone, Box, GJKSolver>;
-  collision_matrix[GEOM_CONE][GEOM_SPHERE] = &ShapeShapeCollide<Cone, Sphere, GJKSolver>;
-  collision_matrix[GEOM_CONE][GEOM_CAPSULE] = &ShapeShapeCollide<Cone, Capsule, GJKSolver>;
-  collision_matrix[GEOM_CONE][GEOM_CONE] = &ShapeShapeCollide<Cone, Cone, GJKSolver>;
-  collision_matrix[GEOM_CONE][GEOM_CYLINDER] = &ShapeShapeCollide<Cone, Cylinder, GJKSolver>;
-  collision_matrix[GEOM_CONE][GEOM_CONVEX] = &ShapeShapeCollide<Cone, Convex, GJKSolver>;
-  collision_matrix[GEOM_CONE][GEOM_PLANE] = &ShapeShapeCollide<Cone, Plane, GJKSolver>;
-  collision_matrix[GEOM_CONE][GEOM_HALFSPACE] = &ShapeShapeCollide<Cone, Halfspace, GJKSolver>;
-
-  collision_matrix[GEOM_CYLINDER][GEOM_BOX] = &ShapeShapeCollide<Cylinder, Box, GJKSolver>;
-  collision_matrix[GEOM_CYLINDER][GEOM_SPHERE] = &ShapeShapeCollide<Cylinder, Sphere, GJKSolver>;
-  collision_matrix[GEOM_CYLINDER][GEOM_CAPSULE] = &ShapeShapeCollide<Cylinder, Capsule, GJKSolver>;
-  collision_matrix[GEOM_CYLINDER][GEOM_CONE] = &ShapeShapeCollide<Cylinder, Cone, GJKSolver>;
-  collision_matrix[GEOM_CYLINDER][GEOM_CYLINDER] = &ShapeShapeCollide<Cylinder, Cylinder, GJKSolver>;
-  collision_matrix[GEOM_CYLINDER][GEOM_CONVEX] = &ShapeShapeCollide<Cylinder, Convex, GJKSolver>;
-  collision_matrix[GEOM_CYLINDER][GEOM_PLANE] = &ShapeShapeCollide<Cylinder, Plane, GJKSolver>;
-  collision_matrix[GEOM_CYLINDER][GEOM_HALFSPACE] = &ShapeShapeCollide<Cylinder, Halfspace, GJKSolver>;
-
-  collision_matrix[GEOM_CONVEX][GEOM_BOX] = &ShapeShapeCollide<Convex, Box, GJKSolver>;
-  collision_matrix[GEOM_CONVEX][GEOM_SPHERE] = &ShapeShapeCollide<Convex, Sphere, GJKSolver>;
-  collision_matrix[GEOM_CONVEX][GEOM_CAPSULE] = &ShapeShapeCollide<Convex, Capsule, GJKSolver>;
-  collision_matrix[GEOM_CONVEX][GEOM_CONE] = &ShapeShapeCollide<Convex, Cone, GJKSolver>;
-  collision_matrix[GEOM_CONVEX][GEOM_CYLINDER] = &ShapeShapeCollide<Convex, Cylinder, GJKSolver>;
-  collision_matrix[GEOM_CONVEX][GEOM_CONVEX] = &ShapeShapeCollide<Convex, Convex, GJKSolver>;
-  collision_matrix[GEOM_CONVEX][GEOM_PLANE] = &ShapeShapeCollide<Convex, Plane, GJKSolver>;
-  collision_matrix[GEOM_CONVEX][GEOM_HALFSPACE] = &ShapeShapeCollide<Convex, Halfspace, GJKSolver>;
-
-  collision_matrix[GEOM_PLANE][GEOM_BOX] = &ShapeShapeCollide<Plane, Box, GJKSolver>;
-  collision_matrix[GEOM_PLANE][GEOM_SPHERE] = &ShapeShapeCollide<Plane, Sphere, GJKSolver>;
-  collision_matrix[GEOM_PLANE][GEOM_CAPSULE] = &ShapeShapeCollide<Plane, Capsule, GJKSolver>;
-  collision_matrix[GEOM_PLANE][GEOM_CONE] = &ShapeShapeCollide<Plane, Cone, GJKSolver>;
-  collision_matrix[GEOM_PLANE][GEOM_CYLINDER] = &ShapeShapeCollide<Plane, Cylinder, GJKSolver>;
-  collision_matrix[GEOM_PLANE][GEOM_CONVEX] = &ShapeShapeCollide<Plane, Convex, GJKSolver>;
-  collision_matrix[GEOM_PLANE][GEOM_PLANE] = &ShapeShapeCollide<Plane, Plane, GJKSolver>;
-  collision_matrix[GEOM_PLANE][GEOM_HALFSPACE] = &ShapeShapeCollide<Plane, Halfspace, GJKSolver>;
-
-  collision_matrix[GEOM_HALFSPACE][GEOM_BOX] = &ShapeShapeCollide<Halfspace, Box, GJKSolver>;
-  collision_matrix[GEOM_HALFSPACE][GEOM_SPHERE] = &ShapeShapeCollide<Halfspace, Sphere, GJKSolver>;
-  collision_matrix[GEOM_HALFSPACE][GEOM_CAPSULE] = &ShapeShapeCollide<Halfspace, Capsule, GJKSolver>;
-  collision_matrix[GEOM_HALFSPACE][GEOM_CONE] = &ShapeShapeCollide<Halfspace, Cone, GJKSolver>;
-  collision_matrix[GEOM_HALFSPACE][GEOM_CYLINDER] = &ShapeShapeCollide<Halfspace, Cylinder, GJKSolver>;
-  collision_matrix[GEOM_HALFSPACE][GEOM_CONVEX] = &ShapeShapeCollide<Halfspace, Convex, GJKSolver>;
-  collision_matrix[GEOM_HALFSPACE][GEOM_PLANE] = &ShapeShapeCollide<Halfspace, Plane, GJKSolver>;
-  collision_matrix[GEOM_HALFSPACE][GEOM_HALFSPACE] = &ShapeShapeCollide<Halfspace, Halfspace, GJKSolver>;
-
-  collision_matrix[BV_AABB][GEOM_BOX] = &BVHShapeCollider<AABB, Box, GJKSolver>::collide;
-  collision_matrix[BV_AABB][GEOM_SPHERE] = &BVHShapeCollider<AABB, Sphere, GJKSolver>::collide;
-  collision_matrix[BV_AABB][GEOM_CAPSULE] = &BVHShapeCollider<AABB, Capsule, GJKSolver>::collide;
-  collision_matrix[BV_AABB][GEOM_CONE] = &BVHShapeCollider<AABB, Cone, GJKSolver>::collide;
-  collision_matrix[BV_AABB][GEOM_CYLINDER] = &BVHShapeCollider<AABB, Cylinder, GJKSolver>::collide;
-  collision_matrix[BV_AABB][GEOM_CONVEX] = &BVHShapeCollider<AABB, Convex, GJKSolver>::collide;
-  collision_matrix[BV_AABB][GEOM_PLANE] = &BVHShapeCollider<AABB, Plane, GJKSolver>::collide;
-  collision_matrix[BV_AABB][GEOM_HALFSPACE] = &BVHShapeCollider<AABB, Halfspace, GJKSolver>::collide;
-
-  collision_matrix[BV_OBB][GEOM_BOX] = &BVHShapeCollider<OBB, Box, GJKSolver>::collide;
-  collision_matrix[BV_OBB][GEOM_SPHERE] = &BVHShapeCollider<OBB, Sphere, GJKSolver>::collide;
-  collision_matrix[BV_OBB][GEOM_CAPSULE] = &BVHShapeCollider<OBB, Capsule, GJKSolver>::collide;
-  collision_matrix[BV_OBB][GEOM_CONE] = &BVHShapeCollider<OBB, Cone, GJKSolver>::collide;
-  collision_matrix[BV_OBB][GEOM_CYLINDER] = &BVHShapeCollider<OBB, Cylinder, GJKSolver>::collide;
-  collision_matrix[BV_OBB][GEOM_CONVEX] = &BVHShapeCollider<OBB, Convex, GJKSolver>::collide;
-  collision_matrix[BV_OBB][GEOM_PLANE] = &BVHShapeCollider<OBB, Plane, GJKSolver>::collide;
-  collision_matrix[BV_OBB][GEOM_HALFSPACE] = &BVHShapeCollider<OBB, Halfspace, GJKSolver>::collide;
-
-  collision_matrix[BV_RSS][GEOM_BOX] = &BVHShapeCollider<RSS, Box, GJKSolver>::collide;
-  collision_matrix[BV_RSS][GEOM_SPHERE] = &BVHShapeCollider<RSS, Sphere, GJKSolver>::collide;
-  collision_matrix[BV_RSS][GEOM_CAPSULE] = &BVHShapeCollider<RSS, Capsule, GJKSolver>::collide;
-  collision_matrix[BV_RSS][GEOM_CONE] = &BVHShapeCollider<RSS, Cone, GJKSolver>::collide;
-  collision_matrix[BV_RSS][GEOM_CYLINDER] = &BVHShapeCollider<RSS, Cylinder, GJKSolver>::collide;
-  collision_matrix[BV_RSS][GEOM_CONVEX] = &BVHShapeCollider<RSS, Convex, GJKSolver>::collide;
-  collision_matrix[BV_RSS][GEOM_PLANE] = &BVHShapeCollider<RSS, Plane, GJKSolver>::collide;
-  collision_matrix[BV_RSS][GEOM_HALFSPACE] = &BVHShapeCollider<RSS, Halfspace, GJKSolver>::collide;
-
-  collision_matrix[BV_KDOP16][GEOM_BOX] = &BVHShapeCollider<KDOP<16>, Box, GJKSolver>::collide;
-  collision_matrix[BV_KDOP16][GEOM_SPHERE] = &BVHShapeCollider<KDOP<16>, Sphere, GJKSolver>::collide;
-  collision_matrix[BV_KDOP16][GEOM_CAPSULE] = &BVHShapeCollider<KDOP<16>, Capsule, GJKSolver>::collide;
-  collision_matrix[BV_KDOP16][GEOM_CONE] = &BVHShapeCollider<KDOP<16>, Cone, GJKSolver>::collide;
-  collision_matrix[BV_KDOP16][GEOM_CYLINDER] = &BVHShapeCollider<KDOP<16>, Cylinder, GJKSolver>::collide;
-  collision_matrix[BV_KDOP16][GEOM_CONVEX] = &BVHShapeCollider<KDOP<16>, Convex, GJKSolver>::collide;
-  collision_matrix[BV_KDOP16][GEOM_PLANE] = &BVHShapeCollider<KDOP<16>, Plane, GJKSolver>::collide;
-  collision_matrix[BV_KDOP16][GEOM_HALFSPACE] = &BVHShapeCollider<KDOP<16>, Halfspace, GJKSolver>::collide;
-
-  collision_matrix[BV_KDOP18][GEOM_BOX] = &BVHShapeCollider<KDOP<18>, Box, GJKSolver>::collide;
-  collision_matrix[BV_KDOP18][GEOM_SPHERE] = &BVHShapeCollider<KDOP<18>, Sphere, GJKSolver>::collide;
-  collision_matrix[BV_KDOP18][GEOM_CAPSULE] = &BVHShapeCollider<KDOP<18>, Capsule, GJKSolver>::collide;
-  collision_matrix[BV_KDOP18][GEOM_CONE] = &BVHShapeCollider<KDOP<18>, Cone, GJKSolver>::collide;
-  collision_matrix[BV_KDOP18][GEOM_CYLINDER] = &BVHShapeCollider<KDOP<18>, Cylinder, GJKSolver>::collide;
-  collision_matrix[BV_KDOP18][GEOM_CONVEX] = &BVHShapeCollider<KDOP<18>, Convex, GJKSolver>::collide;
-  collision_matrix[BV_KDOP18][GEOM_PLANE] = &BVHShapeCollider<KDOP<18>, Plane, GJKSolver>::collide;
-  collision_matrix[BV_KDOP18][GEOM_HALFSPACE] = &BVHShapeCollider<KDOP<18>, Halfspace, GJKSolver>::collide;
-
-  collision_matrix[BV_KDOP24][GEOM_BOX] = &BVHShapeCollider<KDOP<24>, Box, GJKSolver>::collide;
-  collision_matrix[BV_KDOP24][GEOM_SPHERE] = &BVHShapeCollider<KDOP<24>, Sphere, GJKSolver>::collide;
-  collision_matrix[BV_KDOP24][GEOM_CAPSULE] = &BVHShapeCollider<KDOP<24>, Capsule, GJKSolver>::collide;
-  collision_matrix[BV_KDOP24][GEOM_CONE] = &BVHShapeCollider<KDOP<24>, Cone, GJKSolver>::collide;
-  collision_matrix[BV_KDOP24][GEOM_CYLINDER] = &BVHShapeCollider<KDOP<24>, Cylinder, GJKSolver>::collide;
-  collision_matrix[BV_KDOP24][GEOM_CONVEX] = &BVHShapeCollider<KDOP<24>, Convex, GJKSolver>::collide;
-  collision_matrix[BV_KDOP24][GEOM_PLANE] = &BVHShapeCollider<KDOP<24>, Plane, GJKSolver>::collide;
-  collision_matrix[BV_KDOP24][GEOM_HALFSPACE] = &BVHShapeCollider<KDOP<24>, Halfspace, GJKSolver>::collide;
-
-  collision_matrix[BV_kIOS][GEOM_BOX] = &BVHShapeCollider<kIOS, Box, GJKSolver>::collide;
-  collision_matrix[BV_kIOS][GEOM_SPHERE] = &BVHShapeCollider<kIOS, Sphere, GJKSolver>::collide;
-  collision_matrix[BV_kIOS][GEOM_CAPSULE] = &BVHShapeCollider<kIOS, Capsule, GJKSolver>::collide;
-  collision_matrix[BV_kIOS][GEOM_CONE] = &BVHShapeCollider<kIOS, Cone, GJKSolver>::collide;
-  collision_matrix[BV_kIOS][GEOM_CYLINDER] = &BVHShapeCollider<kIOS, Cylinder, GJKSolver>::collide;
-  collision_matrix[BV_kIOS][GEOM_CONVEX] = &BVHShapeCollider<kIOS, Convex, GJKSolver>::collide;
-  collision_matrix[BV_kIOS][GEOM_PLANE] = &BVHShapeCollider<kIOS, Plane, GJKSolver>::collide;
-  collision_matrix[BV_kIOS][GEOM_HALFSPACE] = &BVHShapeCollider<kIOS, Halfspace, GJKSolver>::collide;
-
-  collision_matrix[BV_OBBRSS][GEOM_BOX] = &BVHShapeCollider<OBBRSS, Box, GJKSolver>::collide;
-  collision_matrix[BV_OBBRSS][GEOM_SPHERE] = &BVHShapeCollider<OBBRSS, Sphere, GJKSolver>::collide;
-  collision_matrix[BV_OBBRSS][GEOM_CAPSULE] = &BVHShapeCollider<OBBRSS, Capsule, GJKSolver>::collide;
-  collision_matrix[BV_OBBRSS][GEOM_CONE] = &BVHShapeCollider<OBBRSS, Cone, GJKSolver>::collide;
-  collision_matrix[BV_OBBRSS][GEOM_CYLINDER] = &BVHShapeCollider<OBBRSS, Cylinder, GJKSolver>::collide;
-  collision_matrix[BV_OBBRSS][GEOM_CONVEX] = &BVHShapeCollider<OBBRSS, Convex, GJKSolver>::collide;
-  collision_matrix[BV_OBBRSS][GEOM_PLANE] = &BVHShapeCollider<OBBRSS, Plane, GJKSolver>::collide;
-  collision_matrix[BV_OBBRSS][GEOM_HALFSPACE] = &BVHShapeCollider<OBBRSS, Halfspace, GJKSolver>::collide;
-
-  collision_matrix[BV_AABB][BV_AABB] = &BVHCollide<AABB, GJKSolver>;
-  collision_matrix[BV_OBB][BV_OBB] = &BVHCollide<OBB, GJKSolver>;
-  collision_matrix[BV_RSS][BV_RSS] = &BVHCollide<RSS, GJKSolver>;
-  collision_matrix[BV_KDOP16][BV_KDOP16] = &BVHCollide<KDOP<16>, GJKSolver>;
-  collision_matrix[BV_KDOP18][BV_KDOP18] = &BVHCollide<KDOP<18>, GJKSolver>;
-  collision_matrix[BV_KDOP24][BV_KDOP24] = &BVHCollide<KDOP<24>, GJKSolver>;
-  collision_matrix[BV_kIOS][BV_kIOS] = &BVHCollide<kIOS, GJKSolver>;
-  collision_matrix[BV_OBBRSS][BV_OBBRSS] = &BVHCollide<OBBRSS, GJKSolver>;
+  collision_matrix[GEOM_BOX][GEOM_BOX] = &ShapeShapeCollide<Box, Box>;
+  collision_matrix[GEOM_BOX][GEOM_SPHERE] = &ShapeShapeCollide<Box, Sphere>;
+  collision_matrix[GEOM_BOX][GEOM_CAPSULE] = &ShapeShapeCollide<Box, Capsule>;
+  collision_matrix[GEOM_BOX][GEOM_CONE] = &ShapeShapeCollide<Box, Cone>;
+  collision_matrix[GEOM_BOX][GEOM_CYLINDER] = &ShapeShapeCollide<Box, Cylinder>;
+  collision_matrix[GEOM_BOX][GEOM_CONVEX] = &ShapeShapeCollide<Box, Convex>;
+  collision_matrix[GEOM_BOX][GEOM_PLANE] = &ShapeShapeCollide<Box, Plane>;
+  collision_matrix[GEOM_BOX][GEOM_HALFSPACE] = &ShapeShapeCollide<Box, Halfspace>;
+
+  collision_matrix[GEOM_SPHERE][GEOM_BOX] = &ShapeShapeCollide<Sphere, Box>;
+  collision_matrix[GEOM_SPHERE][GEOM_SPHERE] = &ShapeShapeCollide<Sphere, Sphere>;
+  collision_matrix[GEOM_SPHERE][GEOM_CAPSULE] = &ShapeShapeCollide<Sphere, Capsule>;
+  collision_matrix[GEOM_SPHERE][GEOM_CONE] = &ShapeShapeCollide<Sphere, Cone>;
+  collision_matrix[GEOM_SPHERE][GEOM_CYLINDER] = &ShapeShapeCollide<Sphere, Cylinder>;
+  collision_matrix[GEOM_SPHERE][GEOM_CONVEX] = &ShapeShapeCollide<Sphere, Convex>;
+  collision_matrix[GEOM_SPHERE][GEOM_PLANE] = &ShapeShapeCollide<Sphere, Plane>;
+  collision_matrix[GEOM_SPHERE][GEOM_HALFSPACE] = &ShapeShapeCollide<Sphere, Halfspace>;
+
+  collision_matrix[GEOM_CAPSULE][GEOM_BOX] = &ShapeShapeCollide<Capsule, Box>;
+  collision_matrix[GEOM_CAPSULE][GEOM_SPHERE] = &ShapeShapeCollide<Capsule, Sphere>;
+  collision_matrix[GEOM_CAPSULE][GEOM_CAPSULE] = &ShapeShapeCollide<Capsule, Capsule>;
+  collision_matrix[GEOM_CAPSULE][GEOM_CONE] = &ShapeShapeCollide<Capsule, Cone>;
+  collision_matrix[GEOM_CAPSULE][GEOM_CYLINDER] = &ShapeShapeCollide<Capsule, Cylinder>;
+  collision_matrix[GEOM_CAPSULE][GEOM_CONVEX] = &ShapeShapeCollide<Capsule, Convex>;
+  collision_matrix[GEOM_CAPSULE][GEOM_PLANE] = &ShapeShapeCollide<Capsule, Plane>;
+  collision_matrix[GEOM_CAPSULE][GEOM_HALFSPACE] = &ShapeShapeCollide<Capsule, Halfspace>;
+
+  collision_matrix[GEOM_CONE][GEOM_BOX] = &ShapeShapeCollide<Cone, Box>;
+  collision_matrix[GEOM_CONE][GEOM_SPHERE] = &ShapeShapeCollide<Cone, Sphere>;
+  collision_matrix[GEOM_CONE][GEOM_CAPSULE] = &ShapeShapeCollide<Cone, Capsule>;
+  collision_matrix[GEOM_CONE][GEOM_CONE] = &ShapeShapeCollide<Cone, Cone>;
+  collision_matrix[GEOM_CONE][GEOM_CYLINDER] = &ShapeShapeCollide<Cone, Cylinder>;
+  collision_matrix[GEOM_CONE][GEOM_CONVEX] = &ShapeShapeCollide<Cone, Convex>;
+  collision_matrix[GEOM_CONE][GEOM_PLANE] = &ShapeShapeCollide<Cone, Plane>;
+  collision_matrix[GEOM_CONE][GEOM_HALFSPACE] = &ShapeShapeCollide<Cone, Halfspace>;
+
+  collision_matrix[GEOM_CYLINDER][GEOM_BOX] = &ShapeShapeCollide<Cylinder, Box>;
+  collision_matrix[GEOM_CYLINDER][GEOM_SPHERE] = &ShapeShapeCollide<Cylinder, Sphere>;
+  collision_matrix[GEOM_CYLINDER][GEOM_CAPSULE] = &ShapeShapeCollide<Cylinder, Capsule>;
+  collision_matrix[GEOM_CYLINDER][GEOM_CONE] = &ShapeShapeCollide<Cylinder, Cone>;
+  collision_matrix[GEOM_CYLINDER][GEOM_CYLINDER] = &ShapeShapeCollide<Cylinder, Cylinder>;
+  collision_matrix[GEOM_CYLINDER][GEOM_CONVEX] = &ShapeShapeCollide<Cylinder, Convex>;
+  collision_matrix[GEOM_CYLINDER][GEOM_PLANE] = &ShapeShapeCollide<Cylinder, Plane>;
+  collision_matrix[GEOM_CYLINDER][GEOM_HALFSPACE] = &ShapeShapeCollide<Cylinder, Halfspace>;
+
+  collision_matrix[GEOM_CONVEX][GEOM_BOX] = &ShapeShapeCollide<Convex, Box>;
+  collision_matrix[GEOM_CONVEX][GEOM_SPHERE] = &ShapeShapeCollide<Convex, Sphere>;
+  collision_matrix[GEOM_CONVEX][GEOM_CAPSULE] = &ShapeShapeCollide<Convex, Capsule>;
+  collision_matrix[GEOM_CONVEX][GEOM_CONE] = &ShapeShapeCollide<Convex, Cone>;
+  collision_matrix[GEOM_CONVEX][GEOM_CYLINDER] = &ShapeShapeCollide<Convex, Cylinder>;
+  collision_matrix[GEOM_CONVEX][GEOM_CONVEX] = &ShapeShapeCollide<Convex, Convex>;
+  collision_matrix[GEOM_CONVEX][GEOM_PLANE] = &ShapeShapeCollide<Convex, Plane>;
+  collision_matrix[GEOM_CONVEX][GEOM_HALFSPACE] = &ShapeShapeCollide<Convex, Halfspace>;
+
+  collision_matrix[GEOM_PLANE][GEOM_BOX] = &ShapeShapeCollide<Plane, Box>;
+  collision_matrix[GEOM_PLANE][GEOM_SPHERE] = &ShapeShapeCollide<Plane, Sphere>;
+  collision_matrix[GEOM_PLANE][GEOM_CAPSULE] = &ShapeShapeCollide<Plane, Capsule>;
+  collision_matrix[GEOM_PLANE][GEOM_CONE] = &ShapeShapeCollide<Plane, Cone>;
+  collision_matrix[GEOM_PLANE][GEOM_CYLINDER] = &ShapeShapeCollide<Plane, Cylinder>;
+  collision_matrix[GEOM_PLANE][GEOM_CONVEX] = &ShapeShapeCollide<Plane, Convex>;
+  collision_matrix[GEOM_PLANE][GEOM_PLANE] = &ShapeShapeCollide<Plane, Plane>;
+  collision_matrix[GEOM_PLANE][GEOM_HALFSPACE] = &ShapeShapeCollide<Plane, Halfspace>;
+
+  collision_matrix[GEOM_HALFSPACE][GEOM_BOX] = &ShapeShapeCollide<Halfspace, Box>;
+  collision_matrix[GEOM_HALFSPACE][GEOM_SPHERE] = &ShapeShapeCollide<Halfspace, Sphere>;
+  collision_matrix[GEOM_HALFSPACE][GEOM_CAPSULE] = &ShapeShapeCollide<Halfspace, Capsule>;
+  collision_matrix[GEOM_HALFSPACE][GEOM_CONE] = &ShapeShapeCollide<Halfspace, Cone>;
+  collision_matrix[GEOM_HALFSPACE][GEOM_CYLINDER] = &ShapeShapeCollide<Halfspace, Cylinder>;
+  collision_matrix[GEOM_HALFSPACE][GEOM_CONVEX] = &ShapeShapeCollide<Halfspace, Convex>;
+  collision_matrix[GEOM_HALFSPACE][GEOM_PLANE] = &ShapeShapeCollide<Halfspace, Plane>;
+  collision_matrix[GEOM_HALFSPACE][GEOM_HALFSPACE] = &ShapeShapeCollide<Halfspace, Halfspace>;
+
+  collision_matrix[BV_AABB][GEOM_BOX] = &BVHShapeCollider<AABB, Box>::collide;
+  collision_matrix[BV_AABB][GEOM_SPHERE] = &BVHShapeCollider<AABB, Sphere>::collide;
+  collision_matrix[BV_AABB][GEOM_CAPSULE] = &BVHShapeCollider<AABB, Capsule>::collide;
+  collision_matrix[BV_AABB][GEOM_CONE] = &BVHShapeCollider<AABB, Cone>::collide;
+  collision_matrix[BV_AABB][GEOM_CYLINDER] = &BVHShapeCollider<AABB, Cylinder>::collide;
+  collision_matrix[BV_AABB][GEOM_CONVEX] = &BVHShapeCollider<AABB, Convex>::collide;
+  collision_matrix[BV_AABB][GEOM_PLANE] = &BVHShapeCollider<AABB, Plane>::collide;
+  collision_matrix[BV_AABB][GEOM_HALFSPACE] = &BVHShapeCollider<AABB, Halfspace>::collide;
+
+  collision_matrix[BV_OBB][GEOM_BOX] = &BVHShapeCollider<OBB, Box>::collide;
+  collision_matrix[BV_OBB][GEOM_SPHERE] = &BVHShapeCollider<OBB, Sphere>::collide;
+  collision_matrix[BV_OBB][GEOM_CAPSULE] = &BVHShapeCollider<OBB, Capsule>::collide;
+  collision_matrix[BV_OBB][GEOM_CONE] = &BVHShapeCollider<OBB, Cone>::collide;
+  collision_matrix[BV_OBB][GEOM_CYLINDER] = &BVHShapeCollider<OBB, Cylinder>::collide;
+  collision_matrix[BV_OBB][GEOM_CONVEX] = &BVHShapeCollider<OBB, Convex>::collide;
+  collision_matrix[BV_OBB][GEOM_PLANE] = &BVHShapeCollider<OBB, Plane>::collide;
+  collision_matrix[BV_OBB][GEOM_HALFSPACE] = &BVHShapeCollider<OBB, Halfspace>::collide;
+
+  collision_matrix[BV_RSS][GEOM_BOX] = &BVHShapeCollider<RSS, Box>::collide;
+  collision_matrix[BV_RSS][GEOM_SPHERE] = &BVHShapeCollider<RSS, Sphere>::collide;
+  collision_matrix[BV_RSS][GEOM_CAPSULE] = &BVHShapeCollider<RSS, Capsule>::collide;
+  collision_matrix[BV_RSS][GEOM_CONE] = &BVHShapeCollider<RSS, Cone>::collide;
+  collision_matrix[BV_RSS][GEOM_CYLINDER] = &BVHShapeCollider<RSS, Cylinder>::collide;
+  collision_matrix[BV_RSS][GEOM_CONVEX] = &BVHShapeCollider<RSS, Convex>::collide;
+  collision_matrix[BV_RSS][GEOM_PLANE] = &BVHShapeCollider<RSS, Plane>::collide;
+  collision_matrix[BV_RSS][GEOM_HALFSPACE] = &BVHShapeCollider<RSS, Halfspace>::collide;
+
+  collision_matrix[BV_KDOP16][GEOM_BOX] = &BVHShapeCollider<KDOP<16>, Box>::collide;
+  collision_matrix[BV_KDOP16][GEOM_SPHERE] = &BVHShapeCollider<KDOP<16>, Sphere>::collide;
+  collision_matrix[BV_KDOP16][GEOM_CAPSULE] = &BVHShapeCollider<KDOP<16>, Capsule>::collide;
+  collision_matrix[BV_KDOP16][GEOM_CONE] = &BVHShapeCollider<KDOP<16>, Cone>::collide;
+  collision_matrix[BV_KDOP16][GEOM_CYLINDER] = &BVHShapeCollider<KDOP<16>, Cylinder>::collide;
+  collision_matrix[BV_KDOP16][GEOM_CONVEX] = &BVHShapeCollider<KDOP<16>, Convex>::collide;
+  collision_matrix[BV_KDOP16][GEOM_PLANE] = &BVHShapeCollider<KDOP<16>, Plane>::collide;
+  collision_matrix[BV_KDOP16][GEOM_HALFSPACE] = &BVHShapeCollider<KDOP<16>, Halfspace>::collide;
+
+  collision_matrix[BV_KDOP18][GEOM_BOX] = &BVHShapeCollider<KDOP<18>, Box>::collide;
+  collision_matrix[BV_KDOP18][GEOM_SPHERE] = &BVHShapeCollider<KDOP<18>, Sphere>::collide;
+  collision_matrix[BV_KDOP18][GEOM_CAPSULE] = &BVHShapeCollider<KDOP<18>, Capsule>::collide;
+  collision_matrix[BV_KDOP18][GEOM_CONE] = &BVHShapeCollider<KDOP<18>, Cone>::collide;
+  collision_matrix[BV_KDOP18][GEOM_CYLINDER] = &BVHShapeCollider<KDOP<18>, Cylinder>::collide;
+  collision_matrix[BV_KDOP18][GEOM_CONVEX] = &BVHShapeCollider<KDOP<18>, Convex>::collide;
+  collision_matrix[BV_KDOP18][GEOM_PLANE] = &BVHShapeCollider<KDOP<18>, Plane>::collide;
+  collision_matrix[BV_KDOP18][GEOM_HALFSPACE] = &BVHShapeCollider<KDOP<18>, Halfspace>::collide;
+
+  collision_matrix[BV_KDOP24][GEOM_BOX] = &BVHShapeCollider<KDOP<24>, Box>::collide;
+  collision_matrix[BV_KDOP24][GEOM_SPHERE] = &BVHShapeCollider<KDOP<24>, Sphere>::collide;
+  collision_matrix[BV_KDOP24][GEOM_CAPSULE] = &BVHShapeCollider<KDOP<24>, Capsule>::collide;
+  collision_matrix[BV_KDOP24][GEOM_CONE] = &BVHShapeCollider<KDOP<24>, Cone>::collide;
+  collision_matrix[BV_KDOP24][GEOM_CYLINDER] = &BVHShapeCollider<KDOP<24>, Cylinder>::collide;
+  collision_matrix[BV_KDOP24][GEOM_CONVEX] = &BVHShapeCollider<KDOP<24>, Convex>::collide;
+  collision_matrix[BV_KDOP24][GEOM_PLANE] = &BVHShapeCollider<KDOP<24>, Plane>::collide;
+  collision_matrix[BV_KDOP24][GEOM_HALFSPACE] = &BVHShapeCollider<KDOP<24>, Halfspace>::collide;
+
+  collision_matrix[BV_kIOS][GEOM_BOX] = &BVHShapeCollider<kIOS, Box>::collide;
+  collision_matrix[BV_kIOS][GEOM_SPHERE] = &BVHShapeCollider<kIOS, Sphere>::collide;
+  collision_matrix[BV_kIOS][GEOM_CAPSULE] = &BVHShapeCollider<kIOS, Capsule>::collide;
+  collision_matrix[BV_kIOS][GEOM_CONE] = &BVHShapeCollider<kIOS, Cone>::collide;
+  collision_matrix[BV_kIOS][GEOM_CYLINDER] = &BVHShapeCollider<kIOS, Cylinder>::collide;
+  collision_matrix[BV_kIOS][GEOM_CONVEX] = &BVHShapeCollider<kIOS, Convex>::collide;
+  collision_matrix[BV_kIOS][GEOM_PLANE] = &BVHShapeCollider<kIOS, Plane>::collide;
+  collision_matrix[BV_kIOS][GEOM_HALFSPACE] = &BVHShapeCollider<kIOS, Halfspace>::collide;
+
+  collision_matrix[BV_OBBRSS][GEOM_BOX] = &BVHShapeCollider<OBBRSS, Box>::collide;
+  collision_matrix[BV_OBBRSS][GEOM_SPHERE] = &BVHShapeCollider<OBBRSS, Sphere>::collide;
+  collision_matrix[BV_OBBRSS][GEOM_CAPSULE] = &BVHShapeCollider<OBBRSS, Capsule>::collide;
+  collision_matrix[BV_OBBRSS][GEOM_CONE] = &BVHShapeCollider<OBBRSS, Cone>::collide;
+  collision_matrix[BV_OBBRSS][GEOM_CYLINDER] = &BVHShapeCollider<OBBRSS, Cylinder>::collide;
+  collision_matrix[BV_OBBRSS][GEOM_CONVEX] = &BVHShapeCollider<OBBRSS, Convex>::collide;
+  collision_matrix[BV_OBBRSS][GEOM_PLANE] = &BVHShapeCollider<OBBRSS, Plane>::collide;
+  collision_matrix[BV_OBBRSS][GEOM_HALFSPACE] = &BVHShapeCollider<OBBRSS, Halfspace>::collide;
+
+  collision_matrix[BV_AABB][BV_AABB] = &BVHCollide<AABB>;
+  collision_matrix[BV_OBB][BV_OBB] = &BVHCollide<OBB>;
+  collision_matrix[BV_RSS][BV_RSS] = &BVHCollide<RSS>;
+  collision_matrix[BV_KDOP16][BV_KDOP16] = &BVHCollide<KDOP<16>>;
+  collision_matrix[BV_KDOP18][BV_KDOP18] = &BVHCollide<KDOP<18>>;
+  collision_matrix[BV_KDOP24][BV_KDOP24] = &BVHCollide<KDOP<24>>;
+  collision_matrix[BV_kIOS][BV_kIOS] = &BVHCollide<kIOS>;
+  collision_matrix[BV_OBBRSS][BV_OBBRSS] = &BVHCollide<OBBRSS>;
 
 #ifdef HPP_FCL_HAVE_OCTOMAP
-  collision_matrix[GEOM_OCTREE][GEOM_BOX] = &OcTreeShapeCollide<Box, GJKSolver>;
-  collision_matrix[GEOM_OCTREE][GEOM_SPHERE] = &OcTreeShapeCollide<Sphere, GJKSolver>;
-  collision_matrix[GEOM_OCTREE][GEOM_CAPSULE] = &OcTreeShapeCollide<Capsule, GJKSolver>;
-  collision_matrix[GEOM_OCTREE][GEOM_CONE] = &OcTreeShapeCollide<Cone, GJKSolver>;
-  collision_matrix[GEOM_OCTREE][GEOM_CYLINDER] = &OcTreeShapeCollide<Cylinder, GJKSolver>;
-  collision_matrix[GEOM_OCTREE][GEOM_CONVEX] = &OcTreeShapeCollide<Convex, GJKSolver>;
-  collision_matrix[GEOM_OCTREE][GEOM_PLANE] = &OcTreeShapeCollide<Plane, GJKSolver>;
-  collision_matrix[GEOM_OCTREE][GEOM_HALFSPACE] = &OcTreeShapeCollide<Halfspace, GJKSolver>;
-
-  collision_matrix[GEOM_BOX][GEOM_OCTREE] = &ShapeOcTreeCollide<Box, GJKSolver>;
-  collision_matrix[GEOM_SPHERE][GEOM_OCTREE] = &ShapeOcTreeCollide<Sphere, GJKSolver>;
-  collision_matrix[GEOM_CAPSULE][GEOM_OCTREE] = &ShapeOcTreeCollide<Capsule, GJKSolver>;
-  collision_matrix[GEOM_CONE][GEOM_OCTREE] = &ShapeOcTreeCollide<Cone, GJKSolver>;
-  collision_matrix[GEOM_CYLINDER][GEOM_OCTREE] = &ShapeOcTreeCollide<Cylinder, GJKSolver>;
-  collision_matrix[GEOM_CONVEX][GEOM_OCTREE] = &ShapeOcTreeCollide<Convex, GJKSolver>;
-  collision_matrix[GEOM_PLANE][GEOM_OCTREE] = &ShapeOcTreeCollide<Plane, GJKSolver>;
-  collision_matrix[GEOM_HALFSPACE][GEOM_OCTREE] = &ShapeOcTreeCollide<Halfspace, GJKSolver>;
-
-  collision_matrix[GEOM_OCTREE][GEOM_OCTREE] = &OcTreeCollide<GJKSolver>;
-
-  collision_matrix[GEOM_OCTREE][BV_AABB] = &OcTreeBVHCollide<AABB, GJKSolver>;
-  collision_matrix[GEOM_OCTREE][BV_OBB] = &OcTreeBVHCollide<OBB, GJKSolver>;
-  collision_matrix[GEOM_OCTREE][BV_RSS] = &OcTreeBVHCollide<RSS, GJKSolver>;
-  collision_matrix[GEOM_OCTREE][BV_OBBRSS] = &OcTreeBVHCollide<OBBRSS, GJKSolver>;
-  collision_matrix[GEOM_OCTREE][BV_kIOS] = &OcTreeBVHCollide<kIOS, GJKSolver>;
-  collision_matrix[GEOM_OCTREE][BV_KDOP16] = &OcTreeBVHCollide<KDOP<16>, GJKSolver>;
-  collision_matrix[GEOM_OCTREE][BV_KDOP18] = &OcTreeBVHCollide<KDOP<18>, GJKSolver>;
-  collision_matrix[GEOM_OCTREE][BV_KDOP24] = &OcTreeBVHCollide<KDOP<24>, GJKSolver>;
-
-  collision_matrix[BV_AABB][GEOM_OCTREE] = &BVHOcTreeCollide<AABB, GJKSolver>;
-  collision_matrix[BV_OBB][GEOM_OCTREE] = &BVHOcTreeCollide<OBB, GJKSolver>;
-  collision_matrix[BV_RSS][GEOM_OCTREE] = &BVHOcTreeCollide<RSS, GJKSolver>;
-  collision_matrix[BV_OBBRSS][GEOM_OCTREE] = &BVHOcTreeCollide<OBBRSS, GJKSolver>;
-  collision_matrix[BV_kIOS][GEOM_OCTREE] = &BVHOcTreeCollide<kIOS, GJKSolver>;
-  collision_matrix[BV_KDOP16][GEOM_OCTREE] = &BVHOcTreeCollide<KDOP<16>, GJKSolver>;
-  collision_matrix[BV_KDOP18][GEOM_OCTREE] = &BVHOcTreeCollide<KDOP<18>, GJKSolver>;
-  collision_matrix[BV_KDOP24][GEOM_OCTREE] = &BVHOcTreeCollide<KDOP<24>, GJKSolver>;
+  collision_matrix[GEOM_OCTREE][GEOM_BOX] = &OcTreeShapeCollide<Box>;
+  collision_matrix[GEOM_OCTREE][GEOM_SPHERE] = &OcTreeShapeCollide<Sphere>;
+  collision_matrix[GEOM_OCTREE][GEOM_CAPSULE] = &OcTreeShapeCollide<Capsule>;
+  collision_matrix[GEOM_OCTREE][GEOM_CONE] = &OcTreeShapeCollide<Cone>;
+  collision_matrix[GEOM_OCTREE][GEOM_CYLINDER] = &OcTreeShapeCollide<Cylinder>;
+  collision_matrix[GEOM_OCTREE][GEOM_CONVEX] = &OcTreeShapeCollide<Convex>;
+  collision_matrix[GEOM_OCTREE][GEOM_PLANE] = &OcTreeShapeCollide<Plane>;
+  collision_matrix[GEOM_OCTREE][GEOM_HALFSPACE] = &OcTreeShapeCollide<Halfspace>;
+
+  collision_matrix[GEOM_BOX][GEOM_OCTREE] = &ShapeOcTreeCollide<Box>;
+  collision_matrix[GEOM_SPHERE][GEOM_OCTREE] = &ShapeOcTreeCollide<Sphere>;
+  collision_matrix[GEOM_CAPSULE][GEOM_OCTREE] = &ShapeOcTreeCollide<Capsule>;
+  collision_matrix[GEOM_CONE][GEOM_OCTREE] = &ShapeOcTreeCollide<Cone>;
+  collision_matrix[GEOM_CYLINDER][GEOM_OCTREE] = &ShapeOcTreeCollide<Cylinder>;
+  collision_matrix[GEOM_CONVEX][GEOM_OCTREE] = &ShapeOcTreeCollide<Convex>;
+  collision_matrix[GEOM_PLANE][GEOM_OCTREE] = &ShapeOcTreeCollide<Plane>;
+  collision_matrix[GEOM_HALFSPACE][GEOM_OCTREE] = &ShapeOcTreeCollide<Halfspace>;
+
+  collision_matrix[GEOM_OCTREE][GEOM_OCTREE] = &OcTreeCollide;
+
+  collision_matrix[GEOM_OCTREE][BV_AABB] = &OcTreeBVHCollide<AABB>;
+  collision_matrix[GEOM_OCTREE][BV_OBB] = &OcTreeBVHCollide<OBB>;
+  collision_matrix[GEOM_OCTREE][BV_RSS] = &OcTreeBVHCollide<RSS>;
+  collision_matrix[GEOM_OCTREE][BV_OBBRSS] = &OcTreeBVHCollide<OBBRSS>;
+  collision_matrix[GEOM_OCTREE][BV_kIOS] = &OcTreeBVHCollide<kIOS>;
+  collision_matrix[GEOM_OCTREE][BV_KDOP16] = &OcTreeBVHCollide<KDOP<16>>;
+  collision_matrix[GEOM_OCTREE][BV_KDOP18] = &OcTreeBVHCollide<KDOP<18>>;
+  collision_matrix[GEOM_OCTREE][BV_KDOP24] = &OcTreeBVHCollide<KDOP<24>>;
+
+  collision_matrix[BV_AABB][GEOM_OCTREE] = &BVHOcTreeCollide<AABB>;
+  collision_matrix[BV_OBB][GEOM_OCTREE] = &BVHOcTreeCollide<OBB>;
+  collision_matrix[BV_RSS][GEOM_OCTREE] = &BVHOcTreeCollide<RSS>;
+  collision_matrix[BV_OBBRSS][GEOM_OCTREE] = &BVHOcTreeCollide<OBBRSS>;
+  collision_matrix[BV_kIOS][GEOM_OCTREE] = &BVHOcTreeCollide<kIOS>;
+  collision_matrix[BV_KDOP16][GEOM_OCTREE] = &BVHOcTreeCollide<KDOP<16>>;
+  collision_matrix[BV_KDOP18][GEOM_OCTREE] = &BVHOcTreeCollide<KDOP<18>>;
+  collision_matrix[BV_KDOP24][GEOM_OCTREE] = &BVHOcTreeCollide<KDOP<24>>;
 #endif
 }
-template struct CollisionFunctionMatrix<GJKSolver>;
+//template struct CollisionFunctionMatrix;
 }
 
 } // namespace hpp
diff --git a/src/distance.cpp b/src/distance.cpp
index 41ae36ee8a122137f89d5857cbadcee2f648fbaa..a2bcd9ad169edc521b0e0f7c6aa2709f12b8d9e3 100644
--- a/src/distance.cpp
+++ b/src/distance.cpp
@@ -46,22 +46,19 @@ namespace hpp
 namespace fcl
 {
 
-template<typename GJKSolver>
-DistanceFunctionMatrix<GJKSolver>& getDistanceFunctionLookTable()
+DistanceFunctionMatrix& getDistanceFunctionLookTable()
 {
-  static DistanceFunctionMatrix<GJKSolver> table;
+  static DistanceFunctionMatrix table;
   return table;
 }
 
-template<typename GJKSolver>
 FCL_REAL distance(const CollisionObject* o1, const CollisionObject* o2, const GJKSolver* nsolver,
                   const DistanceRequest& request, DistanceResult& result)
 {
-  return distance<GJKSolver>(o1->collisionGeometry().get(), o1->getTransform(), o2->collisionGeometry().get(), o2->getTransform(), nsolver,
+  return distance(o1->collisionGeometry().get(), o1->getTransform(), o2->collisionGeometry().get(), o2->getTransform(), nsolver,
                                      request, result);
 }
 
-template<typename GJKSolver>
 FCL_REAL distance(const CollisionGeometry* o1, const Transform3f& tf1, 
                   const CollisionGeometry* o2, const Transform3f& tf2,
                   const GJKSolver* nsolver_,
@@ -71,7 +68,7 @@ FCL_REAL distance(const CollisionGeometry* o1, const Transform3f& tf1,
   if(!nsolver_) 
     nsolver = new GJKSolver();
 
-  const DistanceFunctionMatrix<GJKSolver>& looktable = getDistanceFunctionLookTable<GJKSolver>();
+  const DistanceFunctionMatrix& looktable = getDistanceFunctionLookTable();
 
   OBJECT_TYPE object_type1 = o1->getObjectType();
   NODE_TYPE node_type1 = o1->getNodeType();
@@ -126,7 +123,7 @@ FCL_REAL distance(const CollisionObject* o1, const CollisionObject* o2, const Di
   case GST_INDEP:
     {
       GJKSolver solver;
-      return distance<GJKSolver>(o1, o2, &solver, request, result);
+      return distance(o1, o2, &solver, request, result);
     }
   default:
     return -1; // error
@@ -142,7 +139,7 @@ FCL_REAL distance(const CollisionGeometry* o1, const Transform3f& tf1,
   case GST_INDEP:
     {
       GJKSolver solver;
-      return distance<GJKSolver>(o1, tf1, o2, tf2, &solver, request, result);
+      return distance(o1, tf1, o2, tf2, &solver, request, result);
     }
   default:
     return -1;
diff --git a/src/distance_box_halfspace.cpp b/src/distance_box_halfspace.cpp
index 80fc3fe265b44f5ab7c5881a61a78fea54b19662..8ad3a97db8f4c76d078c02207a5b38b20c3c2f5b 100644
--- a/src/distance_box_halfspace.cpp
+++ b/src/distance_box_halfspace.cpp
@@ -49,7 +49,7 @@ namespace fcl {
     class GJKSolver;
 
   template <>
-  FCL_REAL ShapeShapeDistance <Box, Halfspace, GJKSolver>
+  FCL_REAL ShapeShapeDistance <Box, Halfspace>
   (const CollisionGeometry* o1, const Transform3f& tf1,
    const CollisionGeometry* o2, const Transform3f& tf2,
    const GJKSolver*, const DistanceRequest&,
@@ -65,7 +65,7 @@ namespace fcl {
   }
 
   template <>
-  FCL_REAL ShapeShapeDistance <Halfspace, Box, GJKSolver>
+  FCL_REAL ShapeShapeDistance <Halfspace, Box>
   (const CollisionGeometry* o1, const Transform3f& tf1,
    const CollisionGeometry* o2, const Transform3f& tf2,
    const GJKSolver*, const DistanceRequest&,
diff --git a/src/distance_box_plane.cpp b/src/distance_box_plane.cpp
index 0c438f324b45313beb37a50274691bc3ca86bde7..1619e4876a29625f313ca760f5e6e332e158d503 100644
--- a/src/distance_box_plane.cpp
+++ b/src/distance_box_plane.cpp
@@ -49,7 +49,7 @@ namespace fcl {
     class GJKSolver;
 
   template <>
-  FCL_REAL ShapeShapeDistance <Box, Plane, GJKSolver>
+  FCL_REAL ShapeShapeDistance <Box, Plane>
   (const CollisionGeometry* o1, const Transform3f& tf1,
    const CollisionGeometry* o2, const Transform3f& tf2,
    const GJKSolver*, const DistanceRequest&,
@@ -65,7 +65,7 @@ namespace fcl {
   }
 
   template <>
-  FCL_REAL ShapeShapeDistance <Plane, Box, GJKSolver>
+  FCL_REAL ShapeShapeDistance <Plane, Box>
   (const CollisionGeometry* o1, const Transform3f& tf1,
    const CollisionGeometry* o2, const Transform3f& tf2,
    const GJKSolver*, const DistanceRequest&,
diff --git a/src/distance_box_sphere.cpp b/src/distance_box_sphere.cpp
index 6ee8870f717afaf65774f53374632d15b103c4be..553cbeb621adc522f20819fe2a0564800a9a4cc4 100644
--- a/src/distance_box_sphere.cpp
+++ b/src/distance_box_sphere.cpp
@@ -49,7 +49,7 @@ namespace fcl {
     class GJKSolver;
 
   template <>
-  FCL_REAL ShapeShapeDistance <Box, Sphere, GJKSolver>
+  FCL_REAL ShapeShapeDistance <Box, Sphere>
   (const CollisionGeometry* o1, const Transform3f& tf1,
    const CollisionGeometry* o2, const Transform3f& tf2,
    const GJKSolver*, const DistanceRequest&,
@@ -65,7 +65,7 @@ namespace fcl {
   }
 
   template <>
-  FCL_REAL ShapeShapeDistance <Sphere, Box, GJKSolver>
+  FCL_REAL ShapeShapeDistance <Sphere, Box>
   (const CollisionGeometry* o1, const Transform3f& tf1,
    const CollisionGeometry* o2, const Transform3f& tf2,
    const GJKSolver*, const DistanceRequest&,
diff --git a/src/distance_capsule_capsule.cpp b/src/distance_capsule_capsule.cpp
index 5e6867c59a142f103380fce46a01ee5117597222..c73f2742d754a84e1e5e3ac2b3a4604c17178ecc 100644
--- a/src/distance_capsule_capsule.cpp
+++ b/src/distance_capsule_capsule.cpp
@@ -26,7 +26,7 @@ namespace fcl {
   class GJKSolver;
 
   template <>
-  FCL_REAL ShapeShapeDistance <Capsule, Capsule, GJKSolver>
+  FCL_REAL ShapeShapeDistance <Capsule, Capsule>
   (const CollisionGeometry* o1, const Transform3f& tf1,
    const CollisionGeometry* o2, const Transform3f& tf2,
    const GJKSolver*, const DistanceRequest& request,
@@ -321,7 +321,7 @@ namespace fcl {
   }
 
   template <>
-  std::size_t ShapeShapeCollide <Capsule, Capsule, GJKSolver>
+  std::size_t ShapeShapeCollide <Capsule, Capsule>
   (const CollisionGeometry* o1, const Transform3f& tf1,
    const CollisionGeometry* o2, const Transform3f& tf2,
    const GJKSolver*, const CollisionRequest& request,
@@ -331,7 +331,7 @@ namespace fcl {
     DistanceResult distanceResult;
     DistanceRequest distanceRequest (request.enable_contact);
 
-    FCL_REAL distance = ShapeShapeDistance <Capsule, Capsule, GJKSolver>
+    FCL_REAL distance = ShapeShapeDistance <Capsule, Capsule>
       (o1, tf1, o2, tf2, unused, distanceRequest, distanceResult);
 
     if (distance <= 0) {
diff --git a/src/distance_capsule_halfspace.cpp b/src/distance_capsule_halfspace.cpp
index badb4eb85d2196762518541c1bf4ec747b18d2ab..49976683742bf5cb2311570b00c5db557cae7e9c 100644
--- a/src/distance_capsule_halfspace.cpp
+++ b/src/distance_capsule_halfspace.cpp
@@ -49,7 +49,7 @@ namespace fcl {
     class GJKSolver;
 
   template <>
-  FCL_REAL ShapeShapeDistance <Capsule, Halfspace, GJKSolver>
+  FCL_REAL ShapeShapeDistance <Capsule, Halfspace>
   (const CollisionGeometry* o1, const Transform3f& tf1,
    const CollisionGeometry* o2, const Transform3f& tf2,
    const GJKSolver*, const DistanceRequest&,
@@ -65,7 +65,7 @@ namespace fcl {
   }
 
   template <>
-  FCL_REAL ShapeShapeDistance <Halfspace, Capsule, GJKSolver>
+  FCL_REAL ShapeShapeDistance <Halfspace, Capsule>
   (const CollisionGeometry* o1, const Transform3f& tf1,
    const CollisionGeometry* o2, const Transform3f& tf2,
    const GJKSolver*, const DistanceRequest&,
diff --git a/src/distance_capsule_plane.cpp b/src/distance_capsule_plane.cpp
index b8d0a55aef768df778aa323b1d7ba943e83a7f0b..f719d38ba8ed69a89f8b65cf53bf2eebf3b09f9c 100644
--- a/src/distance_capsule_plane.cpp
+++ b/src/distance_capsule_plane.cpp
@@ -49,7 +49,7 @@ namespace fcl {
     class GJKSolver;
 
   template <>
-  FCL_REAL ShapeShapeDistance <Capsule, Plane, GJKSolver>
+  FCL_REAL ShapeShapeDistance <Capsule, Plane>
   (const CollisionGeometry* o1, const Transform3f& tf1,
    const CollisionGeometry* o2, const Transform3f& tf2,
    const GJKSolver*, const DistanceRequest&,
@@ -65,7 +65,7 @@ namespace fcl {
   }
 
   template <>
-  FCL_REAL ShapeShapeDistance <Plane, Capsule, GJKSolver>
+  FCL_REAL ShapeShapeDistance <Plane, Capsule>
   (const CollisionGeometry* o1, const Transform3f& tf1,
    const CollisionGeometry* o2, const Transform3f& tf2,
    const GJKSolver*, const DistanceRequest&,
diff --git a/src/distance_cone_halfspace.cpp b/src/distance_cone_halfspace.cpp
index 74b8dafeb115cda7ccd81da3d48ca4f5e9529a4e..d7bda73365fcb5ed43bafb7101a80dfc817e3aa1 100644
--- a/src/distance_cone_halfspace.cpp
+++ b/src/distance_cone_halfspace.cpp
@@ -49,7 +49,7 @@ namespace fcl {
     class GJKSolver;
 
   template <>
-  FCL_REAL ShapeShapeDistance <Cone, Halfspace, GJKSolver>
+  FCL_REAL ShapeShapeDistance <Cone, Halfspace>
   (const CollisionGeometry* o1, const Transform3f& tf1,
    const CollisionGeometry* o2, const Transform3f& tf2,
    const GJKSolver*, const DistanceRequest&,
@@ -65,7 +65,7 @@ namespace fcl {
   }
 
   template <>
-  FCL_REAL ShapeShapeDistance <Halfspace, Cone, GJKSolver>
+  FCL_REAL ShapeShapeDistance <Halfspace, Cone>
   (const CollisionGeometry* o1, const Transform3f& tf1,
    const CollisionGeometry* o2, const Transform3f& tf2,
    const GJKSolver*, const DistanceRequest&,
diff --git a/src/distance_cone_plane.cpp b/src/distance_cone_plane.cpp
index 9e0161fb5d0ecd1242d4543ce9e1915e406c042d..893192a111ba7511c7926f1fb37c0dd3734819a1 100644
--- a/src/distance_cone_plane.cpp
+++ b/src/distance_cone_plane.cpp
@@ -49,7 +49,7 @@ namespace fcl {
     class GJKSolver;
 
   template <>
-  FCL_REAL ShapeShapeDistance <Cone, Plane, GJKSolver>
+  FCL_REAL ShapeShapeDistance <Cone, Plane>
   (const CollisionGeometry* o1, const Transform3f& tf1,
    const CollisionGeometry* o2, const Transform3f& tf2,
    const GJKSolver*, const DistanceRequest&,
@@ -65,7 +65,7 @@ namespace fcl {
   }
 
   template <>
-  FCL_REAL ShapeShapeDistance <Plane, Cone, GJKSolver>
+  FCL_REAL ShapeShapeDistance <Plane, Cone>
   (const CollisionGeometry* o1, const Transform3f& tf1,
    const CollisionGeometry* o2, const Transform3f& tf2,
    const GJKSolver*, const DistanceRequest&,
diff --git a/src/distance_cylinder_halfspace.cpp b/src/distance_cylinder_halfspace.cpp
index 975c5926573b539fcd76a00ca7cab80c8b21c61a..086a6b3c1638867e05f0b9ad7d05bc2ed2980a7d 100644
--- a/src/distance_cylinder_halfspace.cpp
+++ b/src/distance_cylinder_halfspace.cpp
@@ -49,7 +49,7 @@ namespace fcl {
     class GJKSolver;
 
   template <>
-  FCL_REAL ShapeShapeDistance <Cylinder, Halfspace, GJKSolver>
+  FCL_REAL ShapeShapeDistance <Cylinder, Halfspace>
   (const CollisionGeometry* o1, const Transform3f& tf1,
    const CollisionGeometry* o2, const Transform3f& tf2,
    const GJKSolver*, const DistanceRequest&,
@@ -65,7 +65,7 @@ namespace fcl {
   }
 
   template <>
-  FCL_REAL ShapeShapeDistance <Halfspace, Cylinder, GJKSolver>
+  FCL_REAL ShapeShapeDistance <Halfspace, Cylinder>
   (const CollisionGeometry* o1, const Transform3f& tf1,
    const CollisionGeometry* o2, const Transform3f& tf2,
    const GJKSolver*, const DistanceRequest&,
diff --git a/src/distance_cylinder_plane.cpp b/src/distance_cylinder_plane.cpp
index 4ca23531236dd6cb634758e77452fd5d67b75f6a..88473ecf8d86c0389dda09d75b33b07aac2f2c06 100644
--- a/src/distance_cylinder_plane.cpp
+++ b/src/distance_cylinder_plane.cpp
@@ -49,7 +49,7 @@ namespace fcl {
     class GJKSolver;
 
   template <>
-  FCL_REAL ShapeShapeDistance <Cylinder, Plane, GJKSolver>
+  FCL_REAL ShapeShapeDistance <Cylinder, Plane>
   (const CollisionGeometry* o1, const Transform3f& tf1,
    const CollisionGeometry* o2, const Transform3f& tf2,
    const GJKSolver*, const DistanceRequest&,
@@ -65,7 +65,7 @@ namespace fcl {
   }
 
   template <>
-  FCL_REAL ShapeShapeDistance <Plane, Cylinder, GJKSolver>
+  FCL_REAL ShapeShapeDistance <Plane, Cylinder>
   (const CollisionGeometry* o1, const Transform3f& tf1,
    const CollisionGeometry* o2, const Transform3f& tf2,
    const GJKSolver*, const DistanceRequest&,
diff --git a/src/distance_func_matrix.cpp b/src/distance_func_matrix.cpp
index 126dbefc90c1cb78d6f7b9ea59e3b1d6da5eb884..4494e5c88926d259429abb5a6dc20a5af9ecca69 100644
--- a/src/distance_func_matrix.cpp
+++ b/src/distance_func_matrix.cpp
@@ -39,7 +39,6 @@
 
 #include <../src/collision_node.h>
 #include "traversal/traversal_node_setup.h"
-#include <hpp/fcl/narrowphase/narrowphase.h>
 
 namespace hpp
 {
@@ -47,15 +46,15 @@ namespace fcl
 {
 
 #ifdef HPP_FCL_HAVE_OCTOMAP
-template<typename T_SH, typename GJKSolver>
+template<typename T_SH>
 FCL_REAL ShapeOcTreeDistance(const CollisionGeometry* o1, const Transform3f& tf1, const CollisionGeometry* o2, const Transform3f& tf2, const GJKSolver* nsolver,
                              const DistanceRequest& request, DistanceResult& result)
 {
   if(request.isSatisfied(result)) return result.min_distance;
-  ShapeOcTreeDistanceTraversalNode<T_SH, GJKSolver> node;
+  ShapeOcTreeDistanceTraversalNode<T_SH> node;
   const T_SH* obj1 = static_cast<const T_SH*>(o1);
   const OcTree* obj2 = static_cast<const OcTree*>(o2);
-  OcTreeSolver<GJKSolver> otsolver(nsolver);
+  OcTreeSolver otsolver(nsolver);
 
   initialize(node, *obj1, tf1, *obj2, tf2, &otsolver, request, result);
   distance(&node);
@@ -63,15 +62,15 @@ FCL_REAL ShapeOcTreeDistance(const CollisionGeometry* o1, const Transform3f& tf1
   return result.min_distance;
 }
 
-template<typename T_SH, typename GJKSolver>
+template<typename T_SH>
 FCL_REAL OcTreeShapeDistance(const CollisionGeometry* o1, const Transform3f& tf1, const CollisionGeometry* o2, const Transform3f& tf2, const GJKSolver* nsolver,
                              const DistanceRequest& request, DistanceResult& result)
 {
   if(request.isSatisfied(result)) return result.min_distance;
-  OcTreeShapeDistanceTraversalNode<T_SH, GJKSolver> node;
+  OcTreeShapeDistanceTraversalNode<T_SH> node;
   const OcTree* obj1 = static_cast<const OcTree*>(o1);
   const T_SH* obj2 = static_cast<const T_SH*>(o2);
-  OcTreeSolver<GJKSolver> otsolver(nsolver);
+  OcTreeSolver otsolver(nsolver);
 
   initialize(node, *obj1, tf1, *obj2, tf2, &otsolver, request, result);
   distance(&node);
@@ -79,15 +78,14 @@ FCL_REAL OcTreeShapeDistance(const CollisionGeometry* o1, const Transform3f& tf1
   return result.min_distance;
 }
 
-template<typename GJKSolver>
 FCL_REAL OcTreeDistance(const CollisionGeometry* o1, const Transform3f& tf1, const CollisionGeometry* o2, const Transform3f& tf2, const GJKSolver* nsolver,
                         const DistanceRequest& request, DistanceResult& result)
 {
   if(request.isSatisfied(result)) return result.min_distance;
-  OcTreeDistanceTraversalNode<GJKSolver> node;
+  OcTreeDistanceTraversalNode node;
   const OcTree* obj1 = static_cast<const OcTree*>(o1);
   const OcTree* obj2 = static_cast<const OcTree*>(o2);
-  OcTreeSolver<GJKSolver> otsolver(nsolver);
+  OcTreeSolver otsolver(nsolver);
 
   initialize(node, *obj1, tf1, *obj2, tf2, &otsolver, request, result);
   distance(&node);
@@ -95,15 +93,15 @@ FCL_REAL OcTreeDistance(const CollisionGeometry* o1, const Transform3f& tf1, con
   return result.min_distance;
 }
 
-template<typename T_BVH, typename GJKSolver>
+template<typename T_BVH>
 FCL_REAL BVHOcTreeDistance(const CollisionGeometry* o1, const Transform3f& tf1, const CollisionGeometry* o2, const Transform3f& tf2, const GJKSolver* nsolver,
                            const DistanceRequest& request, DistanceResult& result)
 {
   if(request.isSatisfied(result)) return result.min_distance;
-  MeshOcTreeDistanceTraversalNode<T_BVH, GJKSolver> node;
+  MeshOcTreeDistanceTraversalNode<T_BVH> node;
   const BVHModel<T_BVH>* obj1 = static_cast<const BVHModel<T_BVH>*>(o1);
   const OcTree* obj2 = static_cast<const OcTree*>(o2);
-  OcTreeSolver<GJKSolver> otsolver(nsolver);
+  OcTreeSolver otsolver(nsolver);
 
   initialize(node, *obj1, tf1, *obj2, tf2, &otsolver, request, result);
   distance(&node);
@@ -111,15 +109,15 @@ FCL_REAL BVHOcTreeDistance(const CollisionGeometry* o1, const Transform3f& tf1,
   return result.min_distance;
 }
 
-template<typename T_BVH, typename GJKSolver>
+template<typename T_BVH>
 FCL_REAL OcTreeBVHDistance(const CollisionGeometry* o1, const Transform3f& tf1, const CollisionGeometry* o2, const Transform3f& tf2, const GJKSolver* nsolver,
                        const DistanceRequest& request, DistanceResult& result)
 {
   if(request.isSatisfied(result)) return result.min_distance;
-  OcTreeMeshDistanceTraversalNode<T_BVH, GJKSolver> node;
+  OcTreeMeshDistanceTraversalNode<T_BVH> node;
   const OcTree* obj1 = static_cast<const OcTree*>(o1);
   const BVHModel<T_BVH>* obj2 = static_cast<const BVHModel<T_BVH>*>(o2);
-  OcTreeSolver<GJKSolver> otsolver(nsolver);
+  OcTreeSolver otsolver(nsolver);
 
   initialize(node, *obj1, tf1, *obj2, tf2, &otsolver, request, result);
   distance(&node);
@@ -129,12 +127,12 @@ FCL_REAL OcTreeBVHDistance(const CollisionGeometry* o1, const Transform3f& tf1,
 
 #endif
 
-template<typename T_SH1, typename T_SH2, typename GJKSolver>
+template<typename T_SH1, typename T_SH2>
 FCL_REAL ShapeShapeDistance(const CollisionGeometry* o1, const Transform3f& tf1, const CollisionGeometry* o2, const Transform3f& tf2, const GJKSolver* nsolver,
                         const DistanceRequest& request, DistanceResult& result)
 {
   if(request.isSatisfied(result)) return result.min_distance;
-  ShapeDistanceTraversalNode<T_SH1, T_SH2, GJKSolver> node;
+  ShapeDistanceTraversalNode<T_SH1, T_SH2> node;
   const T_SH1* obj1 = static_cast<const T_SH1*>(o1);
   const T_SH2* obj2 = static_cast<const T_SH2*>(o2);
 
@@ -144,14 +142,14 @@ FCL_REAL ShapeShapeDistance(const CollisionGeometry* o1, const Transform3f& tf1,
   return result.min_distance;
 }
 
-template<typename T_BVH, typename T_SH, typename GJKSolver>
+template<typename T_BVH, typename T_SH>
 struct BVHShapeDistancer
 {
   static FCL_REAL distance(const CollisionGeometry* o1, const Transform3f& tf1, const CollisionGeometry* o2, const Transform3f& tf2, const GJKSolver* nsolver,
                            const DistanceRequest& request, DistanceResult& result)
   {
     if(request.isSatisfied(result)) return result.min_distance;
-    MeshShapeDistanceTraversalNode<T_BVH, T_SH, GJKSolver> node;
+    MeshShapeDistanceTraversalNode<T_BVH, T_SH> node;
     const BVHModel<T_BVH>* obj1 = static_cast<const BVHModel<T_BVH>* >(o1);
     BVHModel<T_BVH>* obj1_tmp = new BVHModel<T_BVH>(*obj1);
     Transform3f tf1_tmp = tf1;
@@ -168,7 +166,7 @@ struct BVHShapeDistancer
 namespace details
 {
 
-template<typename OrientedMeshShapeDistanceTraversalNode, typename T_BVH, typename T_SH, typename GJKSolver>
+template<typename OrientedMeshShapeDistanceTraversalNode, typename T_BVH, typename T_SH>
 FCL_REAL orientedBVHShapeDistance(const CollisionGeometry* o1, const Transform3f& tf1, const CollisionGeometry* o2, const Transform3f& tf2, const GJKSolver* nsolver,
                                   const DistanceRequest& request, DistanceResult& result)
 {
@@ -185,34 +183,34 @@ FCL_REAL orientedBVHShapeDistance(const CollisionGeometry* o1, const Transform3f
 
 }
 
-template<typename T_SH, typename GJKSolver>
-struct BVHShapeDistancer<RSS, T_SH, GJKSolver>
+template<typename T_SH>
+struct BVHShapeDistancer<RSS, T_SH>
 {
   static FCL_REAL distance(const CollisionGeometry* o1, const Transform3f& tf1, const CollisionGeometry* o2, const Transform3f& tf2, const GJKSolver* nsolver,
                            const DistanceRequest& request, DistanceResult& result)
   {
-    return details::orientedBVHShapeDistance<MeshShapeDistanceTraversalNodeRSS<T_SH, GJKSolver>, RSS, T_SH, GJKSolver>(o1, tf1, o2, tf2, nsolver, request, result);
+    return details::orientedBVHShapeDistance<MeshShapeDistanceTraversalNodeRSS<T_SH>, RSS, T_SH>(o1, tf1, o2, tf2, nsolver, request, result);
   }
 };
 
 
-template<typename T_SH, typename GJKSolver>
-struct BVHShapeDistancer<kIOS, T_SH, GJKSolver>
+template<typename T_SH>
+struct BVHShapeDistancer<kIOS, T_SH>
 {
   static FCL_REAL distance(const CollisionGeometry* o1, const Transform3f& tf1, const CollisionGeometry* o2, const Transform3f& tf2, const GJKSolver* nsolver,
                        const DistanceRequest& request, DistanceResult& result)
   {
-    return details::orientedBVHShapeDistance<MeshShapeDistanceTraversalNodekIOS<T_SH, GJKSolver>, kIOS, T_SH, GJKSolver>(o1, tf1, o2, tf2, nsolver, request, result);
+    return details::orientedBVHShapeDistance<MeshShapeDistanceTraversalNodekIOS<T_SH>, kIOS, T_SH>(o1, tf1, o2, tf2, nsolver, request, result);
   }
 };
 
-template<typename T_SH, typename GJKSolver>
-struct BVHShapeDistancer<OBBRSS, T_SH, GJKSolver>
+template<typename T_SH>
+struct BVHShapeDistancer<OBBRSS, T_SH>
 {
   static FCL_REAL distance(const CollisionGeometry* o1, const Transform3f& tf1, const CollisionGeometry* o2, const Transform3f& tf2, const GJKSolver* nsolver,
                            const DistanceRequest& request, DistanceResult& result)
   {
-    return details::orientedBVHShapeDistance<MeshShapeDistanceTraversalNodeOBBRSS<T_SH, GJKSolver>, OBBRSS, T_SH, GJKSolver>(o1, tf1, o2, tf2, nsolver, request, result);
+    return details::orientedBVHShapeDistance<MeshShapeDistanceTraversalNodeOBBRSS<T_SH>, OBBRSS, T_SH>(o1, tf1, o2, tf2, nsolver, request, result);
   }
 };
 
@@ -280,7 +278,7 @@ FCL_REAL BVHDistance<OBBRSS>(const CollisionGeometry* o1, const Transform3f& tf1
 }
 
 
-template<typename T_BVH, typename GJKSolver>
+template<typename T_BVH>
 FCL_REAL BVHDistance(const CollisionGeometry* o1, const Transform3f& tf1, const CollisionGeometry* o2, const Transform3f& tf2,
                      const GJKSolver* /*nsolver*/,
                      const DistanceRequest& request, DistanceResult& result)
@@ -288,8 +286,7 @@ FCL_REAL BVHDistance(const CollisionGeometry* o1, const Transform3f& tf1, const
   return BVHDistance<T_BVH>(o1, tf1, o2, tf2, request, result);
 }
 
-template<typename GJKSolver>
-DistanceFunctionMatrix<GJKSolver>::DistanceFunctionMatrix()
+DistanceFunctionMatrix::DistanceFunctionMatrix()
 {
   for(int i = 0; i < NODE_COUNT; ++i)
   {
@@ -297,205 +294,205 @@ DistanceFunctionMatrix<GJKSolver>::DistanceFunctionMatrix()
       distance_matrix[i][j] = NULL;
   }
 
-  distance_matrix[GEOM_BOX][GEOM_BOX] = &ShapeShapeDistance<Box, Box, GJKSolver>;
-  distance_matrix[GEOM_BOX][GEOM_SPHERE] = &ShapeShapeDistance<Box, Sphere, GJKSolver>;
-  distance_matrix[GEOM_BOX][GEOM_CAPSULE] = &ShapeShapeDistance<Box, Capsule, GJKSolver>;
-  distance_matrix[GEOM_BOX][GEOM_CONE] = &ShapeShapeDistance<Box, Cone, GJKSolver>;
-  distance_matrix[GEOM_BOX][GEOM_CYLINDER] = &ShapeShapeDistance<Box, Cylinder, GJKSolver>;
-  distance_matrix[GEOM_BOX][GEOM_CONVEX] = &ShapeShapeDistance<Box, Convex, GJKSolver>;
-  distance_matrix[GEOM_BOX][GEOM_PLANE] = &ShapeShapeDistance<Box, Plane, GJKSolver>;
-  distance_matrix[GEOM_BOX][GEOM_HALFSPACE] = &ShapeShapeDistance<Box, Halfspace, GJKSolver>;
-
-  distance_matrix[GEOM_SPHERE][GEOM_BOX] = &ShapeShapeDistance<Sphere, Box, GJKSolver>;
-  distance_matrix[GEOM_SPHERE][GEOM_SPHERE] = &ShapeShapeDistance<Sphere, Sphere, GJKSolver>;
-  distance_matrix[GEOM_SPHERE][GEOM_CAPSULE] = &ShapeShapeDistance<Sphere, Capsule, GJKSolver>;
-  distance_matrix[GEOM_SPHERE][GEOM_CONE] = &ShapeShapeDistance<Sphere, Cone, GJKSolver>;
-  distance_matrix[GEOM_SPHERE][GEOM_CYLINDER] = &ShapeShapeDistance<Sphere, Cylinder, GJKSolver>;
-  distance_matrix[GEOM_SPHERE][GEOM_CONVEX] = &ShapeShapeDistance<Sphere, Convex, GJKSolver>;
-  distance_matrix[GEOM_SPHERE][GEOM_PLANE] = &ShapeShapeDistance<Sphere, Plane, GJKSolver>;
-  distance_matrix[GEOM_SPHERE][GEOM_HALFSPACE] = &ShapeShapeDistance<Sphere, Halfspace, GJKSolver>;
-
-  distance_matrix[GEOM_CAPSULE][GEOM_BOX] = &ShapeShapeDistance<Capsule, Box, GJKSolver>;
-  distance_matrix[GEOM_CAPSULE][GEOM_SPHERE] = &ShapeShapeDistance<Capsule, Sphere, GJKSolver>;
-  distance_matrix[GEOM_CAPSULE][GEOM_CAPSULE] = &ShapeShapeDistance<Capsule, Capsule, GJKSolver>;
-  distance_matrix[GEOM_CAPSULE][GEOM_CONE] = &ShapeShapeDistance<Capsule, Cone, GJKSolver>;
-  distance_matrix[GEOM_CAPSULE][GEOM_CYLINDER] = &ShapeShapeDistance<Capsule, Cylinder, GJKSolver>;
-  distance_matrix[GEOM_CAPSULE][GEOM_CONVEX] = &ShapeShapeDistance<Capsule, Convex, GJKSolver>;
-  distance_matrix[GEOM_CAPSULE][GEOM_PLANE] = &ShapeShapeDistance<Capsule, Plane, GJKSolver>;
-  distance_matrix[GEOM_CAPSULE][GEOM_HALFSPACE] = &ShapeShapeDistance<Capsule, Halfspace, GJKSolver>;
-
-  distance_matrix[GEOM_CONE][GEOM_BOX] = &ShapeShapeDistance<Cone, Box, GJKSolver>;
-  distance_matrix[GEOM_CONE][GEOM_SPHERE] = &ShapeShapeDistance<Cone, Sphere, GJKSolver>;
-  distance_matrix[GEOM_CONE][GEOM_CAPSULE] = &ShapeShapeDistance<Cone, Capsule, GJKSolver>;
-  distance_matrix[GEOM_CONE][GEOM_CONE] = &ShapeShapeDistance<Cone, Cone, GJKSolver>;
-  distance_matrix[GEOM_CONE][GEOM_CYLINDER] = &ShapeShapeDistance<Cone, Cylinder, GJKSolver>;
-  distance_matrix[GEOM_CONE][GEOM_CONVEX] = &ShapeShapeDistance<Cone, Convex, GJKSolver>;
-  distance_matrix[GEOM_CONE][GEOM_PLANE] = &ShapeShapeDistance<Cone, Plane, GJKSolver>;
-  distance_matrix[GEOM_CONE][GEOM_HALFSPACE] = &ShapeShapeDistance<Cone, Halfspace, GJKSolver>;
-
-  distance_matrix[GEOM_CYLINDER][GEOM_BOX] = &ShapeShapeDistance<Cylinder, Box, GJKSolver>;
-  distance_matrix[GEOM_CYLINDER][GEOM_SPHERE] = &ShapeShapeDistance<Cylinder, Sphere, GJKSolver>;
-  distance_matrix[GEOM_CYLINDER][GEOM_CAPSULE] = &ShapeShapeDistance<Cylinder, Capsule, GJKSolver>;
-  distance_matrix[GEOM_CYLINDER][GEOM_CONE] = &ShapeShapeDistance<Cylinder, Cone, GJKSolver>;
-  distance_matrix[GEOM_CYLINDER][GEOM_CYLINDER] = &ShapeShapeDistance<Cylinder, Cylinder, GJKSolver>;
-  distance_matrix[GEOM_CYLINDER][GEOM_CONVEX] = &ShapeShapeDistance<Cylinder, Convex, GJKSolver>;
-  distance_matrix[GEOM_CYLINDER][GEOM_PLANE] = &ShapeShapeDistance<Cylinder, Plane, GJKSolver>;
-  distance_matrix[GEOM_CYLINDER][GEOM_HALFSPACE] = &ShapeShapeDistance<Cylinder, Halfspace, GJKSolver>;
-
-  distance_matrix[GEOM_CONVEX][GEOM_BOX] = &ShapeShapeDistance<Convex, Box, GJKSolver>;
-  distance_matrix[GEOM_CONVEX][GEOM_SPHERE] = &ShapeShapeDistance<Convex, Sphere, GJKSolver>;
-  distance_matrix[GEOM_CONVEX][GEOM_CAPSULE] = &ShapeShapeDistance<Convex, Capsule, GJKSolver>;
-  distance_matrix[GEOM_CONVEX][GEOM_CONE] = &ShapeShapeDistance<Convex, Cone, GJKSolver>;
-  distance_matrix[GEOM_CONVEX][GEOM_CYLINDER] = &ShapeShapeDistance<Convex, Cylinder, GJKSolver>;
-  distance_matrix[GEOM_CONVEX][GEOM_CONVEX] = &ShapeShapeDistance<Convex, Convex, GJKSolver>;
-  distance_matrix[GEOM_CONVEX][GEOM_PLANE] = &ShapeShapeDistance<Convex, Plane, GJKSolver>;
-  distance_matrix[GEOM_CONVEX][GEOM_HALFSPACE] = &ShapeShapeDistance<Convex, Halfspace, GJKSolver>;
-
-  distance_matrix[GEOM_PLANE][GEOM_BOX] = &ShapeShapeDistance<Plane, Box, GJKSolver>;
-  distance_matrix[GEOM_PLANE][GEOM_SPHERE] = &ShapeShapeDistance<Plane, Sphere, GJKSolver>;
-  distance_matrix[GEOM_PLANE][GEOM_CAPSULE] = &ShapeShapeDistance<Plane, Capsule, GJKSolver>;
-  distance_matrix[GEOM_PLANE][GEOM_CONE] = &ShapeShapeDistance<Plane, Cone, GJKSolver>;
-  distance_matrix[GEOM_PLANE][GEOM_CYLINDER] = &ShapeShapeDistance<Plane, Cylinder, GJKSolver>;
-  distance_matrix[GEOM_PLANE][GEOM_CONVEX] = &ShapeShapeDistance<Plane, Convex, GJKSolver>;
-  distance_matrix[GEOM_PLANE][GEOM_PLANE] = &ShapeShapeDistance<Plane, Plane, GJKSolver>;
-  distance_matrix[GEOM_PLANE][GEOM_HALFSPACE] = &ShapeShapeDistance<Plane, Halfspace, GJKSolver>;
-
-  distance_matrix[GEOM_HALFSPACE][GEOM_BOX] = &ShapeShapeDistance<Halfspace, Box, GJKSolver>;
-  distance_matrix[GEOM_HALFSPACE][GEOM_SPHERE] = &ShapeShapeDistance<Halfspace, Sphere, GJKSolver>;
-  distance_matrix[GEOM_HALFSPACE][GEOM_CAPSULE] = &ShapeShapeDistance<Halfspace, Capsule, GJKSolver>;
-  distance_matrix[GEOM_HALFSPACE][GEOM_CONE] = &ShapeShapeDistance<Halfspace, Cone, GJKSolver>;
-  distance_matrix[GEOM_HALFSPACE][GEOM_CYLINDER] = &ShapeShapeDistance<Halfspace, Cylinder, GJKSolver>;
-  distance_matrix[GEOM_HALFSPACE][GEOM_CONVEX] = &ShapeShapeDistance<Halfspace, Convex, GJKSolver>;
-  distance_matrix[GEOM_HALFSPACE][GEOM_PLANE] = &ShapeShapeDistance<Halfspace, Plane, GJKSolver>;
-  distance_matrix[GEOM_HALFSPACE][GEOM_HALFSPACE] = &ShapeShapeDistance<Halfspace, Halfspace, GJKSolver>;
+  distance_matrix[GEOM_BOX][GEOM_BOX] = &ShapeShapeDistance<Box, Box>;
+  distance_matrix[GEOM_BOX][GEOM_SPHERE] = &ShapeShapeDistance<Box, Sphere>;
+  distance_matrix[GEOM_BOX][GEOM_CAPSULE] = &ShapeShapeDistance<Box, Capsule>;
+  distance_matrix[GEOM_BOX][GEOM_CONE] = &ShapeShapeDistance<Box, Cone>;
+  distance_matrix[GEOM_BOX][GEOM_CYLINDER] = &ShapeShapeDistance<Box, Cylinder>;
+  distance_matrix[GEOM_BOX][GEOM_CONVEX] = &ShapeShapeDistance<Box, Convex>;
+  distance_matrix[GEOM_BOX][GEOM_PLANE] = &ShapeShapeDistance<Box, Plane>;
+  distance_matrix[GEOM_BOX][GEOM_HALFSPACE] = &ShapeShapeDistance<Box, Halfspace>;
+
+  distance_matrix[GEOM_SPHERE][GEOM_BOX] = &ShapeShapeDistance<Sphere, Box>;
+  distance_matrix[GEOM_SPHERE][GEOM_SPHERE] = &ShapeShapeDistance<Sphere, Sphere>;
+  distance_matrix[GEOM_SPHERE][GEOM_CAPSULE] = &ShapeShapeDistance<Sphere, Capsule>;
+  distance_matrix[GEOM_SPHERE][GEOM_CONE] = &ShapeShapeDistance<Sphere, Cone>;
+  distance_matrix[GEOM_SPHERE][GEOM_CYLINDER] = &ShapeShapeDistance<Sphere, Cylinder>;
+  distance_matrix[GEOM_SPHERE][GEOM_CONVEX] = &ShapeShapeDistance<Sphere, Convex>;
+  distance_matrix[GEOM_SPHERE][GEOM_PLANE] = &ShapeShapeDistance<Sphere, Plane>;
+  distance_matrix[GEOM_SPHERE][GEOM_HALFSPACE] = &ShapeShapeDistance<Sphere, Halfspace>;
+
+  distance_matrix[GEOM_CAPSULE][GEOM_BOX] = &ShapeShapeDistance<Capsule, Box>;
+  distance_matrix[GEOM_CAPSULE][GEOM_SPHERE] = &ShapeShapeDistance<Capsule, Sphere>;
+  distance_matrix[GEOM_CAPSULE][GEOM_CAPSULE] = &ShapeShapeDistance<Capsule, Capsule>;
+  distance_matrix[GEOM_CAPSULE][GEOM_CONE] = &ShapeShapeDistance<Capsule, Cone>;
+  distance_matrix[GEOM_CAPSULE][GEOM_CYLINDER] = &ShapeShapeDistance<Capsule, Cylinder>;
+  distance_matrix[GEOM_CAPSULE][GEOM_CONVEX] = &ShapeShapeDistance<Capsule, Convex>;
+  distance_matrix[GEOM_CAPSULE][GEOM_PLANE] = &ShapeShapeDistance<Capsule, Plane>;
+  distance_matrix[GEOM_CAPSULE][GEOM_HALFSPACE] = &ShapeShapeDistance<Capsule, Halfspace>;
+
+  distance_matrix[GEOM_CONE][GEOM_BOX] = &ShapeShapeDistance<Cone, Box>;
+  distance_matrix[GEOM_CONE][GEOM_SPHERE] = &ShapeShapeDistance<Cone, Sphere>;
+  distance_matrix[GEOM_CONE][GEOM_CAPSULE] = &ShapeShapeDistance<Cone, Capsule>;
+  distance_matrix[GEOM_CONE][GEOM_CONE] = &ShapeShapeDistance<Cone, Cone>;
+  distance_matrix[GEOM_CONE][GEOM_CYLINDER] = &ShapeShapeDistance<Cone, Cylinder>;
+  distance_matrix[GEOM_CONE][GEOM_CONVEX] = &ShapeShapeDistance<Cone, Convex>;
+  distance_matrix[GEOM_CONE][GEOM_PLANE] = &ShapeShapeDistance<Cone, Plane>;
+  distance_matrix[GEOM_CONE][GEOM_HALFSPACE] = &ShapeShapeDistance<Cone, Halfspace>;
+
+  distance_matrix[GEOM_CYLINDER][GEOM_BOX] = &ShapeShapeDistance<Cylinder, Box>;
+  distance_matrix[GEOM_CYLINDER][GEOM_SPHERE] = &ShapeShapeDistance<Cylinder, Sphere>;
+  distance_matrix[GEOM_CYLINDER][GEOM_CAPSULE] = &ShapeShapeDistance<Cylinder, Capsule>;
+  distance_matrix[GEOM_CYLINDER][GEOM_CONE] = &ShapeShapeDistance<Cylinder, Cone>;
+  distance_matrix[GEOM_CYLINDER][GEOM_CYLINDER] = &ShapeShapeDistance<Cylinder, Cylinder>;
+  distance_matrix[GEOM_CYLINDER][GEOM_CONVEX] = &ShapeShapeDistance<Cylinder, Convex>;
+  distance_matrix[GEOM_CYLINDER][GEOM_PLANE] = &ShapeShapeDistance<Cylinder, Plane>;
+  distance_matrix[GEOM_CYLINDER][GEOM_HALFSPACE] = &ShapeShapeDistance<Cylinder, Halfspace>;
+
+  distance_matrix[GEOM_CONVEX][GEOM_BOX] = &ShapeShapeDistance<Convex, Box>;
+  distance_matrix[GEOM_CONVEX][GEOM_SPHERE] = &ShapeShapeDistance<Convex, Sphere>;
+  distance_matrix[GEOM_CONVEX][GEOM_CAPSULE] = &ShapeShapeDistance<Convex, Capsule>;
+  distance_matrix[GEOM_CONVEX][GEOM_CONE] = &ShapeShapeDistance<Convex, Cone>;
+  distance_matrix[GEOM_CONVEX][GEOM_CYLINDER] = &ShapeShapeDistance<Convex, Cylinder>;
+  distance_matrix[GEOM_CONVEX][GEOM_CONVEX] = &ShapeShapeDistance<Convex, Convex>;
+  distance_matrix[GEOM_CONVEX][GEOM_PLANE] = &ShapeShapeDistance<Convex, Plane>;
+  distance_matrix[GEOM_CONVEX][GEOM_HALFSPACE] = &ShapeShapeDistance<Convex, Halfspace>;
+
+  distance_matrix[GEOM_PLANE][GEOM_BOX] = &ShapeShapeDistance<Plane, Box>;
+  distance_matrix[GEOM_PLANE][GEOM_SPHERE] = &ShapeShapeDistance<Plane, Sphere>;
+  distance_matrix[GEOM_PLANE][GEOM_CAPSULE] = &ShapeShapeDistance<Plane, Capsule>;
+  distance_matrix[GEOM_PLANE][GEOM_CONE] = &ShapeShapeDistance<Plane, Cone>;
+  distance_matrix[GEOM_PLANE][GEOM_CYLINDER] = &ShapeShapeDistance<Plane, Cylinder>;
+  distance_matrix[GEOM_PLANE][GEOM_CONVEX] = &ShapeShapeDistance<Plane, Convex>;
+  distance_matrix[GEOM_PLANE][GEOM_PLANE] = &ShapeShapeDistance<Plane, Plane>;
+  distance_matrix[GEOM_PLANE][GEOM_HALFSPACE] = &ShapeShapeDistance<Plane, Halfspace>;
+
+  distance_matrix[GEOM_HALFSPACE][GEOM_BOX] = &ShapeShapeDistance<Halfspace, Box>;
+  distance_matrix[GEOM_HALFSPACE][GEOM_SPHERE] = &ShapeShapeDistance<Halfspace, Sphere>;
+  distance_matrix[GEOM_HALFSPACE][GEOM_CAPSULE] = &ShapeShapeDistance<Halfspace, Capsule>;
+  distance_matrix[GEOM_HALFSPACE][GEOM_CONE] = &ShapeShapeDistance<Halfspace, Cone>;
+  distance_matrix[GEOM_HALFSPACE][GEOM_CYLINDER] = &ShapeShapeDistance<Halfspace, Cylinder>;
+  distance_matrix[GEOM_HALFSPACE][GEOM_CONVEX] = &ShapeShapeDistance<Halfspace, Convex>;
+  distance_matrix[GEOM_HALFSPACE][GEOM_PLANE] = &ShapeShapeDistance<Halfspace, Plane>;
+  distance_matrix[GEOM_HALFSPACE][GEOM_HALFSPACE] = &ShapeShapeDistance<Halfspace, Halfspace>;
 
   /* AABB distance not implemented */
   /*
-  distance_matrix[BV_AABB][GEOM_BOX] = &BVHShapeDistancer<AABB, Box, GJKSolver>::distance;
-  distance_matrix[BV_AABB][GEOM_SPHERE] = &BVHShapeDistancer<AABB, Sphere, GJKSolver>::distance;
-  distance_matrix[BV_AABB][GEOM_CAPSULE] = &BVHShapeDistancer<AABB, Capsule, GJKSolver>::distance;
-  distance_matrix[BV_AABB][GEOM_CONE] = &BVHShapeDistancer<AABB, Cone, GJKSolver>::distance;
-  distance_matrix[BV_AABB][GEOM_CYLINDER] = &BVHShapeDistancer<AABB, Cylinder, GJKSolver>::distance;
-  distance_matrix[BV_AABB][GEOM_CONVEX] = &BVHShapeDistancer<AABB, Convex, GJKSolver>::distance;
-  distance_matrix[BV_AABB][GEOM_PLANE] = &BVHShapeDistancer<AABB, Plane, GJKSolver>::distance;
-  distance_matrix[BV_AABB][GEOM_HALFSPACE] = &BVHShapeDistancer<AABB, Halfspace, GJKSolver>::distance;
+  distance_matrix[BV_AABB][GEOM_BOX] = &BVHShapeDistancer<AABB, Box>::distance;
+  distance_matrix[BV_AABB][GEOM_SPHERE] = &BVHShapeDistancer<AABB, Sphere>::distance;
+  distance_matrix[BV_AABB][GEOM_CAPSULE] = &BVHShapeDistancer<AABB, Capsule>::distance;
+  distance_matrix[BV_AABB][GEOM_CONE] = &BVHShapeDistancer<AABB, Cone>::distance;
+  distance_matrix[BV_AABB][GEOM_CYLINDER] = &BVHShapeDistancer<AABB, Cylinder>::distance;
+  distance_matrix[BV_AABB][GEOM_CONVEX] = &BVHShapeDistancer<AABB, Convex>::distance;
+  distance_matrix[BV_AABB][GEOM_PLANE] = &BVHShapeDistancer<AABB, Plane>::distance;
+  distance_matrix[BV_AABB][GEOM_HALFSPACE] = &BVHShapeDistancer<AABB, Halfspace>::distance;
   */
 
-  distance_matrix[BV_OBB][GEOM_BOX] = &BVHShapeDistancer<OBB, Box, GJKSolver>::distance;
-  distance_matrix[BV_OBB][GEOM_SPHERE] = &BVHShapeDistancer<OBB, Sphere, GJKSolver>::distance;
-  distance_matrix[BV_OBB][GEOM_CAPSULE] = &BVHShapeDistancer<OBB, Capsule, GJKSolver>::distance;
-  distance_matrix[BV_OBB][GEOM_CONE] = &BVHShapeDistancer<OBB, Cone, GJKSolver>::distance;
-  distance_matrix[BV_OBB][GEOM_CYLINDER] = &BVHShapeDistancer<OBB, Cylinder, GJKSolver>::distance;
-  distance_matrix[BV_OBB][GEOM_CONVEX] = &BVHShapeDistancer<OBB, Convex, GJKSolver>::distance;
-  distance_matrix[BV_OBB][GEOM_PLANE] = &BVHShapeDistancer<OBB, Plane, GJKSolver>::distance;
-  distance_matrix[BV_OBB][GEOM_HALFSPACE] = &BVHShapeDistancer<OBB, Halfspace, GJKSolver>::distance;
-
-  distance_matrix[BV_RSS][GEOM_BOX] = &BVHShapeDistancer<RSS, Box, GJKSolver>::distance;
-  distance_matrix[BV_RSS][GEOM_SPHERE] = &BVHShapeDistancer<RSS, Sphere, GJKSolver>::distance;
-  distance_matrix[BV_RSS][GEOM_CAPSULE] = &BVHShapeDistancer<RSS, Capsule, GJKSolver>::distance;
-  distance_matrix[BV_RSS][GEOM_CONE] = &BVHShapeDistancer<RSS, Cone, GJKSolver>::distance;
-  distance_matrix[BV_RSS][GEOM_CYLINDER] = &BVHShapeDistancer<RSS, Cylinder, GJKSolver>::distance;
-  distance_matrix[BV_RSS][GEOM_CONVEX] = &BVHShapeDistancer<RSS, Convex, GJKSolver>::distance;
-  distance_matrix[BV_RSS][GEOM_PLANE] = &BVHShapeDistancer<RSS, Plane, GJKSolver>::distance;
-  distance_matrix[BV_RSS][GEOM_HALFSPACE] = &BVHShapeDistancer<RSS, Halfspace, GJKSolver>::distance;
+  distance_matrix[BV_OBB][GEOM_BOX] = &BVHShapeDistancer<OBB, Box>::distance;
+  distance_matrix[BV_OBB][GEOM_SPHERE] = &BVHShapeDistancer<OBB, Sphere>::distance;
+  distance_matrix[BV_OBB][GEOM_CAPSULE] = &BVHShapeDistancer<OBB, Capsule>::distance;
+  distance_matrix[BV_OBB][GEOM_CONE] = &BVHShapeDistancer<OBB, Cone>::distance;
+  distance_matrix[BV_OBB][GEOM_CYLINDER] = &BVHShapeDistancer<OBB, Cylinder>::distance;
+  distance_matrix[BV_OBB][GEOM_CONVEX] = &BVHShapeDistancer<OBB, Convex>::distance;
+  distance_matrix[BV_OBB][GEOM_PLANE] = &BVHShapeDistancer<OBB, Plane>::distance;
+  distance_matrix[BV_OBB][GEOM_HALFSPACE] = &BVHShapeDistancer<OBB, Halfspace>::distance;
+
+  distance_matrix[BV_RSS][GEOM_BOX] = &BVHShapeDistancer<RSS, Box>::distance;
+  distance_matrix[BV_RSS][GEOM_SPHERE] = &BVHShapeDistancer<RSS, Sphere>::distance;
+  distance_matrix[BV_RSS][GEOM_CAPSULE] = &BVHShapeDistancer<RSS, Capsule>::distance;
+  distance_matrix[BV_RSS][GEOM_CONE] = &BVHShapeDistancer<RSS, Cone>::distance;
+  distance_matrix[BV_RSS][GEOM_CYLINDER] = &BVHShapeDistancer<RSS, Cylinder>::distance;
+  distance_matrix[BV_RSS][GEOM_CONVEX] = &BVHShapeDistancer<RSS, Convex>::distance;
+  distance_matrix[BV_RSS][GEOM_PLANE] = &BVHShapeDistancer<RSS, Plane>::distance;
+  distance_matrix[BV_RSS][GEOM_HALFSPACE] = &BVHShapeDistancer<RSS, Halfspace>::distance;
 
   /* KDOP distance not implemented */
   /*
-  distance_matrix[BV_KDOP16][GEOM_BOX] = &BVHShapeDistancer<KDOP<16>, Box, GJKSolver>::distance;
-  distance_matrix[BV_KDOP16][GEOM_SPHERE] = &BVHShapeDistancer<KDOP<16>, Sphere, GJKSolver>::distance;
-  distance_matrix[BV_KDOP16][GEOM_CAPSULE] = &BVHShapeDistancer<KDOP<16>, Capsule, GJKSolver>::distance;
-  distance_matrix[BV_KDOP16][GEOM_CONE] = &BVHShapeDistancer<KDOP<16>, Cone, GJKSolver>::distance;
-  distance_matrix[BV_KDOP16][GEOM_CYLINDER] = &BVHShapeDistancer<KDOP<16>, Cylinder, GJKSolver>::distance;
-  distance_matrix[BV_KDOP16][GEOM_CONVEX] = &BVHShapeDistancer<KDOP<16>, Convex, GJKSolver>::distance;
-  distance_matrix[BV_KDOP16][GEOM_PLANE] = &BVHShapeDistancer<KDOP<16>, Plane, GJKSolver>::distance;
-  distance_matrix[BV_KDOP16][GEOM_HALFSPACE] = &BVHShapeDistancer<KDOP<16>, Halfspace, GJKSolver>::distance;
-
-  distance_matrix[BV_KDOP18][GEOM_BOX] = &BVHShapeDistancer<KDOP<18>, Box, GJKSolver>::distance;
-  distance_matrix[BV_KDOP18][GEOM_SPHERE] = &BVHShapeDistancer<KDOP<18>, Sphere, GJKSolver>::distance;
-  distance_matrix[BV_KDOP18][GEOM_CAPSULE] = &BVHShapeDistancer<KDOP<18>, Capsule, GJKSolver>::distance;
-  distance_matrix[BV_KDOP18][GEOM_CONE] = &BVHShapeDistancer<KDOP<18>, Cone, GJKSolver>::distance;
-  distance_matrix[BV_KDOP18][GEOM_CYLINDER] = &BVHShapeDistancer<KDOP<18>, Cylinder, GJKSolver>::distance;
-  distance_matrix[BV_KDOP18][GEOM_CONVEX] = &BVHShapeDistancer<KDOP<18>, Convex, GJKSolver>::distance;
-  distance_matrix[BV_KDOP18][GEOM_PLANE] = &BVHShapeDistancer<KDOP<18>, Plane, GJKSolver>::distance;
-  distance_matrix[BV_KDOP18][GEOM_HALFSPACE] = &BVHShapeDistancer<KDOP<18>, Halfspace, GJKSolver>::distance;
-
-  distance_matrix[BV_KDOP24][GEOM_BOX] = &BVHShapeDistancer<KDOP<24>, Box, GJKSolver>::distance;
-  distance_matrix[BV_KDOP24][GEOM_SPHERE] = &BVHShapeDistancer<KDOP<24>, Sphere, GJKSolver>::distance;
-  distance_matrix[BV_KDOP24][GEOM_CAPSULE] = &BVHShapeDistancer<KDOP<24>, Capsule, GJKSolver>::distance;
-  distance_matrix[BV_KDOP24][GEOM_CONE] = &BVHShapeDistancer<KDOP<24>, Cone, GJKSolver>::distance;
-  distance_matrix[BV_KDOP24][GEOM_CYLINDER] = &BVHShapeDistancer<KDOP<24>, Cylinder, GJKSolver>::distance;
-  distance_matrix[BV_KDOP24][GEOM_CONVEX] = &BVHShapeDistancer<KDOP<24>, Convex, GJKSolver>::distance;
-  distance_matrix[BV_KDOP24][GEOM_PLANE] = &BVHShapeDistancer<KDOP<24>, Plane, GJKSolver>::distance;
-  distance_matrix[BV_KDOP24][GEOM_HALFSPACE] = &BVHShapeDistancer<KDOP<24>, Halfspace, GJKSolver>::distance;
+  distance_matrix[BV_KDOP16][GEOM_BOX] = &BVHShapeDistancer<KDOP<16>, Box>::distance;
+  distance_matrix[BV_KDOP16][GEOM_SPHERE] = &BVHShapeDistancer<KDOP<16>, Sphere>::distance;
+  distance_matrix[BV_KDOP16][GEOM_CAPSULE] = &BVHShapeDistancer<KDOP<16>, Capsule>::distance;
+  distance_matrix[BV_KDOP16][GEOM_CONE] = &BVHShapeDistancer<KDOP<16>, Cone>::distance;
+  distance_matrix[BV_KDOP16][GEOM_CYLINDER] = &BVHShapeDistancer<KDOP<16>, Cylinder>::distance;
+  distance_matrix[BV_KDOP16][GEOM_CONVEX] = &BVHShapeDistancer<KDOP<16>, Convex>::distance;
+  distance_matrix[BV_KDOP16][GEOM_PLANE] = &BVHShapeDistancer<KDOP<16>, Plane>::distance;
+  distance_matrix[BV_KDOP16][GEOM_HALFSPACE] = &BVHShapeDistancer<KDOP<16>, Halfspace>::distance;
+
+  distance_matrix[BV_KDOP18][GEOM_BOX] = &BVHShapeDistancer<KDOP<18>, Box>::distance;
+  distance_matrix[BV_KDOP18][GEOM_SPHERE] = &BVHShapeDistancer<KDOP<18>, Sphere>::distance;
+  distance_matrix[BV_KDOP18][GEOM_CAPSULE] = &BVHShapeDistancer<KDOP<18>, Capsule>::distance;
+  distance_matrix[BV_KDOP18][GEOM_CONE] = &BVHShapeDistancer<KDOP<18>, Cone>::distance;
+  distance_matrix[BV_KDOP18][GEOM_CYLINDER] = &BVHShapeDistancer<KDOP<18>, Cylinder>::distance;
+  distance_matrix[BV_KDOP18][GEOM_CONVEX] = &BVHShapeDistancer<KDOP<18>, Convex>::distance;
+  distance_matrix[BV_KDOP18][GEOM_PLANE] = &BVHShapeDistancer<KDOP<18>, Plane>::distance;
+  distance_matrix[BV_KDOP18][GEOM_HALFSPACE] = &BVHShapeDistancer<KDOP<18>, Halfspace>::distance;
+
+  distance_matrix[BV_KDOP24][GEOM_BOX] = &BVHShapeDistancer<KDOP<24>, Box>::distance;
+  distance_matrix[BV_KDOP24][GEOM_SPHERE] = &BVHShapeDistancer<KDOP<24>, Sphere>::distance;
+  distance_matrix[BV_KDOP24][GEOM_CAPSULE] = &BVHShapeDistancer<KDOP<24>, Capsule>::distance;
+  distance_matrix[BV_KDOP24][GEOM_CONE] = &BVHShapeDistancer<KDOP<24>, Cone>::distance;
+  distance_matrix[BV_KDOP24][GEOM_CYLINDER] = &BVHShapeDistancer<KDOP<24>, Cylinder>::distance;
+  distance_matrix[BV_KDOP24][GEOM_CONVEX] = &BVHShapeDistancer<KDOP<24>, Convex>::distance;
+  distance_matrix[BV_KDOP24][GEOM_PLANE] = &BVHShapeDistancer<KDOP<24>, Plane>::distance;
+  distance_matrix[BV_KDOP24][GEOM_HALFSPACE] = &BVHShapeDistancer<KDOP<24>, Halfspace>::distance;
   */
 
-  distance_matrix[BV_kIOS][GEOM_BOX] = &BVHShapeDistancer<kIOS, Box, GJKSolver>::distance;
-  distance_matrix[BV_kIOS][GEOM_SPHERE] = &BVHShapeDistancer<kIOS, Sphere, GJKSolver>::distance;
-  distance_matrix[BV_kIOS][GEOM_CAPSULE] = &BVHShapeDistancer<kIOS, Capsule, GJKSolver>::distance;
-  distance_matrix[BV_kIOS][GEOM_CONE] = &BVHShapeDistancer<kIOS, Cone, GJKSolver>::distance;
-  distance_matrix[BV_kIOS][GEOM_CYLINDER] = &BVHShapeDistancer<kIOS, Cylinder, GJKSolver>::distance;
-  distance_matrix[BV_kIOS][GEOM_CONVEX] = &BVHShapeDistancer<kIOS, Convex, GJKSolver>::distance;
-  distance_matrix[BV_kIOS][GEOM_PLANE] = &BVHShapeDistancer<kIOS, Plane, GJKSolver>::distance;
-  distance_matrix[BV_kIOS][GEOM_HALFSPACE] = &BVHShapeDistancer<kIOS, Halfspace, GJKSolver>::distance;
-
-  distance_matrix[BV_OBBRSS][GEOM_BOX] = &BVHShapeDistancer<OBBRSS, Box, GJKSolver>::distance;
-  distance_matrix[BV_OBBRSS][GEOM_SPHERE] = &BVHShapeDistancer<OBBRSS, Sphere, GJKSolver>::distance;
-  distance_matrix[BV_OBBRSS][GEOM_CAPSULE] = &BVHShapeDistancer<OBBRSS, Capsule, GJKSolver>::distance;
-  distance_matrix[BV_OBBRSS][GEOM_CONE] = &BVHShapeDistancer<OBBRSS, Cone, GJKSolver>::distance;
-  distance_matrix[BV_OBBRSS][GEOM_CYLINDER] = &BVHShapeDistancer<OBBRSS, Cylinder, GJKSolver>::distance;
-  distance_matrix[BV_OBBRSS][GEOM_CONVEX] = &BVHShapeDistancer<OBBRSS, Convex, GJKSolver>::distance;
-  distance_matrix[BV_OBBRSS][GEOM_PLANE] = &BVHShapeDistancer<OBBRSS, Plane, GJKSolver>::distance;
-  distance_matrix[BV_OBBRSS][GEOM_HALFSPACE] = &BVHShapeDistancer<OBBRSS, Halfspace, GJKSolver>::distance;
-
-  distance_matrix[BV_AABB][BV_AABB] = &BVHDistance<AABB, GJKSolver>;
-  distance_matrix[BV_OBB][BV_OBB] = &BVHDistance<OBB, GJKSolver>;
-  distance_matrix[BV_RSS][BV_RSS] = &BVHDistance<RSS, GJKSolver>;
-  distance_matrix[BV_kIOS][BV_kIOS] = &BVHDistance<kIOS, GJKSolver>;
-  distance_matrix[BV_OBBRSS][BV_OBBRSS] = &BVHDistance<OBBRSS, GJKSolver>;
+  distance_matrix[BV_kIOS][GEOM_BOX] = &BVHShapeDistancer<kIOS, Box>::distance;
+  distance_matrix[BV_kIOS][GEOM_SPHERE] = &BVHShapeDistancer<kIOS, Sphere>::distance;
+  distance_matrix[BV_kIOS][GEOM_CAPSULE] = &BVHShapeDistancer<kIOS, Capsule>::distance;
+  distance_matrix[BV_kIOS][GEOM_CONE] = &BVHShapeDistancer<kIOS, Cone>::distance;
+  distance_matrix[BV_kIOS][GEOM_CYLINDER] = &BVHShapeDistancer<kIOS, Cylinder>::distance;
+  distance_matrix[BV_kIOS][GEOM_CONVEX] = &BVHShapeDistancer<kIOS, Convex>::distance;
+  distance_matrix[BV_kIOS][GEOM_PLANE] = &BVHShapeDistancer<kIOS, Plane>::distance;
+  distance_matrix[BV_kIOS][GEOM_HALFSPACE] = &BVHShapeDistancer<kIOS, Halfspace>::distance;
+
+  distance_matrix[BV_OBBRSS][GEOM_BOX] = &BVHShapeDistancer<OBBRSS, Box>::distance;
+  distance_matrix[BV_OBBRSS][GEOM_SPHERE] = &BVHShapeDistancer<OBBRSS, Sphere>::distance;
+  distance_matrix[BV_OBBRSS][GEOM_CAPSULE] = &BVHShapeDistancer<OBBRSS, Capsule>::distance;
+  distance_matrix[BV_OBBRSS][GEOM_CONE] = &BVHShapeDistancer<OBBRSS, Cone>::distance;
+  distance_matrix[BV_OBBRSS][GEOM_CYLINDER] = &BVHShapeDistancer<OBBRSS, Cylinder>::distance;
+  distance_matrix[BV_OBBRSS][GEOM_CONVEX] = &BVHShapeDistancer<OBBRSS, Convex>::distance;
+  distance_matrix[BV_OBBRSS][GEOM_PLANE] = &BVHShapeDistancer<OBBRSS, Plane>::distance;
+  distance_matrix[BV_OBBRSS][GEOM_HALFSPACE] = &BVHShapeDistancer<OBBRSS, Halfspace>::distance;
+
+  distance_matrix[BV_AABB][BV_AABB] = &BVHDistance<AABB>;
+  distance_matrix[BV_OBB][BV_OBB] = &BVHDistance<OBB>;
+  distance_matrix[BV_RSS][BV_RSS] = &BVHDistance<RSS>;
+  distance_matrix[BV_kIOS][BV_kIOS] = &BVHDistance<kIOS>;
+  distance_matrix[BV_OBBRSS][BV_OBBRSS] = &BVHDistance<OBBRSS>;
 
 #ifdef HPP_FCL_HAVE_OCTOMAP
-  distance_matrix[GEOM_OCTREE][GEOM_BOX] = &OcTreeShapeDistance<Box, GJKSolver>;
-  distance_matrix[GEOM_OCTREE][GEOM_SPHERE] = &OcTreeShapeDistance<Sphere, GJKSolver>;
-  distance_matrix[GEOM_OCTREE][GEOM_CAPSULE] = &OcTreeShapeDistance<Capsule, GJKSolver>;
-  distance_matrix[GEOM_OCTREE][GEOM_CONE] = &OcTreeShapeDistance<Cone, GJKSolver>;
-  distance_matrix[GEOM_OCTREE][GEOM_CYLINDER] = &OcTreeShapeDistance<Cylinder, GJKSolver>;
-  distance_matrix[GEOM_OCTREE][GEOM_CONVEX] = &OcTreeShapeDistance<Convex, GJKSolver>;
-  distance_matrix[GEOM_OCTREE][GEOM_PLANE] = &OcTreeShapeDistance<Plane, GJKSolver>;
-  distance_matrix[GEOM_OCTREE][GEOM_HALFSPACE] = &OcTreeShapeDistance<Halfspace, GJKSolver>;
-
-  distance_matrix[GEOM_BOX][GEOM_OCTREE] = &ShapeOcTreeDistance<Box, GJKSolver>;
-  distance_matrix[GEOM_SPHERE][GEOM_OCTREE] = &ShapeOcTreeDistance<Sphere, GJKSolver>;
-  distance_matrix[GEOM_CAPSULE][GEOM_OCTREE] = &ShapeOcTreeDistance<Capsule, GJKSolver>;
-  distance_matrix[GEOM_CONE][GEOM_OCTREE] = &ShapeOcTreeDistance<Cone, GJKSolver>;
-  distance_matrix[GEOM_CYLINDER][GEOM_OCTREE] = &ShapeOcTreeDistance<Cylinder, GJKSolver>;
-  distance_matrix[GEOM_CONVEX][GEOM_OCTREE] = &ShapeOcTreeDistance<Convex, GJKSolver>;
-  distance_matrix[GEOM_PLANE][GEOM_OCTREE] = &ShapeOcTreeDistance<Plane, GJKSolver>;
-  distance_matrix[GEOM_HALFSPACE][GEOM_OCTREE] = &ShapeOcTreeDistance<Halfspace, GJKSolver>;
-
-  distance_matrix[GEOM_OCTREE][GEOM_OCTREE] = &OcTreeDistance<GJKSolver>;
-
-  distance_matrix[GEOM_OCTREE][BV_AABB] = &OcTreeBVHDistance<AABB, GJKSolver>;
-  distance_matrix[GEOM_OCTREE][BV_OBB] = &OcTreeBVHDistance<OBB, GJKSolver>;
-  distance_matrix[GEOM_OCTREE][BV_RSS] = &OcTreeBVHDistance<RSS, GJKSolver>;
-  distance_matrix[GEOM_OCTREE][BV_OBBRSS] = &OcTreeBVHDistance<OBBRSS, GJKSolver>;
-  distance_matrix[GEOM_OCTREE][BV_kIOS] = &OcTreeBVHDistance<kIOS, GJKSolver>;
-  distance_matrix[GEOM_OCTREE][BV_KDOP16] = &OcTreeBVHDistance<KDOP<16>, GJKSolver>;
-  distance_matrix[GEOM_OCTREE][BV_KDOP18] = &OcTreeBVHDistance<KDOP<18>, GJKSolver>;
-  distance_matrix[GEOM_OCTREE][BV_KDOP24] = &OcTreeBVHDistance<KDOP<24>, GJKSolver>;
-
-  distance_matrix[BV_AABB][GEOM_OCTREE] = &BVHOcTreeDistance<AABB, GJKSolver>;
-  distance_matrix[BV_OBB][GEOM_OCTREE] = &BVHOcTreeDistance<OBB, GJKSolver>;
-  distance_matrix[BV_RSS][GEOM_OCTREE] = &BVHOcTreeDistance<RSS, GJKSolver>;
-  distance_matrix[BV_OBBRSS][GEOM_OCTREE] = &BVHOcTreeDistance<OBBRSS, GJKSolver>;
-  distance_matrix[BV_kIOS][GEOM_OCTREE] = &BVHOcTreeDistance<kIOS, GJKSolver>;
-  distance_matrix[BV_KDOP16][GEOM_OCTREE] = &BVHOcTreeDistance<KDOP<16>, GJKSolver>;
-  distance_matrix[BV_KDOP18][GEOM_OCTREE] = &BVHOcTreeDistance<KDOP<18>, GJKSolver>;
-  distance_matrix[BV_KDOP24][GEOM_OCTREE] = &BVHOcTreeDistance<KDOP<24>, GJKSolver>;
+  distance_matrix[GEOM_OCTREE][GEOM_BOX] = &OcTreeShapeDistance<Box>;
+  distance_matrix[GEOM_OCTREE][GEOM_SPHERE] = &OcTreeShapeDistance<Sphere>;
+  distance_matrix[GEOM_OCTREE][GEOM_CAPSULE] = &OcTreeShapeDistance<Capsule>;
+  distance_matrix[GEOM_OCTREE][GEOM_CONE] = &OcTreeShapeDistance<Cone>;
+  distance_matrix[GEOM_OCTREE][GEOM_CYLINDER] = &OcTreeShapeDistance<Cylinder>;
+  distance_matrix[GEOM_OCTREE][GEOM_CONVEX] = &OcTreeShapeDistance<Convex>;
+  distance_matrix[GEOM_OCTREE][GEOM_PLANE] = &OcTreeShapeDistance<Plane>;
+  distance_matrix[GEOM_OCTREE][GEOM_HALFSPACE] = &OcTreeShapeDistance<Halfspace>;
+
+  distance_matrix[GEOM_BOX][GEOM_OCTREE] = &ShapeOcTreeDistance<Box>;
+  distance_matrix[GEOM_SPHERE][GEOM_OCTREE] = &ShapeOcTreeDistance<Sphere>;
+  distance_matrix[GEOM_CAPSULE][GEOM_OCTREE] = &ShapeOcTreeDistance<Capsule>;
+  distance_matrix[GEOM_CONE][GEOM_OCTREE] = &ShapeOcTreeDistance<Cone>;
+  distance_matrix[GEOM_CYLINDER][GEOM_OCTREE] = &ShapeOcTreeDistance<Cylinder>;
+  distance_matrix[GEOM_CONVEX][GEOM_OCTREE] = &ShapeOcTreeDistance<Convex>;
+  distance_matrix[GEOM_PLANE][GEOM_OCTREE] = &ShapeOcTreeDistance<Plane>;
+  distance_matrix[GEOM_HALFSPACE][GEOM_OCTREE] = &ShapeOcTreeDistance<Halfspace>;
+
+  distance_matrix[GEOM_OCTREE][GEOM_OCTREE] = &OcTreeDistance;
+
+  distance_matrix[GEOM_OCTREE][BV_AABB] = &OcTreeBVHDistance<AABB>;
+  distance_matrix[GEOM_OCTREE][BV_OBB] = &OcTreeBVHDistance<OBB>;
+  distance_matrix[GEOM_OCTREE][BV_RSS] = &OcTreeBVHDistance<RSS>;
+  distance_matrix[GEOM_OCTREE][BV_OBBRSS] = &OcTreeBVHDistance<OBBRSS>;
+  distance_matrix[GEOM_OCTREE][BV_kIOS] = &OcTreeBVHDistance<kIOS>;
+  distance_matrix[GEOM_OCTREE][BV_KDOP16] = &OcTreeBVHDistance<KDOP<16>>;
+  distance_matrix[GEOM_OCTREE][BV_KDOP18] = &OcTreeBVHDistance<KDOP<18>>;
+  distance_matrix[GEOM_OCTREE][BV_KDOP24] = &OcTreeBVHDistance<KDOP<24>>;
+
+  distance_matrix[BV_AABB][GEOM_OCTREE] = &BVHOcTreeDistance<AABB>;
+  distance_matrix[BV_OBB][GEOM_OCTREE] = &BVHOcTreeDistance<OBB>;
+  distance_matrix[BV_RSS][GEOM_OCTREE] = &BVHOcTreeDistance<RSS>;
+  distance_matrix[BV_OBBRSS][GEOM_OCTREE] = &BVHOcTreeDistance<OBBRSS>;
+  distance_matrix[BV_kIOS][GEOM_OCTREE] = &BVHOcTreeDistance<kIOS>;
+  distance_matrix[BV_KDOP16][GEOM_OCTREE] = &BVHOcTreeDistance<KDOP<16>>;
+  distance_matrix[BV_KDOP18][GEOM_OCTREE] = &BVHOcTreeDistance<KDOP<18>>;
+  distance_matrix[BV_KDOP24][GEOM_OCTREE] = &BVHOcTreeDistance<KDOP<24>>;
 #endif
 
 
 }
-template struct DistanceFunctionMatrix<GJKSolver>;
+//template struct DistanceFunctionMatrix;
 }
 
 } // namespace hpp
diff --git a/src/distance_func_matrix.h b/src/distance_func_matrix.h
index 97e90780a3ff7dee186b91928b6a609e71fbcfea..f9a291ee897c58d895b960b2948999d12c416d6f 100644
--- a/src/distance_func_matrix.h
+++ b/src/distance_func_matrix.h
@@ -35,18 +35,19 @@
 /** \author Florent Lamiraux */
 
 #include <hpp/fcl/collision_data.h>
+#include <hpp/fcl/narrowphase/narrowphase.h>
 
 namespace hpp
 {
 namespace fcl {
-  template<typename T_SH1, typename T_SH2, typename GJKSolver>
+  template<typename T_SH1, typename T_SH2>
     FCL_REAL ShapeShapeDistance
     (const CollisionGeometry* o1, const Transform3f& tf1,
      const CollisionGeometry* o2, const Transform3f& tf2,
      const GJKSolver* nsolver, const DistanceRequest& request,
      DistanceResult& result);
 
-  template<typename T_SH1, typename T_SH2, typename GJKSolver>
+  template<typename T_SH1, typename T_SH2>
     std::size_t ShapeShapeCollide
     (const CollisionGeometry* o1, const Transform3f& tf1,
      const CollisionGeometry* o2, const Transform3f& tf2, 
diff --git a/src/distance_sphere_cylinder.cpp b/src/distance_sphere_cylinder.cpp
index bb3686182e68779e27d9099d32a4082ca337b2ba..ef031a97cdf914d807ca006add367d091c19f485 100644
--- a/src/distance_sphere_cylinder.cpp
+++ b/src/distance_sphere_cylinder.cpp
@@ -49,7 +49,7 @@ namespace fcl {
     class GJKSolver;
 
   template <>
-  FCL_REAL ShapeShapeDistance <Sphere, Cylinder, GJKSolver>
+  FCL_REAL ShapeShapeDistance <Sphere, Cylinder>
   (const CollisionGeometry* o1, const Transform3f& tf1,
    const CollisionGeometry* o2, const Transform3f& tf2,
    const GJKSolver*, const DistanceRequest&,
@@ -65,7 +65,7 @@ namespace fcl {
   }
 
   template <>
-  FCL_REAL ShapeShapeDistance <Cylinder, Sphere, GJKSolver>
+  FCL_REAL ShapeShapeDistance <Cylinder, Sphere>
   (const CollisionGeometry* o1, const Transform3f& tf1,
    const CollisionGeometry* o2, const Transform3f& tf2,
    const GJKSolver*, const DistanceRequest&,
diff --git a/src/distance_sphere_halfspace.cpp b/src/distance_sphere_halfspace.cpp
index 90bc6b86348050b0f0e67018c94214ac28c85d72..9060e173c3710c34f701d76befcbea288dace809 100644
--- a/src/distance_sphere_halfspace.cpp
+++ b/src/distance_sphere_halfspace.cpp
@@ -49,7 +49,7 @@ namespace fcl {
     class GJKSolver;
 
   template <>
-  FCL_REAL ShapeShapeDistance <Sphere, Halfspace, GJKSolver>
+  FCL_REAL ShapeShapeDistance <Sphere, Halfspace>
   (const CollisionGeometry* o1, const Transform3f& tf1,
    const CollisionGeometry* o2, const Transform3f& tf2,
    const GJKSolver*, const DistanceRequest&,
@@ -65,7 +65,7 @@ namespace fcl {
   }
 
   template <>
-  FCL_REAL ShapeShapeDistance <Halfspace, Sphere, GJKSolver>
+  FCL_REAL ShapeShapeDistance <Halfspace, Sphere>
   (const CollisionGeometry* o1, const Transform3f& tf1,
    const CollisionGeometry* o2, const Transform3f& tf2,
    const GJKSolver*, const DistanceRequest&,
diff --git a/src/distance_sphere_plane.cpp b/src/distance_sphere_plane.cpp
index 5e8ae30d61c6fcc9ef70a522ed1d386268dccb8f..89ebb150271700891580937bcefac4c6695ff6a1 100644
--- a/src/distance_sphere_plane.cpp
+++ b/src/distance_sphere_plane.cpp
@@ -49,7 +49,7 @@ namespace fcl {
     class GJKSolver;
 
   template <>
-  FCL_REAL ShapeShapeDistance <Sphere, Plane, GJKSolver>
+  FCL_REAL ShapeShapeDistance <Sphere, Plane>
   (const CollisionGeometry* o1, const Transform3f& tf1,
    const CollisionGeometry* o2, const Transform3f& tf2,
    const GJKSolver*, const DistanceRequest&,
@@ -65,7 +65,7 @@ namespace fcl {
   }
 
   template <>
-  FCL_REAL ShapeShapeDistance <Plane, Sphere, GJKSolver>
+  FCL_REAL ShapeShapeDistance <Plane, Sphere>
   (const CollisionGeometry* o1, const Transform3f& tf1,
    const CollisionGeometry* o2, const Transform3f& tf2,
    const GJKSolver*, const DistanceRequest&,
diff --git a/src/distance_sphere_sphere.cpp b/src/distance_sphere_sphere.cpp
index de0203096db54bbe0007e49832605c10285e9438..aeca9663ad61fb62a0b659afca5bf5fd547cc9da 100644
--- a/src/distance_sphere_sphere.cpp
+++ b/src/distance_sphere_sphere.cpp
@@ -53,7 +53,7 @@ namespace fcl {
   class GJKSolver;
 
   template <>
-  FCL_REAL ShapeShapeDistance <Sphere, Sphere, GJKSolver>
+  FCL_REAL ShapeShapeDistance <Sphere, Sphere>
   (const CollisionGeometry* o1, const Transform3f& tf1,
    const CollisionGeometry* o2, const Transform3f& tf2,
    const GJKSolver*, const DistanceRequest&,
@@ -97,7 +97,7 @@ namespace fcl {
   }
 
   template <>
-  std::size_t ShapeShapeCollide <Sphere, Sphere, GJKSolver>
+  std::size_t ShapeShapeCollide <Sphere, Sphere>
   (const CollisionGeometry* o1, const Transform3f& tf1,
    const CollisionGeometry* o2, const Transform3f& tf2,
    const GJKSolver*, const CollisionRequest& request,
diff --git a/src/traversal/traversal_node_bvh_shape.h b/src/traversal/traversal_node_bvh_shape.h
index 2ed8460b79f1f97f2c11403d87fc9228c74ea9a9..e931a392748039f7ef84fdd0f56724df8af1f91d 100644
--- a/src/traversal/traversal_node_bvh_shape.h
+++ b/src/traversal/traversal_node_bvh_shape.h
@@ -146,7 +146,7 @@ public:
 
 
 /// @brief Traversal node for collision between mesh and shape
-template<typename BV, typename S, typename GJKSolver,
+template<typename BV, typename S,
   int _Options = RelativeTransformationIsIdentity>
 class MeshShapeCollisionTraversalNode : public BVHShapeCollisionTraversalNode<BV, S>
 {
@@ -260,46 +260,46 @@ public:
 };
 
 /// @brief Traversal node for mesh and shape, when mesh BVH is one of the oriented node (OBB, RSS, OBBRSS, kIOS)
-template<typename S, typename GJKSolver>
-class MeshShapeCollisionTraversalNodeOBB : public MeshShapeCollisionTraversalNode<OBB, S, GJKSolver, 0>
+template<typename S>
+class MeshShapeCollisionTraversalNodeOBB : public MeshShapeCollisionTraversalNode<OBB, S, 0>
 {
 public:
   MeshShapeCollisionTraversalNodeOBB(const CollisionRequest& request) :
-  MeshShapeCollisionTraversalNode<OBB, S, GJKSolver, 0>
+  MeshShapeCollisionTraversalNode<OBB, S, 0>
     (request)
   {
   }
 
 };
 
-template<typename S, typename GJKSolver>
-class MeshShapeCollisionTraversalNodeRSS : public MeshShapeCollisionTraversalNode<RSS, S, GJKSolver, 0>
+template<typename S>
+class MeshShapeCollisionTraversalNodeRSS : public MeshShapeCollisionTraversalNode<RSS, S, 0>
 {
 public:
   MeshShapeCollisionTraversalNodeRSS (const CollisionRequest& request):
-  MeshShapeCollisionTraversalNode<RSS, S, GJKSolver, 0>
+  MeshShapeCollisionTraversalNode<RSS, S, 0>
     (request)
   {
   }
 };
 
-template<typename S, typename GJKSolver>
-class MeshShapeCollisionTraversalNodekIOS : public MeshShapeCollisionTraversalNode<kIOS, S, GJKSolver, 0>
+template<typename S>
+class MeshShapeCollisionTraversalNodekIOS : public MeshShapeCollisionTraversalNode<kIOS, S, 0>
 {
 public:
   MeshShapeCollisionTraversalNodekIOS(const CollisionRequest& request):
-  MeshShapeCollisionTraversalNode<kIOS, S, GJKSolver, 0>
+  MeshShapeCollisionTraversalNode<kIOS, S, 0>
     (request)
   {
   }
 };
 
-template<typename S, typename GJKSolver>
-class MeshShapeCollisionTraversalNodeOBBRSS : public MeshShapeCollisionTraversalNode<OBBRSS, S, GJKSolver, 0>
+template<typename S>
+class MeshShapeCollisionTraversalNodeOBBRSS : public MeshShapeCollisionTraversalNode<OBBRSS, S, 0>
 {
 public:
   MeshShapeCollisionTraversalNodeOBBRSS (const CollisionRequest& request) :
-  MeshShapeCollisionTraversalNode <OBBRSS, S, GJKSolver, 0>
+  MeshShapeCollisionTraversalNode <OBBRSS, S, 0>
     (request)
   {
   }
@@ -307,7 +307,7 @@ public:
 
 
 /// @brief Traversal node for collision between shape and mesh
-template<typename S, typename BV, typename GJKSolver,
+template<typename S, typename BV,
   int _Options = RelativeTransformationIsIdentity>
 class ShapeMeshCollisionTraversalNode : public ShapeBVHCollisionTraversalNode<S, BV>
 {
@@ -420,41 +420,41 @@ public:
 };
 
 /// @brief Traversal node for shape and mesh, when mesh BVH is one of the oriented node (OBB, RSS, OBBRSS, kIOS)
-template<typename S, typename GJKSolver>
-class ShapeMeshCollisionTraversalNodeOBB : public ShapeMeshCollisionTraversalNode<S, OBB, GJKSolver, 0>
+template<typename S>
+class ShapeMeshCollisionTraversalNodeOBB : public ShapeMeshCollisionTraversalNode<S, OBB, 0>
 {
 public:
-  ShapeMeshCollisionTraversalNodeOBB() : ShapeMeshCollisionTraversalNode<S, OBB, GJKSolver>()
+  ShapeMeshCollisionTraversalNodeOBB() : ShapeMeshCollisionTraversalNode<S, OBB>()
   {
   }
 };
 
 
-template<typename S, typename GJKSolver>
-class ShapeMeshCollisionTraversalNodeRSS : public ShapeMeshCollisionTraversalNode<S, RSS, GJKSolver, 0>
+template<typename S>
+class ShapeMeshCollisionTraversalNodeRSS : public ShapeMeshCollisionTraversalNode<S, RSS, 0>
 {
 public:
-  ShapeMeshCollisionTraversalNodeRSS() : ShapeMeshCollisionTraversalNode<S, RSS, GJKSolver>()
+  ShapeMeshCollisionTraversalNodeRSS() : ShapeMeshCollisionTraversalNode<S, RSS>()
   {
   }
 };
 
 
-template<typename S, typename GJKSolver>
-class ShapeMeshCollisionTraversalNodekIOS : public ShapeMeshCollisionTraversalNode<S, kIOS, GJKSolver, 0>
+template<typename S>
+class ShapeMeshCollisionTraversalNodekIOS : public ShapeMeshCollisionTraversalNode<S, kIOS, 0>
 {
 public:
-  ShapeMeshCollisionTraversalNodekIOS() : ShapeMeshCollisionTraversalNode<S, kIOS, GJKSolver>()
+  ShapeMeshCollisionTraversalNodekIOS() : ShapeMeshCollisionTraversalNode<S, kIOS>()
   {
   }
 };
 
 
-template<typename S, typename GJKSolver>
-class ShapeMeshCollisionTraversalNodeOBBRSS : public ShapeMeshCollisionTraversalNode<S, OBBRSS, GJKSolver, 0>
+template<typename S>
+class ShapeMeshCollisionTraversalNodeOBBRSS : public ShapeMeshCollisionTraversalNode<S, OBBRSS, 0>
 {
 public:
-  ShapeMeshCollisionTraversalNodeOBBRSS() : ShapeMeshCollisionTraversalNode<S, OBBRSS, GJKSolver>()
+  ShapeMeshCollisionTraversalNodeOBBRSS() : ShapeMeshCollisionTraversalNode<S, OBBRSS>()
   {
   }
 };
@@ -557,7 +557,7 @@ public:
                                   
 
 /// @brief Traversal node for distance between mesh and shape
-template<typename BV, typename S, typename GJKSolver>
+template<typename BV, typename S>
 class MeshShapeDistanceTraversalNode : public BVHShapeDistanceTraversalNode<BV, S>
 { 
 public:
@@ -619,7 +619,7 @@ public:
 namespace details
 {
 
-template<typename BV, typename S, typename GJKSolver>
+template<typename BV, typename S>
 void meshShapeDistanceOrientedNodeleafComputeDistance(int b1, int /* b2 */,
                                               const BVHModel<BV>* model1, const S& model2,
                                               Vec3f* vertices, Triangle* tri_indices,
@@ -651,7 +651,7 @@ void meshShapeDistanceOrientedNodeleafComputeDistance(int b1, int /* b2 */,
 }
 
 
-template<typename BV, typename S, typename GJKSolver>
+template<typename BV, typename S>
 static inline void distancePreprocessOrientedNode(const BVHModel<BV>* model1,
                                                   Vec3f* vertices, Triangle* tri_indices, int init_tri_id,
                                                   const S& model2, const Transform3f& tf1, const Transform3f& tf2,
@@ -682,11 +682,11 @@ static inline void distancePreprocessOrientedNode(const BVHModel<BV>* model1,
 
 
 /// @brief Traversal node for distance between mesh and shape, when mesh BVH is one of the oriented node (RSS, OBBRSS, kIOS)
-template<typename S, typename GJKSolver>
-class MeshShapeDistanceTraversalNodeRSS : public MeshShapeDistanceTraversalNode<RSS, S, GJKSolver>
+template<typename S>
+class MeshShapeDistanceTraversalNodeRSS : public MeshShapeDistanceTraversalNode<RSS, S>
 {
 public:
-  MeshShapeDistanceTraversalNodeRSS() : MeshShapeDistanceTraversalNode<RSS, S, GJKSolver>()
+  MeshShapeDistanceTraversalNodeRSS() : MeshShapeDistanceTraversalNode<RSS, S>()
   {
   }
 
@@ -714,11 +714,11 @@ public:
 };
 
 
-template<typename S, typename GJKSolver>
-class MeshShapeDistanceTraversalNodekIOS : public MeshShapeDistanceTraversalNode<kIOS, S, GJKSolver>
+template<typename S>
+class MeshShapeDistanceTraversalNodekIOS : public MeshShapeDistanceTraversalNode<kIOS, S>
 {
 public:
-  MeshShapeDistanceTraversalNodekIOS() : MeshShapeDistanceTraversalNode<kIOS, S, GJKSolver>()
+  MeshShapeDistanceTraversalNodekIOS() : MeshShapeDistanceTraversalNode<kIOS, S>()
   {
   }
 
@@ -746,11 +746,11 @@ public:
 
 };
 
-template<typename S, typename GJKSolver>
-class MeshShapeDistanceTraversalNodeOBBRSS : public MeshShapeDistanceTraversalNode<OBBRSS, S, GJKSolver>
+template<typename S>
+class MeshShapeDistanceTraversalNodeOBBRSS : public MeshShapeDistanceTraversalNode<OBBRSS, S>
 {
 public:
-  MeshShapeDistanceTraversalNodeOBBRSS() : MeshShapeDistanceTraversalNode<OBBRSS, S, GJKSolver>()
+  MeshShapeDistanceTraversalNodeOBBRSS() : MeshShapeDistanceTraversalNode<OBBRSS, S>()
   {
   }
 
@@ -780,7 +780,7 @@ public:
 };
 
 /// @brief Traversal node for distance between shape and mesh
-template<typename S, typename BV, typename GJKSolver>
+template<typename S, typename BV>
 class ShapeMeshDistanceTraversalNode : public ShapeBVHDistanceTraversalNode<S, BV>
 { 
 public:
@@ -838,11 +838,11 @@ public:
   const GJKSolver* nsolver;
 };
 
-template<typename S, typename GJKSolver>
-class ShapeMeshDistanceTraversalNodeRSS : public ShapeMeshDistanceTraversalNode<S, RSS, GJKSolver>
+template<typename S>
+class ShapeMeshDistanceTraversalNodeRSS : public ShapeMeshDistanceTraversalNode<S, RSS>
 {
 public:
-  ShapeMeshDistanceTraversalNodeRSS() : ShapeMeshDistanceTraversalNode<S, RSS, GJKSolver>()
+  ShapeMeshDistanceTraversalNodeRSS() : ShapeMeshDistanceTraversalNode<S, RSS>()
   {
   }
 
@@ -870,11 +870,11 @@ public:
 
 };
 
-template<typename S, typename GJKSolver>
-class ShapeMeshDistanceTraversalNodekIOS : public ShapeMeshDistanceTraversalNode<S, kIOS, GJKSolver>
+template<typename S>
+class ShapeMeshDistanceTraversalNodekIOS : public ShapeMeshDistanceTraversalNode<S, kIOS>
 {
 public:
-  ShapeMeshDistanceTraversalNodekIOS() : ShapeMeshDistanceTraversalNode<S, kIOS, GJKSolver>()
+  ShapeMeshDistanceTraversalNodekIOS() : ShapeMeshDistanceTraversalNode<S, kIOS>()
   {
   }
 
@@ -902,11 +902,11 @@ public:
   
 };
 
-template<typename S, typename GJKSolver>
-class ShapeMeshDistanceTraversalNodeOBBRSS : public ShapeMeshDistanceTraversalNode<S, OBBRSS, GJKSolver>
+template<typename S>
+class ShapeMeshDistanceTraversalNodeOBBRSS : public ShapeMeshDistanceTraversalNode<S, OBBRSS>
 {
 public:
-  ShapeMeshDistanceTraversalNodeOBBRSS() : ShapeMeshDistanceTraversalNode<S, OBBRSS, GJKSolver>()
+  ShapeMeshDistanceTraversalNodeOBBRSS() : ShapeMeshDistanceTraversalNode<S, OBBRSS>()
   {
   }
 
diff --git a/src/traversal/traversal_node_octree.h b/src/traversal/traversal_node_octree.h
index 270fb06d8432f99d1dc06918c673aeb400976d2e..c8f0f52220c39f9babaf1082b429ebcfcd0ebacf 100644
--- a/src/traversal/traversal_node_octree.h
+++ b/src/traversal/traversal_node_octree.h
@@ -51,7 +51,6 @@ namespace fcl
 {
 
 /// @brief Algorithms for collision related with octree
-template<typename GJKSolver>
 class OcTreeSolver
 {
 private:
@@ -890,7 +889,6 @@ private:
 
 
 /// @brief Traversal node for octree collision
-template<typename GJKSolver>
 class OcTreeCollisionTraversalNode : public CollisionTraversalNodeBase
 {
 public:
@@ -923,11 +921,10 @@ public:
 
   Transform3f tf1, tf2;
 
-  const OcTreeSolver<GJKSolver>* otsolver;
+  const OcTreeSolver* otsolver;
 };
 
 /// @brief Traversal node for octree distance
-template<typename GJKSolver>
 class OcTreeDistanceTraversalNode : public DistanceTraversalNodeBase
 {
 public:
@@ -958,11 +955,11 @@ public:
   const OcTree* model1;
   const OcTree* model2;
 
-  const OcTreeSolver<GJKSolver>* otsolver;
+  const OcTreeSolver* otsolver;
 };
 
 /// @brief Traversal node for shape-octree collision
-template<typename S, typename GJKSolver>
+template<typename S>
 class ShapeOcTreeCollisionTraversalNode : public CollisionTraversalNodeBase
 {
 public:
@@ -995,11 +992,11 @@ public:
 
   Transform3f tf1, tf2;
 
-  const OcTreeSolver<GJKSolver>* otsolver;
+  const OcTreeSolver* otsolver;
 };
 
 /// @brief Traversal node for octree-shape collision
-template<typename S, typename GJKSolver>
+template<typename S>
 class OcTreeShapeCollisionTraversalNode : public CollisionTraversalNodeBase
 {
 public:
@@ -1032,11 +1029,11 @@ public:
 
   Transform3f tf1, tf2;
  
-  const OcTreeSolver<GJKSolver>* otsolver;  
+  const OcTreeSolver* otsolver;  
 };
 
 /// @brief Traversal node for shape-octree distance
-template<typename S, typename GJKSolver>
+template<typename S>
 class ShapeOcTreeDistanceTraversalNode : public DistanceTraversalNodeBase
 {
 public:
@@ -1061,11 +1058,11 @@ public:
   const S* model1;
   const OcTree* model2;
 
-  const OcTreeSolver<GJKSolver>* otsolver;
+  const OcTreeSolver* otsolver;
 };
 
 /// @brief Traversal node for octree-shape distance
-template<typename S, typename GJKSolver>
+template<typename S>
 class OcTreeShapeDistanceTraversalNode : public DistanceTraversalNodeBase
 {
 public:
@@ -1090,11 +1087,11 @@ public:
   const OcTree* model1;
   const S* model2;
 
-  const OcTreeSolver<GJKSolver>* otsolver;
+  const OcTreeSolver* otsolver;
 };
 
 /// @brief Traversal node for mesh-octree collision
-template<typename BV, typename GJKSolver>
+template<typename BV>
 class MeshOcTreeCollisionTraversalNode : public CollisionTraversalNodeBase
 {
 public:
@@ -1127,11 +1124,11 @@ public:
 
   Transform3f tf1, tf2;
     
-  const OcTreeSolver<GJKSolver>* otsolver;
+  const OcTreeSolver* otsolver;
 };
 
 /// @brief Traversal node for octree-mesh collision
-template<typename BV, typename GJKSolver>
+template<typename BV>
 class OcTreeMeshCollisionTraversalNode : public CollisionTraversalNodeBase
 {
 public:
@@ -1164,11 +1161,11 @@ public:
 
   Transform3f tf1, tf2;
     
-  const OcTreeSolver<GJKSolver>* otsolver;
+  const OcTreeSolver* otsolver;
 };
 
 /// @brief Traversal node for mesh-octree distance
-template<typename BV, typename GJKSolver>
+template<typename BV>
 class MeshOcTreeDistanceTraversalNode : public DistanceTraversalNodeBase
 {
 public:
@@ -1193,12 +1190,12 @@ public:
   const BVHModel<BV>* model1;
   const OcTree* model2;
 
-  const OcTreeSolver<GJKSolver>* otsolver;
+  const OcTreeSolver* otsolver;
 
 };
 
 /// @brief Traversal node for octree-mesh distance
-template<typename BV, typename GJKSolver>
+template<typename BV>
 class OcTreeMeshDistanceTraversalNode : public DistanceTraversalNodeBase
 {
 public:
@@ -1223,7 +1220,7 @@ public:
   const OcTree* model1;
   const BVHModel<BV>* model2;
 
-  const OcTreeSolver<GJKSolver>* otsolver;
+  const OcTreeSolver* otsolver;
 
 };
 
diff --git a/src/traversal/traversal_node_setup.h b/src/traversal/traversal_node_setup.h
index d6d447fe429659863d64e771eeef10b5e18f880f..fcb3de58e392f5b795eb335e4f9cae9e2e0a002c 100644
--- a/src/traversal/traversal_node_setup.h
+++ b/src/traversal/traversal_node_setup.h
@@ -56,11 +56,10 @@ namespace fcl
 
 #ifdef HPP_FCL_HAVE_OCTOMAP
 /// @brief Initialize traversal node for collision between two octrees, given current object transform
-template<typename GJKSolver>
-bool initialize(OcTreeCollisionTraversalNode<GJKSolver>& node,
+bool initialize(OcTreeCollisionTraversalNode& node,
                 const OcTree& model1, const Transform3f& tf1,
                 const OcTree& model2, const Transform3f& tf2,
-                const OcTreeSolver<GJKSolver>* otsolver,
+                const OcTreeSolver* otsolver,
                 CollisionResult& result)
 {
   node.result = &result;
@@ -77,11 +76,10 @@ bool initialize(OcTreeCollisionTraversalNode<GJKSolver>& node,
 }
 
 /// @brief Initialize traversal node for distance between two octrees, given current object transform
-template<typename GJKSolver>
-bool initialize(OcTreeDistanceTraversalNode<GJKSolver>& node,
+bool initialize(OcTreeDistanceTraversalNode& node,
                 const OcTree& model1, const Transform3f& tf1,
                 const OcTree& model2, const Transform3f& tf2,
-                const OcTreeSolver<GJKSolver>* otsolver,
+                const OcTreeSolver* otsolver,
                 const DistanceRequest& request,
                 DistanceResult& result)
 {
@@ -100,11 +98,11 @@ bool initialize(OcTreeDistanceTraversalNode<GJKSolver>& node,
 }
 
 /// @brief Initialize traversal node for collision between one shape and one octree, given current object transform
-template<typename S, typename GJKSolver>
-bool initialize(ShapeOcTreeCollisionTraversalNode<S, GJKSolver>& node,
+template<typename S>
+bool initialize(ShapeOcTreeCollisionTraversalNode<S>& node,
                 const S& model1, const Transform3f& tf1,
                 const OcTree& model2, const Transform3f& tf2,
-                const OcTreeSolver<GJKSolver>* otsolver,
+                const OcTreeSolver* otsolver,
                 CollisionResult& result)
 {
   node.result = &result;
@@ -121,11 +119,11 @@ bool initialize(ShapeOcTreeCollisionTraversalNode<S, GJKSolver>& node,
 }
 
 /// @brief Initialize traversal node for collision between one octree and one shape, given current object transform
-template<typename S, typename GJKSolver>
-bool initialize(OcTreeShapeCollisionTraversalNode<S, GJKSolver>& node,
+template<typename S>
+bool initialize(OcTreeShapeCollisionTraversalNode<S>& node,
                 const OcTree& model1, const Transform3f& tf1,
                 const S& model2, const Transform3f& tf2,
-                const OcTreeSolver<GJKSolver>* otsolver,
+                const OcTreeSolver* otsolver,
                 CollisionResult& result)
 {
   node.result = &result;
@@ -142,11 +140,11 @@ bool initialize(OcTreeShapeCollisionTraversalNode<S, GJKSolver>& node,
 }
 
 /// @brief Initialize traversal node for distance between one shape and one octree, given current object transform
-template<typename S, typename GJKSolver>
-bool initialize(ShapeOcTreeDistanceTraversalNode<S, GJKSolver>& node,
+template<typename S>
+bool initialize(ShapeOcTreeDistanceTraversalNode<S>& node,
                 const S& model1, const Transform3f& tf1,
                 const OcTree& model2, const Transform3f& tf2,
-                const OcTreeSolver<GJKSolver>* otsolver,
+                const OcTreeSolver* otsolver,
                 const DistanceRequest& request,
                 DistanceResult& result)
 {
@@ -165,11 +163,11 @@ bool initialize(ShapeOcTreeDistanceTraversalNode<S, GJKSolver>& node,
 }
 
 /// @brief Initialize traversal node for distance between one octree and one shape, given current object transform
-template<typename S, typename GJKSolver>
-bool initialize(OcTreeShapeDistanceTraversalNode<S, GJKSolver>& node,
+template<typename S>
+bool initialize(OcTreeShapeDistanceTraversalNode<S>& node,
                 const OcTree& model1, const Transform3f& tf1,
                 const S& model2, const Transform3f& tf2,
-                const OcTreeSolver<GJKSolver>* otsolver,
+                const OcTreeSolver* otsolver,
                 const DistanceRequest& request,
                 DistanceResult& result)
 {
@@ -188,11 +186,11 @@ bool initialize(OcTreeShapeDistanceTraversalNode<S, GJKSolver>& node,
 }
 
 /// @brief Initialize traversal node for collision between one mesh and one octree, given current object transform
-template<typename BV, typename GJKSolver>
-bool initialize(MeshOcTreeCollisionTraversalNode<BV, GJKSolver>& node,
+template<typename BV>
+bool initialize(MeshOcTreeCollisionTraversalNode<BV>& node,
                 const BVHModel<BV>& model1, const Transform3f& tf1,
                 const OcTree& model2, const Transform3f& tf2,
-                const OcTreeSolver<GJKSolver>* otsolver,
+                const OcTreeSolver* otsolver,
                 CollisionResult& result)
 {
   node.result = &result;
@@ -209,11 +207,11 @@ bool initialize(MeshOcTreeCollisionTraversalNode<BV, GJKSolver>& node,
 }
 
 /// @brief Initialize traversal node for collision between one octree and one mesh, given current object transform
-template<typename BV, typename GJKSolver>
-bool initialize(OcTreeMeshCollisionTraversalNode<BV, GJKSolver>& node,
+template<typename BV>
+bool initialize(OcTreeMeshCollisionTraversalNode<BV>& node,
                 const OcTree& model1, const Transform3f& tf1,
                 const BVHModel<BV>& model2, const Transform3f& tf2,
-                const OcTreeSolver<GJKSolver>* otsolver,
+                const OcTreeSolver* otsolver,
                 CollisionResult& result)
 {
   node.result = &result;
@@ -230,11 +228,11 @@ bool initialize(OcTreeMeshCollisionTraversalNode<BV, GJKSolver>& node,
 }
 
 /// @brief Initialize traversal node for distance between one mesh and one octree, given current object transform
-template<typename BV, typename GJKSolver>
-bool initialize(MeshOcTreeDistanceTraversalNode<BV, GJKSolver>& node,
+template<typename BV>
+bool initialize(MeshOcTreeDistanceTraversalNode<BV>& node,
                 const BVHModel<BV>& model1, const Transform3f& tf1,
                 const OcTree& model2, const Transform3f& tf2,
-                const OcTreeSolver<GJKSolver>* otsolver,
+                const OcTreeSolver* otsolver,
                 const DistanceRequest& request,
                 DistanceResult& result)
 {
@@ -253,11 +251,11 @@ bool initialize(MeshOcTreeDistanceTraversalNode<BV, GJKSolver>& node,
 }
 
 /// @brief Initialize traversal node for collision between one octree and one mesh, given current object transform
-template<typename BV, typename GJKSolver>
-bool initialize(OcTreeMeshDistanceTraversalNode<BV, GJKSolver>& node,
+template<typename BV>
+bool initialize(OcTreeMeshDistanceTraversalNode<BV>& node,
                 const OcTree& model1, const Transform3f& tf1,
                 const BVHModel<BV>& model2, const Transform3f& tf2,
-                const OcTreeSolver<GJKSolver>* otsolver,
+                const OcTreeSolver* otsolver,
                 const DistanceRequest& request,
                 DistanceResult& result)
 {
@@ -279,8 +277,8 @@ bool initialize(OcTreeMeshDistanceTraversalNode<BV, GJKSolver>& node,
 
 
 /// @brief Initialize traversal node for collision between two geometric shapes, given current object transform
-template<typename S1, typename S2, typename GJKSolver>
-bool initialize(ShapeCollisionTraversalNode<S1, S2, GJKSolver>& node,
+template<typename S1, typename S2>
+bool initialize(ShapeCollisionTraversalNode<S1, S2>& node,
                 const S1& shape1, const Transform3f& tf1,
                 const S2& shape2, const Transform3f& tf2,
                 const GJKSolver* nsolver,
@@ -298,8 +296,8 @@ bool initialize(ShapeCollisionTraversalNode<S1, S2, GJKSolver>& node,
 }
 
 /// @brief Initialize traversal node for collision between one mesh and one shape, given current object transform
-template<typename BV, typename S, typename GJKSolver>
-bool initialize(MeshShapeCollisionTraversalNode<BV, S, GJKSolver>& node,
+template<typename BV, typename S>
+bool initialize(MeshShapeCollisionTraversalNode<BV, S>& node,
                 BVHModel<BV>& model1, Transform3f& tf1,
                 const S& model2, const Transform3f& tf2,
                 const GJKSolver* nsolver,
@@ -346,8 +344,8 @@ bool initialize(MeshShapeCollisionTraversalNode<BV, S, GJKSolver>& node,
 namespace details
 {
 
-template<typename BV, typename S, typename GJKSolver, template<typename, typename> class OrientedNode>
-static inline bool setupMeshShapeCollisionOrientedNode(OrientedNode<S, GJKSolver>& node, 
+template<typename BV, typename S, template<typename> class OrientedNode>
+static inline bool setupMeshShapeCollisionOrientedNode(OrientedNode<S>& node, 
                                                        const BVHModel<BV>& model1, const Transform3f& tf1,
                                                        const S& model2, const Transform3f& tf2,
                                                        const GJKSolver* nsolver,
@@ -378,8 +376,8 @@ static inline bool setupMeshShapeCollisionOrientedNode(OrientedNode<S, GJKSolver
 
 
 /// @brief Initialize the traversal node for collision between one mesh and one shape, specialized for OBB type
-template<typename S, typename GJKSolver>
-bool initialize(MeshShapeCollisionTraversalNodeOBB<S, GJKSolver>& node,
+template<typename S>
+bool initialize(MeshShapeCollisionTraversalNodeOBB<S>& node,
                 const BVHModel<OBB>& model1, const Transform3f& tf1,
                 const S& model2, const Transform3f& tf2,
                 const GJKSolver* nsolver,
@@ -389,8 +387,8 @@ bool initialize(MeshShapeCollisionTraversalNodeOBB<S, GJKSolver>& node,
 }
 
 /// @brief Initialize the traversal node for collision between one mesh and one shape, specialized for RSS type
-template<typename S, typename GJKSolver>
-bool initialize(MeshShapeCollisionTraversalNodeRSS<S, GJKSolver>& node,
+template<typename S>
+bool initialize(MeshShapeCollisionTraversalNodeRSS<S>& node,
                 const BVHModel<RSS>& model1, const Transform3f& tf1,
                 const S& model2, const Transform3f& tf2,
                 const GJKSolver* nsolver,
@@ -400,8 +398,8 @@ bool initialize(MeshShapeCollisionTraversalNodeRSS<S, GJKSolver>& node,
 }
 
 /// @brief Initialize the traversal node for collision between one mesh and one shape, specialized for kIOS type
-template<typename S, typename GJKSolver>
-bool initialize(MeshShapeCollisionTraversalNodekIOS<S, GJKSolver>& node,
+template<typename S>
+bool initialize(MeshShapeCollisionTraversalNodekIOS<S>& node,
                 const BVHModel<kIOS>& model1, const Transform3f& tf1,
                 const S& model2, const Transform3f& tf2,
                 const GJKSolver* nsolver,
@@ -411,8 +409,8 @@ bool initialize(MeshShapeCollisionTraversalNodekIOS<S, GJKSolver>& node,
 }
 
 /// @brief Initialize the traversal node for collision between one mesh and one shape, specialized for OBBRSS type
-template<typename S, typename GJKSolver>
-bool initialize(MeshShapeCollisionTraversalNodeOBBRSS<S, GJKSolver>& node,
+template<typename S>
+bool initialize(MeshShapeCollisionTraversalNodeOBBRSS<S>& node,
                 const BVHModel<OBBRSS>& model1, const Transform3f& tf1,
                 const S& model2, const Transform3f& tf2,
                 const GJKSolver* nsolver,
@@ -425,8 +423,8 @@ bool initialize(MeshShapeCollisionTraversalNodeOBBRSS<S, GJKSolver>& node,
 /// @cond IGNORE
 namespace details
 {
-template<typename S, typename BV, typename GJKSolver, template<typename, typename> class OrientedNode>
-static inline bool setupShapeMeshCollisionOrientedNode(OrientedNode<S, GJKSolver>& node, 
+template<typename S, typename BV, template<typename> class OrientedNode>
+static inline bool setupShapeMeshCollisionOrientedNode(OrientedNode<S>& node, 
                                                        const S& model1, const Transform3f& tf1,
                                                        const BVHModel<BV>& model2, const Transform3f& tf2,
                                                        const GJKSolver* nsolver,
@@ -544,8 +542,8 @@ bool initialize(MeshCollisionTraversalNode<BV, 0>& node,
 }
 
 /// @brief Initialize traversal node for distance between two geometric shapes
-template<typename S1, typename S2, typename GJKSolver>
-bool initialize(ShapeDistanceTraversalNode<S1, S2, GJKSolver>& node,
+template<typename S1, typename S2>
+bool initialize(ShapeDistanceTraversalNode<S1, S2>& node,
                 const S1& shape1, const Transform3f& tf1,
                 const S2& shape2, const Transform3f& tf2,
                 const GJKSolver* nsolver,
@@ -650,8 +648,8 @@ bool initialize(MeshDistanceTraversalNodeOBBRSS& node,
                 DistanceResult& result);
 
 /// @brief Initialize traversal node for distance computation between one mesh and one shape, given the current transforms
-template<typename BV, typename S, typename GJKSolver>
-bool initialize(MeshShapeDistanceTraversalNode<BV, S, GJKSolver>& node,
+template<typename BV, typename S>
+bool initialize(MeshShapeDistanceTraversalNode<BV, S>& node,
                 BVHModel<BV>& model1, Transform3f& tf1,
                 const S& model2, const Transform3f& tf2,
                 const GJKSolver* nsolver,
@@ -697,8 +695,8 @@ bool initialize(MeshShapeDistanceTraversalNode<BV, S, GJKSolver>& node,
 }
 
 /// @brief Initialize traversal node for distance computation between one shape and one mesh, given the current transforms
-template<typename S, typename BV, typename GJKSolver>
-bool initialize(ShapeMeshDistanceTraversalNode<S, BV, GJKSolver>& node,
+template<typename S, typename BV>
+bool initialize(ShapeMeshDistanceTraversalNode<S, BV>& node,
                 const S& model1, const Transform3f& tf1,
                 BVHModel<BV>& model2, Transform3f& tf2,
                 const GJKSolver* nsolver,
@@ -747,8 +745,8 @@ bool initialize(ShapeMeshDistanceTraversalNode<S, BV, GJKSolver>& node,
 namespace details
 {
 
-template<typename BV, typename S, typename GJKSolver, template<typename, typename> class OrientedNode>
-static inline bool setupMeshShapeDistanceOrientedNode(OrientedNode<S, GJKSolver>& node, 
+template<typename BV, typename S, template<typename> class OrientedNode>
+static inline bool setupMeshShapeDistanceOrientedNode(OrientedNode<S>& node, 
                                                       const BVHModel<BV>& model1, const Transform3f& tf1,
                                                       const S& model2, const Transform3f& tf2,
                                                       const GJKSolver* nsolver,
@@ -778,8 +776,8 @@ static inline bool setupMeshShapeDistanceOrientedNode(OrientedNode<S, GJKSolver>
 /// @endcond
 
 /// @brief Initialize traversal node for distance computation between one mesh and one shape, specialized for RSS type
-template<typename S, typename GJKSolver>
-bool initialize(MeshShapeDistanceTraversalNodeRSS<S, GJKSolver>& node,
+template<typename S>
+bool initialize(MeshShapeDistanceTraversalNodeRSS<S>& node,
                 const BVHModel<RSS>& model1, const Transform3f& tf1,
                 const S& model2, const Transform3f& tf2,
                 const GJKSolver* nsolver,
@@ -790,8 +788,8 @@ bool initialize(MeshShapeDistanceTraversalNodeRSS<S, GJKSolver>& node,
 }
 
 /// @brief Initialize traversal node for distance computation between one mesh and one shape, specialized for kIOS type
-template<typename S, typename GJKSolver>
-bool initialize(MeshShapeDistanceTraversalNodekIOS<S, GJKSolver>& node,
+template<typename S>
+bool initialize(MeshShapeDistanceTraversalNodekIOS<S>& node,
                 const BVHModel<kIOS>& model1, const Transform3f& tf1,
                 const S& model2, const Transform3f& tf2,
                 const GJKSolver* nsolver,
@@ -802,8 +800,8 @@ bool initialize(MeshShapeDistanceTraversalNodekIOS<S, GJKSolver>& node,
 }
 
 /// @brief Initialize traversal node for distance computation between one mesh and one shape, specialized for OBBRSS type
-template<typename S, typename GJKSolver>
-bool initialize(MeshShapeDistanceTraversalNodeOBBRSS<S, GJKSolver>& node,
+template<typename S>
+bool initialize(MeshShapeDistanceTraversalNodeOBBRSS<S>& node,
                 const BVHModel<OBBRSS>& model1, const Transform3f& tf1,
                 const S& model2, const Transform3f& tf2,
                 const GJKSolver* nsolver,
@@ -816,8 +814,8 @@ bool initialize(MeshShapeDistanceTraversalNodeOBBRSS<S, GJKSolver>& node,
 
 namespace details
 {
-template<typename S, typename BV, typename GJKSolver, template<typename, typename> class OrientedNode>
-static inline bool setupShapeMeshDistanceOrientedNode(OrientedNode<S, GJKSolver>& node,
+template<typename S, typename BV, template<typename> class OrientedNode>
+static inline bool setupShapeMeshDistanceOrientedNode(OrientedNode<S>& node,
                                                       const S& model1, const Transform3f& tf1,
                                                       const BVHModel<BV>& model2, const Transform3f& tf2,
                                                       const GJKSolver* nsolver,
@@ -849,8 +847,8 @@ static inline bool setupShapeMeshDistanceOrientedNode(OrientedNode<S, GJKSolver>
 
 
 /// @brief Initialize traversal node for distance computation between one shape and one mesh, specialized for RSS type
-template<typename S, typename GJKSolver>
-bool initialize(ShapeMeshDistanceTraversalNodeRSS<S, GJKSolver>& node,
+template<typename S>
+bool initialize(ShapeMeshDistanceTraversalNodeRSS<S>& node,
                 const S& model1, const Transform3f& tf1,
                 const BVHModel<RSS>& model2, const Transform3f& tf2,
                 const GJKSolver* nsolver,
@@ -861,8 +859,8 @@ bool initialize(ShapeMeshDistanceTraversalNodeRSS<S, GJKSolver>& node,
 }
 
 /// @brief Initialize traversal node for distance computation between one shape and one mesh, specialized for kIOS type
-template<typename S, typename GJKSolver>
-bool initialize(ShapeMeshDistanceTraversalNodekIOS<S, GJKSolver>& node,
+template<typename S>
+bool initialize(ShapeMeshDistanceTraversalNodekIOS<S>& node,
                 const S& model1, const Transform3f& tf1,
                 const BVHModel<kIOS>& model2, const Transform3f& tf2,
                 const GJKSolver* nsolver,
@@ -873,8 +871,8 @@ bool initialize(ShapeMeshDistanceTraversalNodekIOS<S, GJKSolver>& node,
 }
 
 /// @brief Initialize traversal node for distance computation between one shape and one mesh, specialized for OBBRSS type
-template<typename S, typename GJKSolver>
-bool initialize(ShapeMeshDistanceTraversalNodeOBBRSS<S, GJKSolver>& node,
+template<typename S>
+bool initialize(ShapeMeshDistanceTraversalNodeOBBRSS<S>& node,
                 const S& model1, const Transform3f& tf1,
                 const BVHModel<OBBRSS>& model2, const Transform3f& tf2,
                 const GJKSolver* nsolver,
diff --git a/src/traversal/traversal_node_shapes.h b/src/traversal/traversal_node_shapes.h
index 17be1e73f8b19d74ef01dd5709e81140cffd7970..902527343c5e3bba0a56e595c8558330dc68892c 100644
--- a/src/traversal/traversal_node_shapes.h
+++ b/src/traversal/traversal_node_shapes.h
@@ -53,7 +53,7 @@ namespace fcl
 
 
 /// @brief Traversal node for collision between two shapes
-template<typename S1, typename S2, typename GJKSolver>
+template<typename S1, typename S2>
 class ShapeCollisionTraversalNode : public CollisionTraversalNodeBase
 {
 public:
@@ -115,7 +115,7 @@ public:
 };
 
 /// @brief Traversal node for distance between two shapes
-template<typename S1, typename S2, typename GJKSolver>
+template<typename S1, typename S2>
 class ShapeDistanceTraversalNode : public DistanceTraversalNodeBase
 {
 public:
diff --git a/test/profiling.cpp b/test/profiling.cpp
index 6bfcfab8de5d28d4386f1d2147b9a6b63cd8647b..2e96e4c82abe0ece23c4d3c4398b91c708441db2 100644
--- a/test/profiling.cpp
+++ b/test/profiling.cpp
@@ -31,7 +31,7 @@
 
 using namespace hpp::fcl;
 
-CollisionFunctionMatrix<GJKSolver> lookupTable;
+CollisionFunctionMatrix lookupTable;
 bool supportedPair(const CollisionGeometry* o1, const CollisionGeometry* o2)
 {
   OBJECT_TYPE object_type1 = o1->getObjectType();