diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4ddca1f9b1dfc8e9852199f244c1b767eb1b2f2b..0b0b3f923389a1248342e87c9d26c60ca6903f50 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,7 +2,7 @@
 # Software License Agreement (BSD License)
 #
 #  Copyright (c) 2014 CNRS-LAAS
-#  Author: Florent Lamiraux
+#  Author: Florent Lamiraux, Joseph Mirabel
 #  All rights reserved.
 #
 #  Redistribution and use in source and binary forms, with or without
@@ -35,6 +35,7 @@
 cmake_minimum_required(VERSION 2.8)
 set(CXX_DISABLE_WERROR TRUE)
 include(cmake/base.cmake)
+include(cmake/eigen.cmake)
 include(cmake/boost.cmake)
 
 set(PROJECT_NAME hpp-fcl)
@@ -45,6 +46,16 @@ set(PROJECT_URL "http://github.com/humanoid-path-planner/hpp-fcl")
 
 setup_project()
 
+set(FCL_HAVE_SSE FALSE CACHE BOOL "Enable SSE vectorization")
+
+add_optional_dependency("eigen3 >= 3.0.0")
+set(FCL_HAVE_EIGEN  ${EIGEN3_FOUND} CACHE BOOL "Use eigen matrix type when possible")
+if (EIGEN3_FOUND)
+  if (FCL_HAVE_EIGEN)
+    include_directories(${EIGEN3_INCLUDE_DIRS})
+  endif (FCL_HAVE_EIGEN)
+endif (EIGEN3_FOUND)
+
 # Required dependencies
 add_required_dependency("ccd >= 1.4")
 set(BOOST_COMPONENTS
@@ -129,7 +140,9 @@ SET(${PROJECT_NAME}_HEADERS
   include/hpp/fcl/continuous_collision.h
   include/hpp/fcl/math/vec_nf.h
   include/hpp/fcl/math/matrix_3f.h
+  include/hpp/fcl/math/matrix_3fx.h
   include/hpp/fcl/math/vec_3f.h
+  include/hpp/fcl/math/vec_3fx.h
   include/hpp/fcl/math/sampling.h
   include/hpp/fcl/math/math_details.h
   include/hpp/fcl/math/transform.h
@@ -156,6 +169,12 @@ SET(${PROJECT_NAME}_HEADERS
   include/hpp/fcl/collision_object.h
   include/hpp/fcl/octree.h
   include/hpp/fcl/fwd.hh
+  include/hpp/fcl/eigen/math_details.h
+  include/hpp/fcl/eigen/vec_3fx.h
+  include/hpp/fcl/eigen/product.h
+  include/hpp/fcl/eigen/taylor_operator.h
+  include/hpp/fcl/eigen/plugins/ccd/interval-matrix.h
+  include/hpp/fcl/eigen/plugins/ccd/interval-vector.h
   )
 
 add_subdirectory(src)
diff --git a/cmake b/cmake
index 7cdd2146508a3431adb8e5a0d4233704080299cd..5663a002a905b5c8d84a69d8e74044a8e34a48ed 160000
--- a/cmake
+++ b/cmake
@@ -1 +1 @@
-Subproject commit 7cdd2146508a3431adb8e5a0d4233704080299cd
+Subproject commit 5663a002a905b5c8d84a69d8e74044a8e34a48ed
diff --git a/include/hpp/fcl/BV/BV.h b/include/hpp/fcl/BV/BV.h
index d81186404c36570e36e4f22314a8197d103da444..957672fdbe91d84cd6f21dac312a586811826e38 100644
--- a/include/hpp/fcl/BV/BV.h
+++ b/include/hpp/fcl/BV/BV.h
@@ -283,7 +283,7 @@ public:
 
     const Matrix3f& R = tf1.getRotation();
     bool left_hand = (id[0] == (id[1] + 1) % 3);
-    bv2.axis[0] = left_hand ? -R.getColumn(id[0]) : R.getColumn(id[0]);
+    if (left_hand) bv2.axis[0] = -R.getColumn(id[0]); else bv2.axis[0] = R.getColumn(id[0]);
     bv2.axis[1] = R.getColumn(id[1]);
     bv2.axis[2] = R.getColumn(id[2]);    
   }
diff --git a/include/hpp/fcl/BV/OBB.h b/include/hpp/fcl/BV/OBB.h
index 1dcd716065498d3933cd088c874ebc4a11cfd347..e720480525930e5675d8f9ab9f8a618ae25851f4 100644
--- a/include/hpp/fcl/BV/OBB.h
+++ b/include/hpp/fcl/BV/OBB.h
@@ -71,7 +71,7 @@ public:
 
   
   /// @brief Check collision between two OBB and return the overlap part. For OBB, the overlap_part return value is NOT used as the overlap part of two obbs usually is not an obb. 
-  bool overlap(const OBB& other, OBB& overlap_part) const
+  bool overlap(const OBB& other, OBB& /*overlap_part*/) const
   {
     return overlap(other);
   }
diff --git a/include/hpp/fcl/BV/OBBRSS.h b/include/hpp/fcl/BV/OBBRSS.h
index 5b3b9532dce74a9b26a2de130ee589162ad8a2ea..376413fea410333803d551e89fe5a6fc1b92a7f6 100644
--- a/include/hpp/fcl/BV/OBBRSS.h
+++ b/include/hpp/fcl/BV/OBBRSS.h
@@ -72,7 +72,7 @@ public:
   }
 
   /// @brief Check collision between two OBBRSS and return the overlap part.
-  bool overlap(const OBBRSS& other, OBBRSS& overlap_part) const
+  bool overlap(const OBBRSS& other, OBBRSS& /*overlap_part*/) const
   {
     return overlap(other);
   }
diff --git a/include/hpp/fcl/BV/RSS.h b/include/hpp/fcl/BV/RSS.h
index 4e42bab3c72de5986caecdef79699b11b8142189..7dc79c3c0fc0e0cf0e2f5bbe6bba55e678a8d6ad 100644
--- a/include/hpp/fcl/BV/RSS.h
+++ b/include/hpp/fcl/BV/RSS.h
@@ -67,7 +67,7 @@ public:
   bool overlap(const RSS& other) const;
 
   /// Not implemented
-  bool overlap(const RSS& other, FCL_REAL& sqrDistLowerBound) const
+  bool overlap(const RSS& /*other*/, FCL_REAL& /*sqrDistLowerBound*/) const
   {
     throw std::runtime_error ("Not implemented.");
     return false;
@@ -75,7 +75,7 @@ public:
 
   /// @brief Check collision between two RSS and return the overlap part.
   /// For RSS, we return nothing, as the overlap part of two RSSs usually is not a RSS.
-  bool overlap(const RSS& other, RSS& overlap_part) const
+  bool overlap(const RSS& other, RSS& /*overlap_part*/) const
   {
     return overlap(other);
   }
diff --git a/include/hpp/fcl/BV/kDOP.h b/include/hpp/fcl/BV/kDOP.h
index eb102f96ae6dd60830d4e671d0b88a4261b439ad..f38ccce92fa644e2032c55576c48d7f3f5129fa3 100644
--- a/include/hpp/fcl/BV/kDOP.h
+++ b/include/hpp/fcl/BV/kDOP.h
@@ -97,7 +97,7 @@ public:
   bool overlap(const KDOP<N>& other) const;
 
   /// Not implemented
-  bool overlap(const KDOP<N>& other, FCL_REAL&) const
+  bool overlap(const KDOP<N>& /*other*/, FCL_REAL&) const
   {
     throw std::runtime_error ("Not implemented");
   }
diff --git a/include/hpp/fcl/BV/kIOS.h b/include/hpp/fcl/BV/kIOS.h
index 8df8b9f1685ee1d96a4073714511bb9b921075d7..5bda122cab7f5ecbe82652f60d105dc2729a822d 100644
--- a/include/hpp/fcl/BV/kIOS.h
+++ b/include/hpp/fcl/BV/kIOS.h
@@ -69,7 +69,7 @@ class kIOS
     }
     else /** spheres partially overlapping or disjoint */
     {
-      float dist = std::sqrt(dist2);
+      float dist = (float)std::sqrt(dist2);
       kIOS_Sphere s;
       s.r = dist + s0.r + s1.r;
       if(dist > 0)
@@ -99,7 +99,7 @@ public:
   /// @brief Check collision between two kIOS and return the overlap part.
   /// For kIOS, we return nothing, as the overlappart of two kIOS usually is not an kIOS
   /// @todo Not efficient. It first checks the sphere collisions and then use OBB for further culling.
-  bool overlap(const kIOS& other, kIOS& overlap_part) const
+  bool overlap(const kIOS& other, kIOS& /*overlap_part*/) const
   {
     return overlap(other);
   }
diff --git a/include/hpp/fcl/BVH/BVH_internal.h b/include/hpp/fcl/BVH/BVH_internal.h
index b7fd4147b9e37686e806393fc292d4f147369644..3bed65800cb415eed4d3d9389a45405ca5dd2596 100644
--- a/include/hpp/fcl/BVH/BVH_internal.h
+++ b/include/hpp/fcl/BVH/BVH_internal.h
@@ -54,7 +54,7 @@ enum BVHBuildState
     BVH_BUILD_STATE_PROCESSED,        /// after tree has been build, ready for cd use
     BVH_BUILD_STATE_UPDATE_BEGUN,     /// after beginUpdateModel(), state for updating geometry primitives
     BVH_BUILD_STATE_UPDATED,          /// after tree has been build for updated geometry, ready for ccd use
-    BVH_BUILD_STATE_REPLACE_BEGUN,    /// after beginReplaceModel(), state for replacing geometry primitives
+    BVH_BUILD_STATE_REPLACE_BEGUN     /// after beginReplaceModel(), state for replacing geometry primitives
   };
 
 /// @brief Error code for BVH 
diff --git a/include/hpp/fcl/broadphase/broadphase.h b/include/hpp/fcl/broadphase/broadphase.h
index 04311be5d15f86fe380fdb29e8ccc7890812265b..de22336e20077fa056f5f29fbaf159602b7a3213 100644
--- a/include/hpp/fcl/broadphase/broadphase.h
+++ b/include/hpp/fcl/broadphase/broadphase.h
@@ -85,13 +85,13 @@ public:
   virtual void update() = 0;
 
   /// @brief update the manager by explicitly given the object updated
-  virtual void update(CollisionObject* updated_obj)
+  virtual void update(CollisionObject* /*updated_obj*/)
   {
     update();
   }
 
   /// @brief update the manager by explicitly given the set of objects update
-  virtual void update(const std::vector<CollisionObject*>& updated_objs)
+  virtual void update(const std::vector<CollisionObject*>& /*updated_objs*/)
   {
     update();
   }
@@ -184,13 +184,13 @@ public:
   virtual void update() = 0;
 
   /// @brief update the manager by explicitly given the object updated
-  virtual void update(ContinuousCollisionObject* updated_obj)
+  virtual void update(ContinuousCollisionObject* /*updated_obj*/)
   {
     update();
   }
 
   /// @brief update the manager by explicitly given the set of objects update
-  virtual void update(const std::vector<ContinuousCollisionObject*>& updated_objs)
+  virtual void update(const std::vector<ContinuousCollisionObject*>& /*updated_objs*/)
   {
     update();
   }
diff --git a/include/hpp/fcl/ccd/interval_matrix.h b/include/hpp/fcl/ccd/interval_matrix.h
index f828387a26804588a37d5497dd02a3cac2071ea8..6ad14b0daf4683257979074ffec4cfda5f8c9327 100644
--- a/include/hpp/fcl/ccd/interval_matrix.h
+++ b/include/hpp/fcl/ccd/interval_matrix.h
@@ -99,6 +99,10 @@ struct IMatrix3
   IMatrix3& rotationConstrain();
 
   void print() const;
+
+#ifdef FCL_CCD_INTERVALMATRIX_PLUGIN
+# include FCL_CCD_INTERVALMATRIX_PLUGIN
+#endif
 };
 
 IMatrix3 rotationConstrain(const IMatrix3& m);
diff --git a/include/hpp/fcl/ccd/interval_vector.h b/include/hpp/fcl/ccd/interval_vector.h
index f5b71b640294b07ebceeea425c172aac70e4cdd1..7c1216b901887c7f1853cdde55f874fb42d27bde 100644
--- a/include/hpp/fcl/ccd/interval_vector.h
+++ b/include/hpp/fcl/ccd/interval_vector.h
@@ -156,6 +156,10 @@ struct IVector3
 
   bool overlap(const IVector3& v) const;
   bool contain(const IVector3& v) const;
+
+#ifdef FCL_CCD_INTERVALVECTOR_PLUGIN
+# include FCL_CCD_INTERVALVECTOR_PLUGIN
+#endif
 };
 
 IVector3 bound(const IVector3& i, const Vec3f& v);
diff --git a/include/hpp/fcl/ccd/motion.h b/include/hpp/fcl/ccd/motion.h
index c54d3398fdc8b7153661caa2d97720166f5f4124..7f2af4718d7bb8145a58f1d24dd52c3363a5594a 100644
--- a/include/hpp/fcl/ccd/motion.h
+++ b/include/hpp/fcl/ccd/motion.h
@@ -88,7 +88,7 @@ public:
     tf_ = tf;
   }
 
-  void getTaylorModel(TMatrix3& tm, TVector3& tv) const
+  void getTaylorModel(TMatrix3& /*tm*/, TVector3& /*tv*/) const
   {
   }
 
@@ -113,14 +113,14 @@ public:
                const Vec3f& Rd0, const Vec3f& Rd1, const Vec3f& Rd2, const Vec3f& Rd3);
 
   // @brief Construct motion from initial and goal transform
-  SplineMotion(const Matrix3f& R1, const Vec3f& T1,
-               const Matrix3f& R2, const Vec3f& T2) : MotionBase()
+  SplineMotion(const Matrix3f& /*R1*/, const Vec3f& /*T1*/,
+               const Matrix3f& /*R2*/, const Vec3f& /*T2*/) : MotionBase()
   {
     // TODO
   }
 
-  SplineMotion(const Transform3f& tf1,
-               const Transform3f& tf2) : MotionBase()
+  SplineMotion(const Transform3f& /*tf1*/,
+               const Transform3f& /*tf2*/) : MotionBase()
   {
     // TODO
   }
diff --git a/include/hpp/fcl/ccd/motion_base.h b/include/hpp/fcl/ccd/motion_base.h
index 500888e6af1eb422f6e9d05dc551e89b62fc64a7..8f2656e77f70e3aafc5f70daa8b5806f3776f9be 100644
--- a/include/hpp/fcl/ccd/motion_base.h
+++ b/include/hpp/fcl/ccd/motion_base.h
@@ -72,11 +72,11 @@ class TBVMotionBoundVisitor : public BVMotionBoundVisitor
 public:
   TBVMotionBoundVisitor(const BV& bv_, const Vec3f& n_) : bv(bv_), n(n_) {}
 
-  virtual FCL_REAL visit(const MotionBase& motion) const { return 0; }
-  virtual FCL_REAL visit(const SplineMotion& motion) const { return 0; }
-  virtual FCL_REAL visit(const ScrewMotion& motion) const { return 0; }
-  virtual FCL_REAL visit(const InterpMotion& motion) const { return 0; }
-  virtual FCL_REAL visit(const TranslationMotion& motion) const { return 0; }
+  virtual FCL_REAL visit(const MotionBase& /*motion*/) const { return 0; }
+  virtual FCL_REAL visit(const SplineMotion& /*motion*/) const { return 0; }
+  virtual FCL_REAL visit(const ScrewMotion& /*motion*/) const { return 0; }
+  virtual FCL_REAL visit(const InterpMotion& /*motion*/) const { return 0; }
+  virtual FCL_REAL visit(const TranslationMotion& /*motion*/) const { return 0; }
 
 protected:
   BV bv;
@@ -102,7 +102,7 @@ public:
   TriangleMotionBoundVisitor(const Vec3f& a_, const Vec3f& b_, const Vec3f& c_, const Vec3f& n_) :
     a(a_), b(b_), c(c_), n(n_) {}
 
-  virtual FCL_REAL visit(const MotionBase& motion) const { return 0; }
+  virtual FCL_REAL visit(const MotionBase& /*motion*/) const { return 0; }
   virtual FCL_REAL visit(const SplineMotion& motion) const;
   virtual FCL_REAL visit(const ScrewMotion& motion) const;
   virtual FCL_REAL visit(const InterpMotion& motion) const;
diff --git a/include/hpp/fcl/ccd/taylor_vector.h b/include/hpp/fcl/ccd/taylor_vector.h
index a17c262ab06104746a6905e60a282ea142d41003..be570a38c55501fc975dd1565ac10516ac352333 100644
--- a/include/hpp/fcl/ccd/taylor_vector.h
+++ b/include/hpp/fcl/ccd/taylor_vector.h
@@ -41,6 +41,10 @@
 #include <hpp/fcl/ccd/interval_vector.h>
 #include <hpp/fcl/ccd/taylor_model.h>
 
+#if FCL_HAVE_EIGEN
+#include <hpp/fcl/eigen/taylor_operator.h>
+#endif
+
 namespace fcl
 {
 
diff --git a/include/hpp/fcl/config-fcl.hh.in b/include/hpp/fcl/config-fcl.hh.in
index 14cc27ddfd5960d453ca509ef6444dc2e60e292d..e8a2448f228a288f0ec446edacfa5bb81fe23a6c 100644
--- a/include/hpp/fcl/config-fcl.hh.in
+++ b/include/hpp/fcl/config-fcl.hh.in
@@ -37,6 +37,8 @@
 
 # include "config.h"
 
+#cmakedefine01 FCL_HAVE_EIGEN
+
 #cmakedefine01 FCL_HAVE_SSE
 #cmakedefine01 FCL_HAVE_OCTOMAP
 #cmakedefine01 FCL_HAVE_FLANN
diff --git a/include/hpp/fcl/eigen/math_details.h b/include/hpp/fcl/eigen/math_details.h
new file mode 100644
index 0000000000000000000000000000000000000000..c1ed7fd54feb04ab08360dd7423b1a4d7ea12fb7
--- /dev/null
+++ b/include/hpp/fcl/eigen/math_details.h
@@ -0,0 +1,782 @@
+/*
+ * Software License Agreement (BSD License)
+ *
+ *  Copyright (c) 2011-2014, Willow Garage, Inc.
+ *  Copyright (c) 2014-2015, Open Source Robotics Foundation
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of Open Source Robotics Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** \author Joseph Mirabel */
+
+#ifndef FCL_EIGEN_DETAILS_H
+#define FCL_EIGEN_DETAILS_H
+
+#include <Eigen/Dense>
+#include <Eigen/Geometry>
+
+namespace fcl
+{
+
+namespace details
+{
+
+template <typename T>
+struct eigen_wrapper_v3
+{
+  typedef T meta_type;
+  typedef Eigen::Matrix <T, 3, 1> vector_type;
+
+  vector_type v;
+
+  eigen_wrapper_v3() { setValue(0); }
+
+  template <typename Derived>
+    eigen_wrapper_v3(const Eigen::MatrixBase <Derived>& value) :
+      v (value)
+  {}
+
+  eigen_wrapper_v3(T x) :
+    v (vector_type::Constant (x))
+  {}
+
+  eigen_wrapper_v3(T* x) :
+    v (vector_type::Constant (*x))
+  {}
+
+  eigen_wrapper_v3(T x, T y, T z) :
+    v (x, y, z)
+  {}
+
+  inline void setValue(T x, T y, T z)
+  {
+    v << x, y, z;
+  }
+
+  inline void setValue(T x)
+  {
+    v.setConstant (x);
+  }
+
+  inline void negate()
+  {
+    v *= -1;
+  }
+
+  inline eigen_wrapper_v3<T>& ubound(const eigen_wrapper_v3<T>& u)
+  {
+    v = v.cwiseMin (u.v);
+    return *this;
+  }
+
+  inline eigen_wrapper_v3<T>& lbound(const eigen_wrapper_v3<T>& l)
+  {
+    v = v.cwiseMax (l.v);
+    return *this;
+  }
+
+  T operator [] (size_t i) const { return v[i]; }
+  T& operator [] (size_t i) { return v[i]; }
+
+  inline eigen_wrapper_v3<T> operator + (const eigen_wrapper_v3<T>& other) const { return eigen_wrapper_v3<T>(v + other.v); }
+  inline eigen_wrapper_v3<T> operator - (const eigen_wrapper_v3<T>& other) const { return eigen_wrapper_v3<T>(v - other.v); }
+  inline eigen_wrapper_v3<T> operator * (const eigen_wrapper_v3<T>& other) const { return eigen_wrapper_v3<T>(v.cwiseProduct (other.v)); }
+  inline eigen_wrapper_v3<T> operator / (const eigen_wrapper_v3<T>& other) const { return (eigen_wrapper_v3<T>(v) /= other); }
+  inline eigen_wrapper_v3<T>& operator += (const eigen_wrapper_v3<T>& other) { v += other.v; return *this; }
+  inline eigen_wrapper_v3<T>& operator -= (const eigen_wrapper_v3<T>& other) { v -= other.v; return *this; }
+  inline eigen_wrapper_v3<T>& operator *= (const eigen_wrapper_v3<T>& other) { v = v.cwiseProduct  (other.v); return *this; }
+  inline eigen_wrapper_v3<T>& operator /= (const eigen_wrapper_v3<T>& other) { v = v.cwiseQuotient (other.v); return *this; }
+  inline eigen_wrapper_v3<T> operator + (T t) const { return eigen_wrapper_v3<T>((v.array() + t).matrix()); }
+  inline eigen_wrapper_v3<T> operator - (T t) const { return eigen_wrapper_v3<T>((v.array() - t).matrix()); }
+  inline eigen_wrapper_v3<T> operator * (T t) const { return eigen_wrapper_v3<T>(v * t); }
+  inline eigen_wrapper_v3<T> operator / (T t) const { return eigen_wrapper_v3<T>(v / t); }
+  inline eigen_wrapper_v3<T>& operator += (T t) { v.array() += t; return *this; }
+  inline eigen_wrapper_v3<T>& operator -= (T t) { v.array() -= t; return *this; }
+  inline eigen_wrapper_v3<T>& operator *= (T t) { v.array() *= t; return *this; }
+  inline eigen_wrapper_v3<T>& operator /= (T t) { v.array() /= t; return *this; }
+  inline eigen_wrapper_v3<T> operator - () const { return eigen_wrapper_v3<T>(-v); }
+};
+
+
+template <typename T>
+static inline eigen_wrapper_v3<T> cross_prod(const eigen_wrapper_v3<T>& l, const eigen_wrapper_v3<T>& r)
+{
+  return eigen_wrapper_v3<T>(l.v.cross (r.v));
+}
+
+template <typename T>
+static inline T dot_prod3(const eigen_wrapper_v3<T>& l, const eigen_wrapper_v3<T>& r)
+{
+  return l.v.dot(r.v);
+}
+
+template <typename T>
+static inline eigen_wrapper_v3<T> min(const eigen_wrapper_v3<T>& x, const eigen_wrapper_v3<T>& y)
+{
+  return eigen_wrapper_v3<T>(x.v.cwiseMin (y.v));
+}
+
+template <typename T>
+static inline eigen_wrapper_v3<T> max(const eigen_wrapper_v3<T>& x, const eigen_wrapper_v3<T>& y)
+{
+  return eigen_wrapper_v3<T>(x.v.cwiseMax(y.v));
+}
+
+template <typename T>
+static inline eigen_wrapper_v3<T> abs(const eigen_wrapper_v3<T>& x)
+{
+  return eigen_wrapper_v3<T>(x.v.cwiseAbs());
+}
+
+template <typename T>
+static inline bool equal(const eigen_wrapper_v3<T>& x, const eigen_wrapper_v3<T>& y, T epsilon)
+{
+  return ((x.v - y.v).cwiseAbs ().array () < epsilon).all();
+}
+
+namespace internal {
+  template <typename Derived, int Size> struct assign {
+    static Eigen::Matrix<typename Derived::Scalar, 4, 1> run (const Eigen::MatrixBase <Derived>& value)
+    {
+      assert (false);
+    }
+  };
+
+  template <typename Derived> struct assign <Derived, 3> {
+    static Eigen::Matrix<typename Derived::Scalar, 4, 1> run (const Eigen::MatrixBase <Derived>& value)
+    {
+      return (Eigen::Matrix<typename Derived::Scalar, 4, 1> () << value, 0).finished ();
+    }
+  };
+
+  template <typename Derived> struct assign <Derived, 4> {
+    static Eigen::Matrix<typename Derived::Scalar, 4, 1> run (const Eigen::MatrixBase <Derived>& value)
+    {
+      return value;
+    }
+  };
+}
+
+template <typename T>
+struct eigen_wrapper_v4
+{
+  typedef T meta_type;
+  typedef Eigen::Matrix <T, 4, 1> vector_type;
+
+  vector_type v;
+
+  eigen_wrapper_v4() { setValue(0); }
+
+  template <typename Derived>
+    eigen_wrapper_v4(const Eigen::MatrixBase <Derived>& value) :
+      v (internal::assign <Derived, Derived::SizeAtCompileTime>::run (value))
+  {}
+
+  eigen_wrapper_v4(T x) :
+    v (vector_type::Constant (x))
+  {
+    v[3] = 0;
+  }
+
+  eigen_wrapper_v4(T* x) :
+    v (vector_type::Constant (*x))
+  {
+    v[3] = 0;
+  }
+
+  eigen_wrapper_v4(T x, T y, T z) :
+    v (x, y, z, 0)
+  {}
+
+  inline typename vector_type::template FixedSegmentReturnType<3>::Type d () { return v.template head <3> (); }
+
+  inline typename vector_type::template ConstFixedSegmentReturnType<3>::Type d () const { return v.template head <3> (); }
+
+  inline void setValue(T x, T y, T z, T w = 0)
+  {
+    v << x, y, z, w;
+  }
+
+  inline void setValue(T x)
+  {
+    d().setConstant (x);
+    v[3] = 0;
+  }
+
+  inline void negate()
+  {
+    v *= -1;
+  }
+
+  inline eigen_wrapper_v4<T>& ubound(const eigen_wrapper_v4<T>& u)
+  {
+    v = v.cwiseMin (u.v);
+    return *this;
+  }
+
+  inline eigen_wrapper_v4<T>& lbound(const eigen_wrapper_v4<T>& l)
+  {
+    v = v.cwiseMax (l.v);
+    return *this;
+  }
+
+  T operator [] (size_t i) const { return v[i]; }
+  T& operator [] (size_t i) { return v[i]; }
+
+  inline eigen_wrapper_v4<T> operator + (const eigen_wrapper_v4<T>& other) const { return eigen_wrapper_v4<T>(v + other.v); }
+  inline eigen_wrapper_v4<T> operator - (const eigen_wrapper_v4<T>& other) const { return eigen_wrapper_v4<T>(v - other.v); }
+  inline eigen_wrapper_v4<T> operator * (const eigen_wrapper_v4<T>& other) const { return eigen_wrapper_v4<T>(v.cwiseProduct (other.v)); }
+  inline eigen_wrapper_v4<T> operator / (const eigen_wrapper_v4<T>& other) const { return (eigen_wrapper_v4<T>(v) /= other); }
+  inline eigen_wrapper_v4<T>& operator += (const eigen_wrapper_v4<T>& other) { v += other.v; return *this; }
+  inline eigen_wrapper_v4<T>& operator -= (const eigen_wrapper_v4<T>& other) { v -= other.v; return *this; }
+  inline eigen_wrapper_v4<T>& operator *= (const eigen_wrapper_v4<T>& other) { v = v.cwiseProduct  (other.v); return *this; }
+  inline eigen_wrapper_v4<T>& operator /= (const eigen_wrapper_v4<T>& other) { d() = d().cwiseQuotient (other.d()); return *this; }
+  inline eigen_wrapper_v4<T> operator + (T t) const { return eigen_wrapper_v4<T>((d().array() + t).matrix()); }
+  inline eigen_wrapper_v4<T> operator - (T t) const { return eigen_wrapper_v4<T>((d().array() - t).matrix()); }
+  inline eigen_wrapper_v4<T> operator * (T t) const { return eigen_wrapper_v4<T>(v * t); }
+  inline eigen_wrapper_v4<T> operator / (T t) const { return eigen_wrapper_v4<T>(v / t); }
+  inline eigen_wrapper_v4<T>& operator += (T t) { d().array() += t; return *this; }
+  inline eigen_wrapper_v4<T>& operator -= (T t) { d().array() -= t; return *this; }
+  inline eigen_wrapper_v4<T>& operator *= (T t) { v.array() *= t; return *this; }
+  inline eigen_wrapper_v4<T>& operator /= (T t) { v.array() /= t; return *this; }
+  inline eigen_wrapper_v4<T> operator - () const { return eigen_wrapper_v4<T>(-v); }
+} __attribute__ ((aligned));
+
+
+template <typename T>
+static inline eigen_wrapper_v4<T> cross_prod(const eigen_wrapper_v4<T>& l, const eigen_wrapper_v4<T>& r)
+{
+  return eigen_wrapper_v4<T>(l.v.cross3 (r.v));
+}
+
+template <typename T>
+static inline T dot_prod3(const eigen_wrapper_v4<T>& l, const eigen_wrapper_v4<T>& r)
+{
+  return l.v.dot(r.v);
+}
+
+template <typename T>
+static inline eigen_wrapper_v4<T> min(const eigen_wrapper_v4<T>& x, const eigen_wrapper_v4<T>& y)
+{
+  return eigen_wrapper_v4<T>(x.v.cwiseMin (y.v));
+}
+
+template <typename T>
+static inline eigen_wrapper_v4<T> max(const eigen_wrapper_v4<T>& x, const eigen_wrapper_v4<T>& y)
+{
+  return eigen_wrapper_v4<T>(x.v.cwiseMax(y.v));
+}
+
+template <typename T>
+static inline eigen_wrapper_v4<T> abs(const eigen_wrapper_v4<T>& x)
+{
+  return eigen_wrapper_v4<T>(x.v.cwiseAbs());
+}
+
+template <typename T>
+static inline bool equal(const eigen_wrapper_v4<T>& x, const eigen_wrapper_v4<T>& y, T epsilon)
+{
+  return ((x.v - y.v).cwiseAbs ().array () < epsilon).all();
+}
+
+template <typename T>
+struct eigen_v3 :
+  Eigen::Matrix <T, 3, 1>
+{
+  typedef T meta_type;
+  typedef Eigen::Matrix <T, 3, 1> Base;
+
+  eigen_v3(void): Base () { this->setZero (); }
+
+  // This constructor allows you to construct MyVectorType from Eigen expressions
+  template<typename OtherDerived>
+    eigen_v3(const Eigen::MatrixBase<OtherDerived>& other)
+    : Base(other)
+  {}
+
+  // This method allows you to assign Eigen expressions to MyVectorType
+  template<typename OtherDerived>
+    eigen_v3& operator= (const Eigen::MatrixBase <OtherDerived>& other)
+    {
+      this->Base::operator=(other);
+      return *this;
+    }
+
+  eigen_v3(T x) :
+    Base (x, x, x)
+  {}
+
+  eigen_v3(T* x) :
+    Base (*x, *x, *x)
+  {}
+
+  eigen_v3(T x, T y, T z) :
+    Base (x, y, z)
+  {}
+
+  inline void setValue(T x, T y, T z)
+  {
+    this->operator[] (0) = x;
+    this->operator[] (1) = y;
+    this->operator[] (2) = z;
+  }
+
+  inline void setValue(T x)
+  {
+    this->setConstant (x);
+  }
+
+  inline void negate()
+  {
+    this->operator*= (-1);
+  }
+
+  template<typename OtherDerived>
+  inline eigen_v3<T>& ubound(const Eigen::MatrixBase<OtherDerived>& u)
+  {
+    *this = this->cwiseMin (u);
+    return *this;
+  }
+
+  template<typename OtherDerived>
+  inline eigen_v3<T>& lbound(const Eigen::MatrixBase<OtherDerived>& l)
+  {
+    *this = this->cwiseMax (l);
+    return *this;
+  }
+
+  // T operator [] (size_t i) const { return v[i]; }
+  // T& operator [] (size_t i) { return v[i]; }
+
+  // inline eigen_wrapper_v3<T> operator + (const eigen_wrapper_v3<T>& other) const { return eigen_wrapper_v3<T>(v + other.v); }
+  // inline eigen_wrapper_v3<T> operator - (const eigen_wrapper_v3<T>& other) const { return eigen_wrapper_v3<T>(v[0] - other.v[0], v[1] - other.v[1], v[2] - other.v[2]); }
+  // inline eigen_wrapper_v3<T> operator * (const eigen_wrapper_v3<T>& other) const { return eigen_wrapper_v3<T>(v[0] * other.v[0], v[1] * other.v[1], v[2] * other.v[2]); }
+  // inline eigen_v3<T> operator / (const eigen_v3<T>& other) const { return eigen_v3<T>(this->array().cwiseQuotient (other)); }
+  inline eigen_v3<T>& operator += (const eigen_v3<T>& other) { return static_cast<eigen_v3<T>&>(this->Base::operator+= (other)); }
+  inline eigen_v3<T>& operator -= (const eigen_v3<T>& other) { return static_cast<eigen_v3<T>&>(this->Base::operator-= (other)); }
+  inline eigen_v3<T>& operator *= (const eigen_v3<T>& other) { return static_cast<eigen_v3<T>&>(this->array().operator*=(other)); }
+  inline eigen_v3<T>& operator /= (const eigen_v3<T>& other) { return static_cast<eigen_v3<T>&>(this->array().operator/=(other)); }
+  // inline eigen_wrapper_v4<T>& operator /= (const eigen_wrapper_v4<T>& other) {  = d().cwiseQuotient (other.d()); return *this; }
+  // inline eigen_wrapper_v3<T>& operator *= (const eigen_wrapper_v3<T>& other) { return this->Base::operator*= (other); }
+  // inline eigen_wrapper_v3<T>& operator /= (const eigen_wrapper_v3<T>& other) { return this->Base::operator/= (other); }
+  // inline eigen_wrapper_v3<T> operator + (T t) const { return eigen_wrapper_v3<T>(v + t); }
+  // inline eigen_wrapper_v3<T> operator - (T t) const { return eigen_wrapper_v3<T>(v - t); }
+  // inline eigen_wrapper_v3<T> operator * (T t) const { return eigen_wrapper_v3<T>(v * t); }
+  // inline eigen_wrapper_v3<T> operator / (T t) const { return eigen_wrapper_v3<T>(v / t); }
+  inline eigen_v3<T>& operator += (T t) { this->array() += t; return *this; }
+  inline eigen_v3<T>& operator -= (T t) { this->array() -= t; return *this; }
+  inline eigen_v3<T>& operator *= (T t) { this->array() *= t; return *this; }
+  inline eigen_v3<T>& operator /= (T t) { this->array() /= t; return *this; }
+  // inline eigen_wrapper_v3<T> operator - () const { return eigen_wrapper_v3<T>(-v); }
+};
+
+
+template <typename T>
+static inline eigen_v3<T> cross_prod(const eigen_v3<T>& l, const eigen_v3<T>& r)
+{
+  return l.cross (r);
+}
+
+template <typename T>
+static inline T dot_prod3(const eigen_v3<T>& l, const eigen_v3<T>& r)
+{
+  return l.dot(r);
+}
+
+template <typename T>
+static inline eigen_v3<T> min(const eigen_v3<T>& x, const eigen_v3<T>& y)
+{
+  return x.cwiseMin (y);
+}
+
+template <typename T>
+static inline eigen_v3<T> max(const eigen_v3<T>& x, const eigen_v3<T>& y)
+{
+  return x.cwiseMax(y);
+}
+
+template <typename T>
+static inline eigen_v3<T> abs(const eigen_v3<T>& x)
+{
+  return x.cwiseAbs();
+}
+
+template <typename T>
+static inline bool equal(const eigen_v3<T>& x, const eigen_v3<T>& y, T epsilon)
+{
+  return ((x - y).cwiseAbs ().array () < epsilon).all();
+}
+
+template<typename T>
+struct eigen_wrapper_m3
+{
+  typedef T meta_type;
+  typedef eigen_wrapper_v3<T> vector_type;
+  typedef Eigen::Matrix <T, 3, 3, Eigen::RowMajor> matrix_type;
+  typedef Eigen::Matrix <T, 3, 1> inner_col_type;
+  typedef typename matrix_type::ConstRowXpr ConstRowXpr;
+
+  matrix_type m;
+  eigen_wrapper_m3() {};
+
+  template <typename Derived>
+    eigen_wrapper_m3(const Eigen::MatrixBase <Derived>& matrix) :
+      m (matrix)
+  {}
+
+  eigen_wrapper_m3(T xx, T xy, T xz,
+                   T yx, T yy, T yz,
+                   T zx, T zy, T zz)
+  {
+    setValue(xx, xy, xz,
+             yx, yy, yz,
+             zx, zy, zz);
+  }
+
+  eigen_wrapper_m3(const vector_type& v1, const vector_type& v2, const vector_type& v3)
+  {
+    m << v1.v, v2.v, v3.v;
+  }
+
+  eigen_wrapper_m3(const eigen_wrapper_m3<T>& other) { m = other.m; }
+
+  inline inner_col_type getColumn(size_t i) const { return m.col (i); }
+  inline ConstRowXpr getRow(size_t i) const { return m.row (i); }
+
+  inline T operator() (size_t i, size_t j) const { return m(i, j); }
+  inline T& operator() (size_t i, size_t j) { return m(i, j); }
+
+  inline vector_type operator * (const vector_type& v) const { return vector_type(m * v.v); }
+
+  inline eigen_wrapper_m3<T> operator * (const eigen_wrapper_m3<T>& other) const { return eigen_wrapper_m3<T>(m * other.m); }
+  inline eigen_wrapper_m3<T> operator + (const eigen_wrapper_m3<T>& other) const { return eigen_wrapper_m3<T>(m + other.m); }
+  inline eigen_wrapper_m3<T> operator - (const eigen_wrapper_m3<T>& other) const { return eigen_wrapper_m3<T>(m - other.m); }
+
+  inline eigen_wrapper_m3<T> operator + (T c) const { return eigen_wrapper_m3<T>(m + c); }
+  inline eigen_wrapper_m3<T> operator - (T c) const { return eigen_wrapper_m3<T>(m - c); }
+  inline eigen_wrapper_m3<T> operator * (T c) const { return eigen_wrapper_m3<T>(m * c); }
+  inline eigen_wrapper_m3<T> operator / (T c) const { return eigen_wrapper_m3<T>(m / c); }
+
+  inline eigen_wrapper_m3<T>& operator *= (const eigen_wrapper_m3<T>& other) { m *= other.m; return *this; }
+  inline eigen_wrapper_m3<T>& operator += (const eigen_wrapper_m3<T>& other) { m += other.m; return *this; }
+  inline eigen_wrapper_m3<T>& operator -= (const eigen_wrapper_m3<T>& other) { m -= other.m; return *this; }
+
+  inline eigen_wrapper_m3<T>& operator += (T c) { m.array() += c; return *this; }
+  inline eigen_wrapper_m3<T>& operator -= (T c) { m.array() -= c; return *this; }
+  inline eigen_wrapper_m3<T>& operator *= (T c) { m.array() *= c; return *this; }
+  inline eigen_wrapper_m3<T>& operator /= (T c) { m.array() /= c; return *this; }
+
+
+  void setIdentity() { m.setIdentity (); }
+
+  void setZero() { m.setZero(); }
+
+  static const eigen_wrapper_m3<T>& getIdentity()
+  {
+    static const eigen_wrapper_m3<T> I(matrix_type::Identity ());
+    return I;
+  }
+
+  T determinant() const { return m.determinant (); }
+
+  eigen_wrapper_m3<T>& transpose()
+  {
+    m.transposeInPlace ();
+    return *this;
+  }
+
+  eigen_wrapper_m3<T>& inverse()
+  {
+    m = m.inverse().eval();
+    return *this;
+  }
+
+  eigen_wrapper_m3<T> transposeTimes(const eigen_wrapper_m3<T>& other) const
+  {
+    return eigen_wrapper_m3<T>(m.transpose () * other.m);
+  }
+
+  eigen_wrapper_m3<T> timesTranspose(const eigen_wrapper_m3<T>& other) const
+  {
+    return eigen_wrapper_m3<T>(m * other.transpose ());
+  }
+
+  vector_type transposeTimes(const vector_type& other) const
+  {
+    return vector_type(m.transpose () * other.v);
+  }
+
+  inline T transposeDotX(const vector_type& other) const
+  {
+    return m.col(0).dot(other.v);
+  }
+
+  inline T transposeDotY(const vector_type& other) const
+  {
+    return m.col(1).dot(other.v);
+  }
+
+  inline T transposeDotZ(const vector_type& other) const
+  {
+    return m.col(2).dot(other.v);
+  }
+
+  inline T transposeDot(size_t i, const vector_type& other) const
+  {
+    return m.col (i).dot(other.v);
+  }
+
+  inline T dotX(const vector_type& other) const
+  {
+    return m.row (0).dot (other.v);
+  }
+
+  inline T dotY(const vector_type& other) const
+  {
+    return m.row (1).dot (other.v);
+  }
+
+  inline T dotZ(const vector_type& other) const
+  {
+    return m.row (2).dot (other.v);
+  }
+
+  inline T dot(size_t i, const vector_type& other) const
+  {
+    return m.row (i).dot (other.v);
+  }
+
+  inline void setValue(T xx, T xy, T xz,
+                       T yx, T yy, T yz,
+                       T zx, T zy, T zz)
+  {
+    m << xx, xy, xz,
+         yx, yy, yz,
+         zx, zy, zz;
+  }
+
+  inline void setValue(T x) { m.setConstant (x); }
+};
+
+
+template<typename T>
+eigen_wrapper_m3<T> abs(const eigen_wrapper_m3<T>& m)
+{
+  return eigen_wrapper_m3<T>(m.m.cwiseAbs ());
+}
+
+template<typename T>
+eigen_wrapper_m3<T> transpose(const eigen_wrapper_m3<T>& m)
+{
+  return eigen_wrapper_m3<T>(m.m.transpose ());
+}
+
+
+template<typename T>
+eigen_wrapper_m3<T> inverse(const eigen_wrapper_m3<T>& m)
+{
+  return eigen_wrapper_m3<T> (m.m.inverse().eval ());
+}
+
+template<typename T>
+struct eigen_m3 :
+  Eigen::Matrix <T, 3, 3>
+{
+  typedef T meta_type;
+  typedef eigen_v3<T> vector_type;
+  typedef Eigen::Matrix <T, 3, 3> Base;
+
+  typedef typename Base::ColXpr ColXpr;
+  typedef typename Base::ConstColXpr ConstColXpr;
+  typedef typename Base::RowXpr RowXpr;
+  typedef typename Base::ConstRowXpr ConstRowXpr;
+
+  eigen_m3(void): Base () { }
+
+  // This constructor allows you to construct MyVectorType from Eigen expressions
+  template<typename OtherDerived>
+    eigen_m3(const Eigen::MatrixBase<OtherDerived>& other)
+    : Base(other)
+  {}
+
+  // This method allows you to assign Eigen expressions to MyVectorType
+  template<typename OtherDerived>
+    eigen_m3& operator= (const Eigen::MatrixBase <OtherDerived>& other)
+    {
+      this->Base::operator=(other);
+      return *this;
+    }
+
+  eigen_m3(T xx, T xy, T xz,
+           T yx, T yy, T yz,
+           T zx, T zy, T zz)
+  {
+    setValue(xx, xy, xz,
+             yx, yy, yz,
+             zx, zy, zz);
+  }
+
+  eigen_m3(const vector_type& v1, const vector_type& v2, const vector_type& v3)
+  {
+    this->row(1) = v1;
+    this->row(2) = v2;
+    this->row(3) = v3;
+  }
+
+  inline ColXpr getColumn(size_t i) { return this->col (i); }
+  inline RowXpr getRow(size_t i)    { return this->row (i); }
+  inline ConstColXpr getColumn(size_t i) const { return this->col (i); }
+  inline ConstRowXpr getRow(size_t i) const    { return this->row (i); }
+
+  inline eigen_m3<T>& operator *= (const eigen_m3<T>& other) { return static_cast<eigen_m3<T>&>(this->operator*=(other)); }
+  inline eigen_m3<T>& operator += (const eigen_m3<T>& other) { return static_cast<eigen_m3<T>&>(this->operator+=(other)); }
+  inline eigen_m3<T>& operator -= (const eigen_m3<T>& other) { return static_cast<eigen_m3<T>&>(this->operator-=(other)); }
+
+  inline eigen_m3<T>& operator += (T c) { return static_cast<eigen_m3<T>&>(this->operator+=(c)); }
+  inline eigen_m3<T>& operator -= (T c) { return static_cast<eigen_m3<T>&>(this->operator-=(c)); }
+  inline eigen_m3<T>& operator *= (T c) { return static_cast<eigen_m3<T>&>(this->operator*=(c)); }
+  inline eigen_m3<T>& operator /= (T c) { return static_cast<eigen_m3<T>&>(this->operator/=(c)); }
+
+  static const eigen_m3<T>& getIdentity()
+  {
+    static const eigen_m3<T> I(Base::Identity ());
+    return I;
+  }
+
+  eigen_m3<T>& transpose() { this->transposeInPlace (); return *this; }
+
+  eigen_m3<T>& inverse()
+  {
+    this->Base::operator=(this->inverse ().eval());
+    // m = m.inverse().eval();
+    return *this;
+  }
+
+  template <typename OtherDerived>
+    const typename Eigen::ProductReturnType<eigen_m3<T>, OtherDerived>::Type
+    transposeTimes(const Eigen::MatrixBase<OtherDerived>& other) const
+  {
+    return this->Base::transpose() * other;
+  }
+
+  template <typename OtherDerived>
+    const typename Eigen::ProductReturnType<eigen_m3<T>, OtherDerived>::Type
+    timesTranspose(const Eigen::MatrixBase<OtherDerived>& other) const
+  {
+    return this->operator* (other.Base::transpose());
+  }
+
+  template <typename OtherDerived>
+  inline T transposeDotX(const Eigen::MatrixBase<OtherDerived>& other) const
+  {
+    return this->col(0).dot(other);
+  }
+
+  template <typename OtherDerived>
+  inline T transposeDotY(const Eigen::MatrixBase<OtherDerived>& other) const
+  {
+    return this->col(1).dot(other);
+  }
+
+  template <typename OtherDerived>
+  inline T transposeDotZ(const Eigen::MatrixBase<OtherDerived>& other) const
+  {
+    return this->col(2).dot(other);
+  }
+
+  template <typename OtherDerived>
+  inline T transposeDot(size_t i, const Eigen::MatrixBase<OtherDerived>& other) const
+  {
+    return this->col(i).dot(other);
+  }
+
+  template <typename OtherDerived>
+  inline T dotX(const Eigen::MatrixBase<OtherDerived>& other) const
+  {
+    return this->row(0).dot(other);
+  }
+
+  template <typename OtherDerived>
+  inline T dotY(const Eigen::MatrixBase<OtherDerived>& other) const
+  {
+    return this->row(1).dot(other);
+  }
+
+  template <typename OtherDerived>
+  inline T dotZ(const Eigen::MatrixBase<OtherDerived>& other) const
+  {
+    return this->row(2).dot(other);
+  }
+
+  template <typename OtherDerived>
+  inline T dot(size_t i, const Eigen::MatrixBase<OtherDerived>& other) const
+  {
+    return this->row(i).dot(other);
+  }
+
+  inline void setValue(T xx, T xy, T xz,
+                       T yx, T yy, T yz,
+                       T zx, T zy, T zz)
+  {
+    *this << xx, xy, xz,
+             yx, yy, yz,
+             zx, zy, zz;
+  }
+
+  inline void setValue(T x)
+  {
+    this->setConstant (x);
+  }
+};
+
+
+template<typename T>
+eigen_m3<T> abs(const eigen_m3<T>& m)
+{
+  return eigen_m3<T>(m.cwiseAbs ());
+}
+
+template<typename T>
+eigen_m3<T> transpose(const eigen_m3<T>& m)
+{
+  return eigen_m3<T>(m.eigen_m3<T>::Base::transpose ());
+}
+
+
+template<typename T>
+eigen_m3<T> inverse(const eigen_m3<T>& m)
+{
+  return eigen_m3<T> (m.eigen_m3<T>::Base::inverse().eval ());
+}
+
+}
+
+}
+
+#endif
diff --git a/include/hpp/fcl/eigen/plugins/ccd/interval-matrix.h b/include/hpp/fcl/eigen/plugins/ccd/interval-matrix.h
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/include/hpp/fcl/eigen/plugins/ccd/interval-vector.h b/include/hpp/fcl/eigen/plugins/ccd/interval-vector.h
new file mode 100644
index 0000000000000000000000000000000000000000..fda38f99323f5b9a05a7f7e4d8aa0a0a173a787f
--- /dev/null
+++ b/include/hpp/fcl/eigen/plugins/ccd/interval-vector.h
@@ -0,0 +1,7 @@
+template <typename Derived>
+IVector3& operator=(const FclType<Derived>& other)
+{
+  const Vec3f& tmp = other.fcl();
+  setValue (tmp);
+  return *this;
+}
diff --git a/include/hpp/fcl/eigen/product.h b/include/hpp/fcl/eigen/product.h
new file mode 100644
index 0000000000000000000000000000000000000000..3998cf39b4a5fc6931508e7a6b50e7dc72830331
--- /dev/null
+++ b/include/hpp/fcl/eigen/product.h
@@ -0,0 +1,39 @@
+namespace internal {
+
+template<typename Derived, typename OtherDerived, bool coefwise> struct deduce_fcl_type {};
+
+template<typename Derived, typename OtherDerived>
+struct deduce_fcl_type<Derived, OtherDerived, false> {
+  typedef typename ProductReturnType<Derived, OtherDerived>::Type Type;
+};
+template<typename Derived, typename OtherDerived>
+struct deduce_fcl_type<Derived, OtherDerived, true> {
+  typedef CwiseBinaryOp<scalar_multiple_op<typename Derived::Scalar>, const Derived, const OtherDerived> Type;
+};
+
+}
+
+template<typename Derived, typename OtherDerived>
+struct FclProduct
+{
+  enum {
+    COEFWISE = Derived::ColsAtCompileTime == 1 && OtherDerived::ColsAtCompileTime == 1
+  };
+
+  typedef typename internal::remove_fcl<Derived>::type EDerived;
+  typedef typename internal::remove_fcl<OtherDerived>::type EOtherDerived;
+
+  typedef FclOp<typename internal::deduce_fcl_type<EDerived, EOtherDerived, COEFWISE>::Type> ProductType;
+  typedef FclOp<typename ProductReturnType<Transpose<Derived>, EOtherDerived >::Type> TransposeTimesType;
+  typedef FclOp<typename ProductReturnType<EDerived, Transpose<EOtherDerived> >::Type> TimesTransposeType;
+  typedef FclOp<typename ProductReturnType<ProductType, Transpose<EDerived>  >::Type> TensorTransformType;
+  static EIGEN_STRONG_INLINE ProductType run (const Derived& l, const OtherDerived& r) { return ProductType (l, r); }
+};
+
+#define FCL_EIGEN_MAKE_PRODUCT_OPERATOR() \
+      template <typename OtherDerived> \
+      EIGEN_STRONG_INLINE const typename FclProduct<const typename FCL_EIGEN_CURRENT_CLASS::Base, const OtherDerived>::ProductType \
+      operator*(const MatrixBase<OtherDerived>& other) const \
+      { \
+        return FclProduct<const typename FCL_EIGEN_CURRENT_CLASS::Base, const OtherDerived>::run (*this, other.derived()); \
+      }
diff --git a/include/hpp/fcl/eigen/taylor_operator.h b/include/hpp/fcl/eigen/taylor_operator.h
new file mode 100644
index 0000000000000000000000000000000000000000..fa02f2b7aea2b7454b255e0c0cb93e35cf673a2c
--- /dev/null
+++ b/include/hpp/fcl/eigen/taylor_operator.h
@@ -0,0 +1,25 @@
+#ifndef FCL_CCD_TAYLOR_OPERATOR_H
+#define FCL_CCD_TAYLOR_OPERATOR_H
+
+#include <hpp/fcl/math/vec_3f.h>
+#include <hpp/fcl/math/matrix_3f.h>
+
+namespace fcl {
+
+class TVector3;
+class TMatrix3;
+
+template<int Col> struct TaylorReturnType {};
+template<> struct TaylorReturnType<1> { typedef TVector3 type; typedef Vec3f    eigen_type; };
+template<> struct TaylorReturnType<3> { typedef TMatrix3 type; typedef Matrix3f eigen_type; };
+
+template<typename Derived>
+typename TaylorReturnType<Derived::ColsAtCompileTime>::type operator * (const FclType<Derived>& v, const TaylorModel& a)
+{
+  const typename TaylorReturnType<Derived::ColsAtCompileTime>::eigen_type b = v.fcl();
+  return b * a;
+}
+
+}
+
+#endif // FCL_CCD_TAYLOR_OPERATOR_H
diff --git a/include/hpp/fcl/eigen/vec_3fx.h b/include/hpp/fcl/eigen/vec_3fx.h
new file mode 100644
index 0000000000000000000000000000000000000000..23a1e3fd1a2a1e85230577b734eb3a7f68773d3d
--- /dev/null
+++ b/include/hpp/fcl/eigen/vec_3fx.h
@@ -0,0 +1,813 @@
+/*
+ * Software License Agreement (BSD License)
+ *
+ *  Copyright (c) 2011-2014, Willow Garage, Inc.
+ *  Copyright (c) 2014-2015, Open Source Robotics Foundation
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of Open Source Robotics Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** \author Joseph Mirabel */
+
+#ifndef FCL_EIGEN_VEC_3F_H
+#define FCL_EIGEN_VEC_3F_H
+
+#include <hpp/fcl/config-fcl.hh>
+#include <hpp/fcl/data_types.h>
+
+#include <Eigen/Dense>
+#include <Eigen/Geometry>
+
+#include <cmath>
+#include <iostream>
+#include <limits>
+
+#define FCL_CCD_INTERVALVECTOR_PLUGIN <hpp/fcl/eigen/plugins/ccd/interval-vector.h>
+#define FCL_CCD_MATRIXVECTOR_PLUGIN <hpp/fcl/eigen/plugins/ccd/interval-matrix.h>
+
+#define FCL_EIGEN_EXPOSE_PARENT_TYPE(Type) typedef typename Base::Type Type;
+
+#define FCL_EIGEN_MAKE_CWISE_BINARY_OP(METHOD,FUNCTOR) \
+      template <typename OtherDerived> \
+      EIGEN_STRONG_INLINE const FclOp<const CwiseBinaryOp<FUNCTOR<Scalar>, const typename FCL_EIGEN_CURRENT_CLASS::Base, const OtherDerived> > \
+      (METHOD) (const MatrixBase<OtherDerived>& other) const \
+      { \
+        return FclOp <const CwiseBinaryOp<FUNCTOR<Scalar>, const typename FCL_EIGEN_CURRENT_CLASS::Base, const OtherDerived> > (*this, other.derived()); \
+      }
+
+#define FCL_EIGEN_MAKE_CWISE_UNARY_OP(METHOD,FUNCTOR) \
+      EIGEN_STRONG_INLINE const FclOp<const CwiseUnaryOp<FUNCTOR<Scalar>, const typename FCL_EIGEN_CURRENT_CLASS::Base> > \
+      (METHOD) (const Scalar& scalar) const \
+      { \
+        return FclOp <const CwiseUnaryOp<FUNCTOR<Scalar>, const typename FCL_EIGEN_CURRENT_CLASS::Base> > (*this, FUNCTOR<Scalar>(scalar)); \
+      }
+
+#define FCL_EIGEN_RENAME_PARENT_METHOD(OLD,NEW,RETTYPE) \
+      template <typename OtherDerived> \
+      EIGEN_STRONG_INLINE RETTYPE (METHOD) () \
+      { \
+        return (this->Base::METHOD) (); \
+      }
+
+#define FCL_EIGEN_MAKE_EXPOSE_PARENT1(METHOD) \
+      template <typename OtherDerived> \
+      EIGEN_STRONG_INLINE FclMatrix& (METHOD) (const MatrixBase<OtherDerived>& other) \
+      { \
+        (this->Base::METHOD)(other); return *this; \
+      }
+
+#define FCL_EIGEN_MAKE_EXPOSE_PARENT_ARRAY1(METHOD) \
+      template <typename OtherDerived> \
+      EIGEN_STRONG_INLINE FclMatrix& (METHOD) (const MatrixBase<OtherDerived>& other) \
+      { \
+        (this->array().METHOD)(other.derived().array()); return *this; \
+      }
+
+#define FCL_EIGEN_MAKE_EXPOSE_PARENT_ARRAY_SCALAR1(METHOD) \
+      EIGEN_STRONG_INLINE FCL_EIGEN_CURRENT_CLASS& (METHOD) (const Scalar& other) \
+      { \
+        (this->array().METHOD)(other); return *this; \
+      }
+
+#define FCL_EIGEN_MAKE_GET_COL_ROW() \
+  EIGEN_STRONG_INLINE FclOp<ColXpr> getColumn (size_t i) { return FclOp<ColXpr>(*this, i); } \
+  EIGEN_STRONG_INLINE FclOp<RowXpr> getRow    (size_t i) { return FclOp<RowXpr>(*this, i); } \
+  EIGEN_STRONG_INLINE FclOp<ConstColXpr> getColumn (size_t i) const { return FclOp<ConstColXpr>(*this, i); } \
+  EIGEN_STRONG_INLINE FclOp<ConstRowXpr> getRow    (size_t i) const { return FclOp<ConstRowXpr>(*this, i); }
+
+#define FCL_EIGEN_MATRIX_DOT_AXIS(NAME,axis,index) \
+  template<typename OtherDerived> \
+  EIGEN_STRONG_INLINE Scalar NAME##axis (const MatrixBase<OtherDerived>& other) const \
+  { return this->NAME (index, other); }
+
+#define FCL_EIGEN_MATRIX_DOT(NAME,FUNC) \
+  template<typename OtherDerived> \
+  EIGEN_STRONG_INLINE Scalar NAME(size_t i, const MatrixBase<OtherDerived>& other) const \
+  { \
+    EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(FCL_EIGEN_CURRENT_CLASS, 3, 3); \
+    EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived, 3); \
+    return this->FUNC(i).dot(other); \
+  } \
+  FCL_EIGEN_MATRIX_DOT_AXIS(NAME,X,0)\
+  FCL_EIGEN_MATRIX_DOT_AXIS(NAME,Y,1)\
+  FCL_EIGEN_MATRIX_DOT_AXIS(NAME,Z,2)
+
+#define FCL_EIGEN_MAKE_CROSS() \
+  template<typename OtherDerived> \
+  EIGEN_STRONG_INLINE typename BinaryReturnType<FCL_EIGEN_CURRENT_CLASS::Base,OtherDerived>::Cross \
+  cross (const MatrixBase<OtherDerived>& other) const { return this->Base::cross (other); }
+
+#define FCL_EIGEN_MAKE_DOT() \
+  template <typename OtherDerived> \
+  EIGEN_STRONG_INLINE Scalar dot (const MatrixBase<OtherDerived>& other) const \
+  { return this->Base::dot (other.derived()); }
+
+namespace fcl {
+template <typename Derived>
+class FclType
+{
+  public:
+    Derived& fcl () { return static_cast<Derived&> (*this); }
+    const Derived& fcl () const { return static_cast<const Derived&> (*this); }
+};
+}
+
+namespace Eigen {
+  template <typename T> class FclOp;
+  template <typename T, int Cols, int Options> class FclMatrix;
+
+  namespace internal {
+
+    template<typename T> struct traits< FclOp<T> > : traits <T> {};
+    template<typename T, int Cols, int _Options>
+      struct traits< FclMatrix<T, Cols, _Options> >
+      : traits<typename FclMatrix<T, Cols, _Options>::Base>
+      {};
+
+    template <typename Derived> struct remove_fcl { typedef Derived type; };
+    template <> template <typename Derived> struct remove_fcl <FclOp<Derived> > { typedef Derived type; };
+    template <> template <typename Derived> struct remove_fcl <const FclOp<Derived> > { typedef Derived type; };
+    template <> template <typename T, int Col, int Options> struct remove_fcl <FclMatrix<T,Col,Options> > { typedef typename FclMatrix<T,Col,Options>::Base type; };
+    template <> template <typename T, int Col, int Options> struct remove_fcl <const FclMatrix<T,Col,Options> > { typedef typename FclMatrix<T,Col,Options>::Base type; };
+  }
+
+#include <hpp/fcl/eigen/product.h>
+
+  template <typename Derived>
+    struct UnaryReturnType {
+      typedef typename Derived::Scalar Scalar;
+      typedef typename Derived::PlainObject Normalize;
+      typedef FclOp <
+        const CwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const Derived>
+        > Opposite;
+      typedef FclOp <
+        const CwiseUnaryOp<internal::scalar_abs_op<Scalar>, const Derived>
+        > Abs;
+    };
+
+  template <typename Derived, typename OtherDerived>
+    struct BinaryReturnType {
+      typedef typename Derived::Scalar Scalar;
+      typedef FclOp <
+        const CwiseBinaryOp<internal::scalar_difference_op<Scalar>,
+              const Derived, const OtherDerived>
+                > Difference;
+      // static inline const Difference difference (const Derived& l, const OtherDerived& r)
+      // { return Difference (l, r, internal::scalar_difference_op<Scalar>()); }
+      typedef FclOp <
+        const CwiseBinaryOp<internal::scalar_sum_op<Scalar>,
+              const Derived, const OtherDerived>
+                > Sum;
+      typedef FclOp <
+        const CwiseBinaryOp<internal::scalar_min_op<Scalar>,
+              const Derived, const OtherDerived>
+                > Min;
+      typedef FclOp <
+        const CwiseBinaryOp<internal::scalar_max_op<Scalar>,
+              const Derived, const OtherDerived>
+                > Max;
+      typedef FclMatrix <Scalar, 1, 0> Cross;
+    };
+
+#define FCL_EIGEN_CURRENT_CLASS FclMatrix
+
+/// @brief Vector3 class wrapper. The core data is in the template parameter class.
+template <typename T, int Cols, int _Options = internal::traits<Matrix <T, 3, Cols> >::Options >
+class FclMatrix : public Matrix <T, 3, Cols, _Options>, public ::fcl::FclType<FclMatrix <T, Cols, _Options> >
+{
+public:
+  typedef Matrix <T, 3, Cols, _Options> Base;
+  FCL_EIGEN_EXPOSE_PARENT_TYPE(Scalar)
+  FCL_EIGEN_EXPOSE_PARENT_TYPE(ColXpr)
+  FCL_EIGEN_EXPOSE_PARENT_TYPE(RowXpr)
+  FCL_EIGEN_EXPOSE_PARENT_TYPE(ConstColXpr)
+  FCL_EIGEN_EXPOSE_PARENT_TYPE(ConstRowXpr)
+
+  // Compatibility with other Matrix3fX and Vec3f
+  typedef T U;
+  typedef T meta_type;
+
+  FclMatrix(void): Base(Base::Zero()) {}
+
+  // This constructor allows you to construct MyVectorType from Eigen expressions
+  template<typename OtherDerived>
+    FclMatrix(const MatrixBase<OtherDerived>& other)
+    : Base(other)
+    {}
+
+  // This method allows you to assign Eigen expressions to MyVectorType
+  template<typename OtherDerived>
+    FclMatrix& operator=(const MatrixBase <OtherDerived>& other)
+    {
+      this->Base::operator=(other);
+      return *this;
+    }
+
+  /// @brief create Vector (x, y, z)
+  FclMatrix(T x, T y, T z) : Base(x, y, z) {}
+
+  FclMatrix(T xx, T xy, T xz,
+            T yx, T yy, T yz,
+            T zx, T zy, T zz) : Base()
+  {
+    setValue(xx, xy, xz, yx, yy, yz, zx, zy, zz);
+  }
+
+  template <typename Vector>
+  FclMatrix(const ::fcl::FclType<Vector>& r0,
+            const ::fcl::FclType<Vector>& r1,
+            const ::fcl::FclType<Vector>& r2) : Base()
+  {
+    this->row(0) = r0.fcl();
+    this->row(1) = r1.fcl();
+    this->row(2) = r2.fcl();
+  }
+
+  /// @brief create vector (x, x, x)
+  FclMatrix(T x) : Base(Base::Constant (x)) {}
+
+  /// @brief create vector using the internal data type
+  // Vec3fX(const T& data_) : data(data_) {}
+
+  // inline U operator [] (size_t i) const { return data[i]; }
+  // inline U& operator [] (size_t i) { return data[i]; }
+
+  // FclOp<typename Base::ColXpr> getColumn (size_t i) { return FclOp<typename Base::ColXpr>(*this, i); }
+  // FclOp<typename Base::RowXpr> getRow    (size_t i) { return FclOp<typename Base::RowXpr>(*this, i); }
+  // FclOp<typename Base::ColXpr> getColumn (size_t i) { return FclOp<typename Base::ColXpr>(*this, i); }
+  // FclOp<typename Base::RowXpr> getRow    (size_t i) { return FclOp<typename Base::RowXpr>(*this, i); }
+  FCL_EIGEN_MAKE_GET_COL_ROW()
+  FCL_EIGEN_MATRIX_DOT(dot,row)
+  FCL_EIGEN_MATRIX_DOT(transposeDot,col)
+
+  FCL_EIGEN_MAKE_DOT()
+
+  FCL_EIGEN_MAKE_CWISE_BINARY_OP(operator+,internal::scalar_sum_op)
+  FCL_EIGEN_MAKE_CWISE_BINARY_OP(operator-,internal::scalar_difference_op)
+  // Map this to scalar product or matrix product depending on the Cols.
+  // FCL_EIGEN_MAKE_CWISE_BINARY_OP(operator*,internal::scalar_product_op)
+  FCL_EIGEN_MAKE_PRODUCT_OPERATOR()
+  FCL_EIGEN_MAKE_CWISE_BINARY_OP(operator/,internal::scalar_quotient_op)
+  FCL_EIGEN_MAKE_EXPOSE_PARENT1(operator+=)
+  FCL_EIGEN_MAKE_EXPOSE_PARENT1(operator-=)
+  FCL_EIGEN_MAKE_EXPOSE_PARENT_ARRAY1(operator*=)
+  FCL_EIGEN_MAKE_EXPOSE_PARENT_ARRAY1(operator/=)
+  FCL_EIGEN_MAKE_CWISE_UNARY_OP(operator+,internal::scalar_add_op)
+  // This operator cannot be implement with the macro
+  // FCL_EIGEN_MAKE_CWISE_UNARY_OP(operator-,internal::scalar_difference_op)
+  EIGEN_STRONG_INLINE const FclOp<const CwiseUnaryOp<internal::scalar_add_op<Scalar>, const Base> >
+  operator- (const Scalar& scalar) const
+  {
+    return FclOp <const CwiseUnaryOp<internal::scalar_add_op<Scalar>, const Base> > (*this, internal::scalar_add_op<Scalar>(-scalar));
+  }
+  FCL_EIGEN_MAKE_CWISE_UNARY_OP(operator*,internal::scalar_multiple_op)
+  FCL_EIGEN_MAKE_CWISE_UNARY_OP(operator/,internal::scalar_quotient1_op)
+  FCL_EIGEN_MAKE_EXPOSE_PARENT_ARRAY_SCALAR1(operator+=)
+  FCL_EIGEN_MAKE_EXPOSE_PARENT_ARRAY_SCALAR1(operator-=)
+  FCL_EIGEN_MAKE_EXPOSE_PARENT_ARRAY_SCALAR1(operator*=)
+  FCL_EIGEN_MAKE_EXPOSE_PARENT_ARRAY_SCALAR1(operator/=)
+  inline const typename UnaryReturnType<Base>::Opposite operator-() const { return typename UnaryReturnType<Base>::Opposite(*this); }
+  // There is no class for cross 
+  // inline Vec3fX cross(const Vec3fX& other) const { return Vec3fX(details::cross_prod(data, other.data)); }
+  FCL_EIGEN_MAKE_CROSS()
+  inline FclMatrix& normalize()
+  {
+    T sqr_length = this->squaredNorm();
+    if(sqr_length > 0) this->operator/= ((T)std::sqrt(sqr_length));
+    return *this;
+  }
+
+  inline FclMatrix& normalize(bool* signal)
+  {
+    T sqr_length = this->squaredNorm();
+    if(sqr_length > 0)
+    {
+      this->operator/= ((T)std::sqrt(sqr_length));
+      *signal = true;
+    }
+    else
+      *signal = false;
+    return *this;
+  }
+
+  inline FclMatrix& abs() 
+  {
+    *this = this->cwiseAbs ();
+    return *this;
+  }
+
+  inline T length() const { return this->norm(); }
+  // inline T norm() const { return sqrt(details::dot_prod3(data, data)); }
+  inline T sqrLength() const { return this->squaredNorm(); }
+  // inline T squaredNorm() const { return details::dot_prod3(data, data); }
+  inline void setValue(T x, T y, T z) {
+    EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(FclMatrix, 3);
+    this->m_storage.data()[0] = x;
+    this->m_storage.data()[1] = y;
+    this->m_storage.data()[2] = z;
+  }
+  inline void setValue(T xx, T xy, T xz,
+                       T yx, T yy, T yz,
+                       T zx, T zy, T zz)
+  {
+    EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(FclMatrix, 3, 3);
+    this->operator()(0,0) = xx; this->operator()(0,1) = xy; this->operator()(0,2) = xz;
+    this->operator()(1,0) = yx; this->operator()(1,1) = yy; this->operator()(1,2) = yz;
+    this->operator()(2,0) = zx; this->operator()(2,1) = zy; this->operator()(2,2) = zz;
+  }
+  inline void setValue(T x) { this->setConstant (x); }
+  // inline void setZero () {data.setValue (0); }
+  inline bool equal(const FclMatrix& other, T epsilon = std::numeric_limits<T>::epsilon() * 100) const
+  {
+    return ((*this - other).cwiseAbs().array () < epsilon).all();
+  }
+  inline FclMatrix& negate() { *this = -*this; return *this; }
+
+  bool operator == (const FclMatrix& other) const
+  {
+    return equal(other, 0);
+  }
+
+  bool operator != (const FclMatrix& other) const
+  {
+    return !(*this == other);
+  }
+
+  inline FclMatrix& ubound(const FclMatrix& u)
+  {
+    *this = this->cwiseMin (u);
+    return *this;
+  }
+
+  inline FclMatrix& lbound(const FclMatrix& l)
+  {
+    *this = this->cwiseMax (l);
+    return *this;
+  }
+
+  bool isZero() const
+  {
+    return (this->m_storage.data()[0] == 0)
+      &&   (this->m_storage.data()[1] == 0)
+      &&   (this->m_storage.data()[2] == 0);
+  }
+
+  FclMatrix& transpose () {
+    EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Base, 3, 3);
+    this->transposeInPlace();
+    return *this;
+  }
+
+  FclMatrix& inverse()
+  {
+    this->Base::operator=(this->Base::inverse ().eval());
+    return *this;
+  }
+
+  template<typename OtherDerived>
+  EIGEN_STRONG_INLINE const typename FclProduct<const Base,const OtherDerived>::TransposeTimesType
+  transposeTimes (const MatrixBase<OtherDerived>& other) const
+  {
+    const Transpose<const Base> t (*this);
+    return typename FclProduct<const Base,const OtherDerived>::TransposeTimesType (t, other.derived());
+  }
+
+  template<typename OtherDerived>
+  EIGEN_STRONG_INLINE const typename FclProduct<const Base,const OtherDerived>::TimesTransposeType
+  timesTranspose (const MatrixBase<OtherDerived>& other) const
+  {
+    const Transpose<const OtherDerived> t (other.derived());
+    return typename FclProduct<const Base,const OtherDerived>::TimesTransposeType (*this, t);
+  }
+
+  template<typename OtherDerived>
+  EIGEN_STRONG_INLINE const typename FclProduct<const Base,const OtherDerived>::TensorTransformType
+  tensorTransform(const MatrixBase<OtherDerived>& other) const
+  {
+    const Transpose<const Base> t (*this);
+    const typename FclProduct<const Base,const OtherDerived>::ProductType left (*this, other.derived());
+    return typename FclProduct<const Base,const OtherDerived>::TensorTransformType (left, t);
+  }
+
+  static const FclMatrix& getIdentity()
+  {
+    static const FclMatrix I((T)1, (T)0, (T)0,
+                             (T)0, (T)1, (T)0,
+                             (T)0, (T)0, (T)1);
+    return I;
+  }
+
+  /// @brief Set the matrix from euler angles YPR around ZYX axes
+  /// @param eulerX Roll about X axis
+  /// @param eulerY Pitch around Y axis
+  /// @param eulerZ Yaw aboud Z axis
+  ///  
+  /// These angles are used to produce a rotation matrix. The euler
+  /// angles are applied in ZYX order. I.e a vector is first rotated 
+  /// about X then Y and then Z
+  inline void setEulerZYX(Scalar eulerX, Scalar eulerY, Scalar eulerZ)
+  {
+    EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(FclMatrix, 3, 3);
+    Scalar ci(std::cos(eulerX));
+    Scalar cj(std::cos(eulerY));
+    Scalar ch(std::cos(eulerZ));
+    Scalar si(std::sin(eulerX));
+    Scalar sj(std::sin(eulerY));
+    Scalar sh(std::sin(eulerZ));
+    Scalar cc = ci * ch;
+    Scalar cs = ci * sh;
+    Scalar sc = si * ch;
+    Scalar ss = si * sh;
+
+    setValue(cj * ch, sj * sc - cs, sj * cc + ss,
+             cj * sh, sj * ss + cc, sj * cs - sc, 
+             -sj,     cj * si,      cj * ci);
+
+  }
+
+  /// @brief Set the matrix from euler angles using YPR around YXZ respectively
+  /// @param yaw Yaw about Y axis
+  /// @param pitch Pitch about X axis
+  /// @param roll Roll about Z axis 
+  void setEulerYPR(Scalar yaw, Scalar pitch, Scalar roll)
+  {
+    setEulerZYX(roll, pitch, yaw);
+  }
+};
+
+#undef FCL_EIGEN_CURRENT_CLASS
+#define FCL_EIGEN_CURRENT_CLASS FclOp
+
+template <typename EigenOp>
+class FclOp : public EigenOp, public ::fcl::FclType<FclOp <EigenOp> >
+{
+public:
+  typedef typename internal::traits<EigenOp>::Scalar T;
+  typedef EigenOp Base;
+  FCL_EIGEN_EXPOSE_PARENT_TYPE(Scalar)
+  FCL_EIGEN_EXPOSE_PARENT_TYPE(ColXpr)
+  FCL_EIGEN_EXPOSE_PARENT_TYPE(RowXpr)
+  FCL_EIGEN_EXPOSE_PARENT_TYPE(ConstColXpr)
+  FCL_EIGEN_EXPOSE_PARENT_TYPE(ConstRowXpr)
+
+  // template<typename Lhs, typename Rhs, typename BinaryOp>
+  // FclOp (const Lhs& lhs, const Rhs& rhs, const BinaryOp& bop)
+    // : Base (lhs, rhs, bop) {}
+
+  template<typename Lhs, typename Rhs>
+  FclOp (Lhs& lhs, const Rhs& rhs)
+    : Base (lhs, rhs) {}
+
+  template<typename OtherEigenOp>
+  FclOp (const FclOp<OtherEigenOp>& other)
+    : Base (other) {}
+
+  template<typename XprType>
+  FclOp (XprType& xpr)
+    : Base (xpr) {}
+
+  FCL_EIGEN_MAKE_GET_COL_ROW()
+  FCL_EIGEN_MATRIX_DOT(dot,row)
+  FCL_EIGEN_MATRIX_DOT(transposeDot,col)
+
+  FCL_EIGEN_MAKE_DOT()
+
+  FCL_EIGEN_MAKE_CWISE_BINARY_OP(operator+,internal::scalar_sum_op)
+  FCL_EIGEN_MAKE_CWISE_BINARY_OP(operator-,internal::scalar_difference_op)
+  // Map this to scalar product or matrix product depending on the Cols.
+  // FCL_EIGEN_MAKE_CWISE_BINARY_OP(operator*,internal::scalar_product_op)
+  FCL_EIGEN_MAKE_PRODUCT_OPERATOR()
+  FCL_EIGEN_MAKE_CWISE_BINARY_OP(operator/,internal::scalar_quotient_op)
+  FCL_EIGEN_MAKE_CWISE_UNARY_OP(operator+,internal::scalar_add_op)
+  // This operator cannot be implement with the macro
+  // FCL_EIGEN_MAKE_CWISE_UNARY_OP(operator-,internal::scalar_difference_op)
+  EIGEN_STRONG_INLINE const FclOp<const CwiseUnaryOp<internal::scalar_add_op<Scalar>, const Base> >
+  operator- (const Scalar& scalar) const
+  {
+    return FclOp <const CwiseUnaryOp<internal::scalar_add_op<Scalar>, const Base> > (*this, internal::scalar_add_op<Scalar>(-scalar));
+  }
+  FCL_EIGEN_MAKE_CWISE_UNARY_OP(operator*,internal::scalar_multiple_op)
+  FCL_EIGEN_MAKE_CWISE_UNARY_OP(operator/,internal::scalar_quotient1_op)
+  inline const typename UnaryReturnType<const Base>::Opposite operator-() const { return typename UnaryReturnType<const Base>::Opposite(*this); }
+
+  FCL_EIGEN_MAKE_CROSS()
+
+  inline const typename UnaryReturnType<EigenOp>::Normalize
+    normalize() const
+  {
+    return this->normalized ();
+    // T sqr_length = this->squaredNorm();
+    // if(sqr_length > 0) CwiseExpose (*this /= ((T)sqrt(sqr_length)));
+    // return *this;
+  }
+
+  /*
+  inline Vec3fX<T> normalize(bool* signal)
+  {
+    T sqr_length = this->squaredNorm();
+    if(sqr_length > 0)
+    {
+      *this /= ((T)sqrt(sqr_length));
+      *signal = true;
+    }
+    else
+      *signal = false;
+    return *this;
+  }
+  // */
+
+  inline const typename UnaryReturnType<EigenOp>::Abs
+    abs() const
+  {
+    return typename UnaryReturnType<EigenOp>::Abs (*this);
+  }
+
+  inline Scalar length() const { return this->norm(); }
+  inline Scalar sqrLength() const { return this->squaredNorm(); }
+
+  template <typename Derived>
+  inline bool equal(const Eigen::MatrixBase<Derived>& other, T epsilon = std::numeric_limits<T>::epsilon() * 100) const
+  {
+    return ((*this - other).cwiseAbs().array () < epsilon).all();
+  }
+
+  /*
+  inline const typename Eigen::CwiseUnaryOp<Eigen::internal::scalar_opposite_op<T>, const EigenOp>
+    negate() { return this->operator-(); }
+  // */
+
+  template <typename Derived>
+  bool operator == (const Eigen::MatrixBase<Derived>& other) const
+  {
+    return equal(other, 0);
+  }
+
+  template <typename Derived>
+  bool operator != (const Eigen::MatrixBase<Derived>& other) const
+  {
+    return !(*this == other);
+  }
+
+  // Not in place.
+  FCL_EIGEN_MAKE_CWISE_BINARY_OP(ubound,internal::scalar_min_op)
+  FCL_EIGEN_MAKE_CWISE_BINARY_OP(lbound,internal::scalar_max_op)
+
+  bool isZero() const
+  {
+    return this->Base::isZero ();
+  }
+
+  const FclOp<Transpose<const Base> > transpose () const {
+    EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(EigenOp, 3, 3);
+    return FclOp<Transpose<const Base> >(*this);
+  }
+
+  // const FclOp<internal::inverse_impl<FclOp> > inverse () const { return FclOp<Transpose<FclOp> >(*this); }
+};
+
+}
+
+namespace fcl
+{
+// #if 0
+template<typename T, int _Options>
+static inline Eigen::FclMatrix<T, 1, _Options> normalize(const Eigen::FclMatrix<T, 1, _Options>& v)
+{
+  T sqr_length = v.squaredNorm ();
+  if(sqr_length > 0)
+    return v / (T)sqrt(sqr_length);
+  else
+    return v;
+}
+
+template<typename Derived>
+static inline typename Derived::Scalar triple(
+    const FclType<Derived>& x,
+    const FclType<Derived>& y,
+    const FclType<Derived>& z)
+{
+  return x.fcl().dot(y.fcl().cross(z.fcl()));
+}
+
+
+template<typename Derived, typename OtherDerived>
+static inline const typename Eigen::BinaryReturnType<const Derived, const OtherDerived>::Min
+ min(const FclType<Derived>& x, const FclType<OtherDerived>& y)
+{
+  return typename Eigen::BinaryReturnType<const Derived, const OtherDerived>::Min (x.fcl(), y.fcl());
+}
+
+template<typename Derived, typename OtherDerived>
+static inline const typename Eigen::BinaryReturnType<const Derived, const OtherDerived>::Max
+ max(const FclType<Derived>& x, const FclType<OtherDerived>& y)
+{
+  return typename Eigen::BinaryReturnType<const Derived, const OtherDerived>::Max (x.fcl(), y.fcl());
+}
+
+template<typename Derived>
+static inline const typename Eigen::UnaryReturnType<const Derived>::Abs
+abs(const FclType<Derived>& x)
+{
+  return typename Eigen::UnaryReturnType<const Derived>::Abs (x.fcl());
+}
+
+template<typename Derived>
+void generateCoordinateSystem(
+    FclType<Derived>& _w,
+    FclType<Derived>& _u,
+    FclType<Derived>& _v)
+{
+  typedef typename Derived::Scalar T;
+
+  Derived& w = _w.fcl();
+  Derived& u = _u.fcl();
+  Derived& v = _v.fcl();
+
+  T inv_length;
+  if(std::abs(w[0]) >= std::abs(w[1]))
+  {
+    inv_length = (T)1.0 / sqrt(w[0] * w[0] + w[2] * w[2]);
+    u[0] = -w[2] * inv_length;
+    u[1] = (T)0;
+    u[2] = w[0] * inv_length;
+    v[0] = w[1] * u[2];
+    v[1] = w[2] * u[0] - w[0] * u[2];
+    v[2] = -w[1] * u[0];
+  }
+  else
+  {
+    inv_length = (T)1.0 / sqrt(w[1] * w[1] + w[2] * w[2]);
+    u[0] = (T)0;
+    u[1] = w[2] * inv_length;
+    u[2] = -w[1] * inv_length;
+    v[0] = w[1] * u[2] - w[2] * u[1];
+    v[1] = -w[0] * u[2];
+    v[2] = w[0] * u[1];
+  }
+}
+
+ // template <typename T>
+   // inline Vec3fX <T> operator * (const typename Vec3fX <T>::U& t,
+				 // const Vec3fX <T>& v)
+   // {
+     // return Vec3fX <T> (v.data * t);
+   // }
+
+// #endif
+
+/* ----- Start Matrices ------ */
+template<typename Matrix, typename Vector>
+void hat(Matrix& mat, const Vector& vec)
+{
+  mat.setValue(0, -vec[2], vec[1], vec[2], 0, -vec[0], -vec[1], vec[0], 0);
+}
+
+template<typename Matrix, typename Vector>
+void relativeTransform(const Matrix& R1, const Vector& t1,
+                       const Matrix& R2, const Vector& t2,
+                       Matrix& R, Vector& t)
+{
+  R = R1.transposeTimes(R2);
+  t = R1.transposeTimes(t2 - t1);
+}
+
+/// @brief compute the eigen vector and eigen vector of a matrix. dout is the eigen values, vout is the eigen vectors
+template<typename Matrix, typename Vector>
+void eigen(const FclType<Matrix>& m, typename Matrix::Scalar dout[3], Vector* vout)
+{
+  typedef typename Matrix::Scalar Scalar;
+  Matrix R(m.fcl());
+  int n = 3;
+  int j, iq, ip, i;
+  Scalar tresh, theta, tau, t, sm, s, h, g, c;
+  int nrot;
+  Scalar b[3];
+  Scalar z[3];
+  Scalar v[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
+  Scalar d[3];
+
+  for(ip = 0; ip < n; ++ip)
+  {
+    b[ip] = d[ip] = R(ip, ip);
+    z[ip] = 0;
+  }
+
+  nrot = 0;
+
+  for(i = 0; i < 50; ++i)
+  {
+    sm = 0;
+    for(ip = 0; ip < n; ++ip)
+      for(iq = ip + 1; iq < n; ++iq)
+        sm += std::abs(R(ip, iq));
+    if(sm == 0.0)
+    {
+      vout[0].setValue(v[0][0], v[0][1], v[0][2]);
+      vout[1].setValue(v[1][0], v[1][1], v[1][2]);
+      vout[2].setValue(v[2][0], v[2][1], v[2][2]);
+      dout[0] = d[0]; dout[1] = d[1]; dout[2] = d[2];
+      return;
+    }
+
+    if(i < 3) tresh = 0.2 * sm / (n * n);
+    else tresh = 0.0;
+
+    for(ip = 0; ip < n; ++ip)
+    {
+      for(iq= ip + 1; iq < n; ++iq)
+      {
+        g = 100.0 * std::abs(R(ip, iq));
+        if(i > 3 &&
+           std::abs(d[ip]) + g == std::abs(d[ip]) &&
+           std::abs(d[iq]) + g == std::abs(d[iq]))
+          R(ip, iq) = 0.0;
+        else if(std::abs(R(ip, iq)) > tresh)
+        {
+          h = d[iq] - d[ip];
+          if(std::abs(h) + g == std::abs(h)) t = (R(ip, iq)) / h;
+          else
+          {
+            theta = 0.5 * h / (R(ip, iq));
+            t = 1.0 /(std::abs(theta) + std::sqrt(1.0 + theta * theta));
+            if(theta < 0.0) t = -t;
+          }
+          c = 1.0 / std::sqrt(1 + t * t);
+          s = t * c;
+          tau = s / (1.0 + c);
+          h = t * R(ip, iq);
+          z[ip] -= h;
+          z[iq] += h;
+          d[ip] -= h;
+          d[iq] += h;
+          R(ip, iq) = 0.0;
+          for(j = 0; j < ip; ++j) { g = R(j, ip); h = R(j, iq); R(j, ip) = g - s * (h + g * tau); R(j, iq) = h + s * (g - h * tau); }
+          for(j = ip + 1; j < iq; ++j) { g = R(ip, j); h = R(j, iq); R(ip, j) = g - s * (h + g * tau); R(j, iq) = h + s * (g - h * tau); }
+          for(j = iq + 1; j < n; ++j) { g = R(ip, j); h = R(iq, j); R(ip, j) = g - s * (h + g * tau); R(iq, j) = h + s * (g - h * tau); }
+          for(j = 0; j < n; ++j) { g = v[j][ip]; h = v[j][iq]; v[j][ip] = g - s * (h + g * tau); v[j][iq] = h + s * (g - h * tau); }
+          nrot++;
+        }
+      }
+    }
+    for(ip = 0; ip < n; ++ip)
+    {
+      b[ip] += z[ip];
+      d[ip] = b[ip];
+      z[ip] = 0.0;
+    }
+  }
+
+  std::cerr << "eigen: too many iterations in Jacobi transform." << std::endl;
+
+  return;
+}
+
+template<typename Derived>
+Eigen::FclOp<Eigen::Transpose<const typename Eigen::internal::remove_fcl<Derived>::type> > transpose(const FclType<Derived>& R)
+{
+  EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 3, 3);
+  return Eigen::FclOp<Eigen::Transpose<const typename Eigen::internal::remove_fcl<Derived>::type > > (R.fcl());
+}
+
+template<typename T, int _Options>
+Eigen::FclMatrix<T,3,_Options> inverse(const Eigen::FclMatrix<T, 3, _Options>& R)
+{
+  return R.inverse();
+}
+
+template<typename Matrix, typename Vector>
+typename Matrix::Scalar quadraticForm(const Matrix& R, const Vector& v)
+{
+  return v.dot(R * v);
+}
+
+
+}
+
+
+#endif
diff --git a/include/hpp/fcl/math/math_details.h b/include/hpp/fcl/math/math_details.h
index 91db7f524d8e29406aaae329407f490e9edc870d..391efd1f789a8d7d86cb5c7fc33fc6dab0b5b50e 100644
--- a/include/hpp/fcl/math/math_details.h
+++ b/include/hpp/fcl/math/math_details.h
@@ -36,6 +36,9 @@
 #ifndef FCL_MATH_DETAILS_H
 #define FCL_MATH_DETAILS_H
 
+#if FCL_HAVE_EIGEN
+# error "This file should not be included when compiling with Eigen library"
+#endif
 
 #include <cmath>
 #include <algorithm>
diff --git a/include/hpp/fcl/math/matrix_3f.h b/include/hpp/fcl/math/matrix_3f.h
index f67934e9c22e962897c3b48649bd9d70efae5b0d..b04d816b96a9360eeac190d9b2b2f295d181b6c9 100644
--- a/include/hpp/fcl/math/matrix_3f.h
+++ b/include/hpp/fcl/math/matrix_3f.h
@@ -40,436 +40,19 @@
 
 #include <hpp/fcl/math/vec_3f.h>
 
-namespace fcl
-{
-
-/// @brief Matrix2 class wrapper. the core data is in the template parameter class
-template<typename T>
-class Matrix3fX
-{
-public:
-  typedef typename T::meta_type U;
-  typedef typename T::vector_type S;
-  T data;
-  
-  Matrix3fX() {}
-  Matrix3fX(U xx, U xy, U xz,
-            U yx, U yy, U yz,
-            U zx, U zy, U zz) : data(xx, xy, xz, yx, yy, yz, zx, zy, zz)
-  {}
-
-  Matrix3fX(const Vec3fX<S>& v1, const Vec3fX<S>& v2, const Vec3fX<S>& v3)
-    : data(v1.data, v2.data, v3.data) {}
-  
-  Matrix3fX(const Matrix3fX<T>& other) : data(other.data) {}
-
-  Matrix3fX(const T& data_) : data(data_) {}
-  
-  inline Vec3fX<S> getColumn(size_t i) const
-  {
-    return Vec3fX<S>(data.getColumn(i));
-  }
-
-  inline Vec3fX<S> getRow(size_t i) const
-  {
-    return Vec3fX<S>(data.getRow(i));
-  }
-
-  inline U operator () (size_t i, size_t j) const
-  {
-    return data(i, j);
-  }
-
-  inline U& operator () (size_t i, size_t j)
-  {
-    return data(i, j);
-  }
-
-  inline Vec3fX<S> operator * (const Vec3fX<S>& v) const
-  {
-    return Vec3fX<S>(data * v.data);
-  }
-
-  inline Matrix3fX<T> operator * (const Matrix3fX<T>& m) const
-  {
-    return Matrix3fX<T>(data * m.data);
-  }
-
-  inline Matrix3fX<T> operator + (const Matrix3fX<T>& other) const
-  {
-    return Matrix3fX<T>(data + other.data);
-  }
-
-  inline Matrix3fX<T> operator - (const Matrix3fX<T>& other) const
-  {
-    return Matrix3fX<T>(data - other.data);
-  }
-
-  inline Matrix3fX<T> operator + (U c) const
-  {
-    return Matrix3fX<T>(data + c);
-  }
-
-  inline Matrix3fX<T> operator - (U c) const
-  {
-    return Matrix3fX<T>(data - c);
-  }
-
-  inline Matrix3fX<T> operator * (U c) const
-  {
-    return Matrix3fX<T>(data * c);
-  }
-
-  inline Matrix3fX<T> operator / (U c) const
-  {
-    return Matrix3fX<T>(data / c);
-  }
-
-  inline Matrix3fX<T>& operator *= (const Matrix3fX<T>& other)
-  {
-    data *= other.data;
-    return *this;
-  }
-
-  inline Matrix3fX<T>& operator += (const Matrix3fX<T>& other)
-  {
-    data += other.data;
-    return *this;
-  }
-
-  inline Matrix3fX<T>& operator -= (const Matrix3fX<T>& other)
-  {
-    data -= other.data;
-    return *this;
-  }
-
-  inline Matrix3fX<T>& operator += (U c) 
-  {
-    data += c;
-    return *this;
-  }
-
-  inline Matrix3fX<T>& operator -= (U c)
-  {
-    data -= c;
-    return *this;
-  }
-
-  inline Matrix3fX<T>& operator *= (U c)
-  {
-    data *= c;
-    return *this;
-  }
-
-  inline Matrix3fX<T>& operator /= (U c)
-  {
-    data /= c;
-    return *this;
-  }
-
-  inline void setIdentity()
-  {
-    data.setIdentity();
-  }
-
-  inline bool isIdentity () const
-  {
-    return
-      data (0,0) == 1 && data (0,1) == 0 && data (0,2) == 0 &&
-      data (1,0) == 0 && data (1,1) == 1 && data (1,2) == 0 &&
-      data (2,0) == 0 && data (2,1) == 0 && data (2,2) == 1;
-  }
-
-  inline void setZero()
-  {
-    data.setZero();
-  }
-
-  /// @brief Set the matrix from euler angles YPR around ZYX axes
-  /// @param eulerX Roll about X axis
-  /// @param eulerY Pitch around Y axis
-  /// @param eulerZ Yaw aboud Z axis
-  ///  
-  /// These angles are used to produce a rotation matrix. The euler
-  /// angles are applied in ZYX order. I.e a vector is first rotated 
-  /// about X then Y and then Z
-  inline void setEulerZYX(FCL_REAL eulerX, FCL_REAL eulerY, FCL_REAL eulerZ)
-  {
-    FCL_REAL ci(cos(eulerX));
-    FCL_REAL cj(cos(eulerY));
-    FCL_REAL ch(cos(eulerZ));
-    FCL_REAL si(sin(eulerX));
-    FCL_REAL sj(sin(eulerY));
-    FCL_REAL sh(sin(eulerZ));
-    FCL_REAL cc = ci * ch;
-    FCL_REAL cs = ci * sh;
-    FCL_REAL sc = si * ch;
-    FCL_REAL ss = si * sh;
-
-    setValue(cj * ch, sj * sc - cs, sj * cc + ss,
-             cj * sh, sj * ss + cc, sj * cs - sc, 
-             -sj,     cj * si,      cj * ci);
-
-  }
-
-  /// @brief Set the matrix from euler angles using YPR around YXZ respectively
-  /// @param yaw Yaw about Y axis
-  /// @param pitch Pitch about X axis
-  /// @param roll Roll about Z axis 
-  void setEulerYPR(FCL_REAL yaw, FCL_REAL pitch, FCL_REAL roll)
-  {
-    setEulerZYX(roll, pitch, yaw);
-  }
-
-  inline U determinant() const
-  {
-    return data.determinant();
-  }
-
-  Matrix3fX<T>& transpose() 
-  {
-    data.transpose();
-    return *this;
-  }
-
-  Matrix3fX<T>& inverse()
-  {
-    data.inverse();
-    return *this;
-  }
-
-  Matrix3fX<T>& abs()
-  {
-    data.abs();
-    return *this;
-  }
-
-  static const Matrix3fX<T>& getIdentity()
-  {
-    static const Matrix3fX<T> I((U)1, (U)0, (U)0,
-                                (U)0, (U)1, (U)0,
-                                (U)0, (U)0, (U)1);
-    return I;
-  }
-
-  Matrix3fX<T> transposeTimes(const Matrix3fX<T>& other) const
-  {
-    return Matrix3fX<T>(data.transposeTimes(other.data));
-  }
-
-  Matrix3fX<T> timesTranspose(const Matrix3fX<T>& other) const
-  {
-    return Matrix3fX<T>(data.timesTranspose(other.data));
-  }
-
-  Vec3fX<S> transposeTimes(const Vec3fX<S>& v) const
-  {
-    return Vec3fX<S>(data.transposeTimes(v.data));
-  }
-
-  Matrix3fX<T> tensorTransform(const Matrix3fX<T>& m) const
-  {
-    Matrix3fX<T> res(*this);
-    res *= m;
-    return res.timesTranspose(*this);
-  }
-
-  // (1 0 0)^T (*this)^T v
-  inline U transposeDotX(const Vec3fX<S>& v) const
-  {
-    return data.transposeDot(0, v.data);
-  }
-
-  // (0 1 0)^T (*this)^T v
-  inline U transposeDotY(const Vec3fX<S>& v) const
-  {
-    return data.transposeDot(1, v.data);
-  }
-
-  // (0 0 1)^T (*this)^T v
-  inline U transposeDotZ(const Vec3fX<S>& v) const
-  {
-    return data.transposeDot(2, v.data);
-  }
-
-  // (\delta_{i3})^T (*this)^T v
-  inline U transposeDot(size_t i, const Vec3fX<S>& v) const
-  {
-    return data.transposeDot(i, v.data);
-  }
-
-  // (1 0 0)^T (*this) v
-  inline U dotX(const Vec3fX<S>& v) const
-  {
-    return data.dot(0, v.data);
-  }
-
-  // (0 1 0)^T (*this) v
-  inline U dotY(const Vec3fX<S>& v) const
-  {
-    return data.dot(1, v.data);
-  }
-
-  // (0 0 1)^T (*this) v
-  inline U dotZ(const Vec3fX<S>& v) const
-  {
-    return data.dot(2, v.data);
-  }
-
-  // (\delta_{i3})^T (*this) v
-  inline U dot(size_t i, const Vec3fX<S>& v) const
-  {
-    return data.dot(i, v.data);
-  }
-
-  inline void setValue(U xx, U xy, U xz,
-                       U yx, U yy, U yz,
-                       U zx, U zy, U zz)
-  {
-    data.setValue(xx, xy, xz, 
-                  yx, yy, yz,
-                  zx, zy, zz);
-  }
-
-  inline void setValue(U x)
-  {
-    data.setValue(x);
-  }
-};
-
-template<typename T>
-void hat(Matrix3fX<T>& mat, const Vec3fX<typename T::vector_type>& vec)
-{
-  mat.setValue(0, -vec[2], vec[1], vec[2], 0, -vec[0], -vec[1], vec[0], 0);
-}
-
-template<typename T>
-void relativeTransform(const Matrix3fX<T>& R1, const Vec3fX<typename T::vector_type>& t1,
-                       const Matrix3fX<T>& R2, const Vec3fX<typename T::vector_type>& t2,
-                       Matrix3fX<T>& R, Vec3fX<typename T::vector_type>& t)
-{
-  R = R1.transposeTimes(R2);
-  t = R1.transposeTimes(t2 - t1);
-}
-
-/// @brief compute the eigen vector and eigen vector of a matrix. dout is the eigen values, vout is the eigen vectors
-template<typename T>
-void eigen(const Matrix3fX<T>& m, typename T::meta_type dout[3], Vec3fX<typename T::vector_type> vout[3])
-{
-  Matrix3fX<T> R(m);
-  int n = 3;
-  int j, iq, ip, i;
-  typename T::meta_type tresh, theta, tau, t, sm, s, h, g, c;
-  int nrot;
-  typename T::meta_type b[3];
-  typename T::meta_type z[3];
-  typename T::meta_type v[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
-  typename T::meta_type d[3];
-
-  for(ip = 0; ip < n; ++ip)
-  {
-    b[ip] = d[ip] = R(ip, ip);
-    z[ip] = 0;
-  }
-
-  nrot = 0;
-
-  for(i = 0; i < 50; ++i)
-  {
-    sm = 0;
-    for(ip = 0; ip < n; ++ip)
-      for(iq = ip + 1; iq < n; ++iq)
-        sm += std::abs(R(ip, iq));
-    if(sm == 0.0)
-    {
-      vout[0].setValue(v[0][0], v[0][1], v[0][2]);
-      vout[1].setValue(v[1][0], v[1][1], v[1][2]);
-      vout[2].setValue(v[2][0], v[2][1], v[2][2]);
-      dout[0] = d[0]; dout[1] = d[1]; dout[2] = d[2];
-      return;
-    }
-
-    if(i < 3) tresh = 0.2 * sm / (n * n);
-    else tresh = 0.0;
-
-    for(ip = 0; ip < n; ++ip)
-    {
-      for(iq= ip + 1; iq < n; ++iq)
-      {
-        g = 100.0 * std::abs(R(ip, iq));
-        if(i > 3 &&
-           std::abs(d[ip]) + g == std::abs(d[ip]) &&
-           std::abs(d[iq]) + g == std::abs(d[iq]))
-          R(ip, iq) = 0.0;
-        else if(std::abs(R(ip, iq)) > tresh)
-        {
-          h = d[iq] - d[ip];
-          if(std::abs(h) + g == std::abs(h)) t = (R(ip, iq)) / h;
-          else
-          {
-            theta = 0.5 * h / (R(ip, iq));
-            t = 1.0 /(std::abs(theta) + std::sqrt(1.0 + theta * theta));
-            if(theta < 0.0) t = -t;
-          }
-          c = 1.0 / std::sqrt(1 + t * t);
-          s = t * c;
-          tau = s / (1.0 + c);
-          h = t * R(ip, iq);
-          z[ip] -= h;
-          z[iq] += h;
-          d[ip] -= h;
-          d[iq] += h;
-          R(ip, iq) = 0.0;
-          for(j = 0; j < ip; ++j) { g = R(j, ip); h = R(j, iq); R(j, ip) = g - s * (h + g * tau); R(j, iq) = h + s * (g - h * tau); }
-          for(j = ip + 1; j < iq; ++j) { g = R(ip, j); h = R(j, iq); R(ip, j) = g - s * (h + g * tau); R(j, iq) = h + s * (g - h * tau); }
-          for(j = iq + 1; j < n; ++j) { g = R(ip, j); h = R(iq, j); R(ip, j) = g - s * (h + g * tau); R(iq, j) = h + s * (g - h * tau); }
-          for(j = 0; j < n; ++j) { g = v[j][ip]; h = v[j][iq]; v[j][ip] = g - s * (h + g * tau); v[j][iq] = h + s * (g - h * tau); }
-          nrot++;
-        }
-      }
-    }
-    for(ip = 0; ip < n; ++ip)
-    {
-      b[ip] += z[ip];
-      d[ip] = b[ip];
-      z[ip] = 0.0;
-    }
-  }
-
-  std::cerr << "eigen: too many iterations in Jacobi transform." << std::endl;
-
-  return;
-}
-
-template<typename T>
-Matrix3fX<T> abs(const Matrix3fX<T>& R) 
-{
-  return Matrix3fX<T>(abs(R.data));
-}
-
-template<typename T>
-Matrix3fX<T> transpose(const Matrix3fX<T>& R)
-{
-  return Matrix3fX<T>(transpose(R.data));
-}
-
-template<typename T>
-Matrix3fX<T> inverse(const Matrix3fX<T>& R)
-{
-  return Matrix3fX<T>(inverse(R.data));
-}
+#if ! FCL_HAVE_EIGEN
+# include <hpp/fcl/math/matrix_3fx.h>
+#endif
 
-template<typename T>
-typename T::meta_type quadraticForm(const Matrix3fX<T>& R, const Vec3fX<typename T::vector_type>& v)
+namespace fcl
 {
-  return v.dot(R * v);
-}
-
 
-#if FCL_HAVE_SSE
-typedef Matrix3fX<details::sse_meta_f12> Matrix3f;
+#if FCL_HAVE_EIGEN
+  typedef Eigen::FclMatrix<FCL_REAL, 3> Matrix3f;
+#elif FCL_HAVE_SSE
+  typedef Matrix3fX<details::sse_meta_f12> Matrix3f;
 #else
-typedef Matrix3fX<details::Matrix3Data<FCL_REAL> > Matrix3f;
+  typedef Matrix3fX<details::Matrix3Data<FCL_REAL> > Matrix3f;
 #endif
 
 static inline std::ostream& operator << (std::ostream& o, const Matrix3f& m)
diff --git a/include/hpp/fcl/math/matrix_3fx.h b/include/hpp/fcl/math/matrix_3fx.h
new file mode 100644
index 0000000000000000000000000000000000000000..18584b0652ee56f850567b76672eff362301f54e
--- /dev/null
+++ b/include/hpp/fcl/math/matrix_3fx.h
@@ -0,0 +1,470 @@
+/*
+ * Software License Agreement (BSD License)
+ *
+ *  Copyright (c) 2011-2014, Willow Garage, Inc.
+ *  Copyright (c) 2014-2015, Open Source Robotics Foundation
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of Open Source Robotics Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** \author Jia Pan */
+
+#ifndef FCL_MATRIX_3FX_H
+#define FCL_MATRIX_3FX_H
+
+#include <hpp/fcl/math/vec_3f.h>
+
+namespace fcl
+{
+
+/// @brief Matrix2 class wrapper. the core data is in the template parameter class
+template<typename T>
+class Matrix3fX
+{
+public:
+  typedef typename T::meta_type U;
+  typedef typename T::vector_type S;
+  T data;
+  
+  Matrix3fX() {}
+  Matrix3fX(U xx, U xy, U xz,
+            U yx, U yy, U yz,
+            U zx, U zy, U zz) : data(xx, xy, xz, yx, yy, yz, zx, zy, zz)
+  {}
+
+  Matrix3fX(const Vec3fX<S>& v1, const Vec3fX<S>& v2, const Vec3fX<S>& v3)
+    : data(v1.data, v2.data, v3.data) {}
+  
+  Matrix3fX(const Matrix3fX<T>& other) : data(other.data) {}
+
+  Matrix3fX(const T& data_) : data(data_) {}
+  
+  inline Vec3fX<S> getColumn(size_t i) const
+  {
+    return Vec3fX<S>(data.getColumn(i));
+  }
+
+  inline Vec3fX<S> getRow(size_t i) const
+  {
+    return Vec3fX<S>(data.getRow(i));
+  }
+
+  inline U operator () (size_t i, size_t j) const
+  {
+    return data(i, j);
+  }
+
+  inline U& operator () (size_t i, size_t j)
+  {
+    return data(i, j);
+  }
+
+  inline Vec3fX<S> operator * (const Vec3fX<S>& v) const
+  {
+    return Vec3fX<S>(data * v.data);
+  }
+
+  inline Matrix3fX<T> operator * (const Matrix3fX<T>& m) const
+  {
+    return Matrix3fX<T>(data * m.data);
+  }
+
+  inline Matrix3fX<T> operator + (const Matrix3fX<T>& other) const
+  {
+    return Matrix3fX<T>(data + other.data);
+  }
+
+  inline Matrix3fX<T> operator - (const Matrix3fX<T>& other) const
+  {
+    return Matrix3fX<T>(data - other.data);
+  }
+
+  inline Matrix3fX<T> operator + (U c) const
+  {
+    return Matrix3fX<T>(data + c);
+  }
+
+  inline Matrix3fX<T> operator - (U c) const
+  {
+    return Matrix3fX<T>(data - c);
+  }
+
+  inline Matrix3fX<T> operator * (U c) const
+  {
+    return Matrix3fX<T>(data * c);
+  }
+
+  inline Matrix3fX<T> operator / (U c) const
+  {
+    return Matrix3fX<T>(data / c);
+  }
+
+  inline Matrix3fX<T>& operator *= (const Matrix3fX<T>& other)
+  {
+    data *= other.data;
+    return *this;
+  }
+
+  inline Matrix3fX<T>& operator += (const Matrix3fX<T>& other)
+  {
+    data += other.data;
+    return *this;
+  }
+
+  inline Matrix3fX<T>& operator -= (const Matrix3fX<T>& other)
+  {
+    data -= other.data;
+    return *this;
+  }
+
+  inline Matrix3fX<T>& operator += (U c) 
+  {
+    data += c;
+    return *this;
+  }
+
+  inline Matrix3fX<T>& operator -= (U c)
+  {
+    data -= c;
+    return *this;
+  }
+
+  inline Matrix3fX<T>& operator *= (U c)
+  {
+    data *= c;
+    return *this;
+  }
+
+  inline Matrix3fX<T>& operator /= (U c)
+  {
+    data /= c;
+    return *this;
+  }
+
+  inline void setIdentity()
+  {
+    data.setIdentity();
+  }
+
+  inline bool isIdentity () const
+  {
+    return
+      data (0,0) == 1 && data (0,1) == 0 && data (0,2) == 0 &&
+      data (1,0) == 0 && data (1,1) == 1 && data (1,2) == 0 &&
+      data (2,0) == 0 && data (2,1) == 0 && data (2,2) == 1;
+  }
+
+  inline void setZero()
+  {
+    data.setZero();
+  }
+
+  /// @brief Set the matrix from euler angles YPR around ZYX axes
+  /// @param eulerX Roll about X axis
+  /// @param eulerY Pitch around Y axis
+  /// @param eulerZ Yaw aboud Z axis
+  ///  
+  /// These angles are used to produce a rotation matrix. The euler
+  /// angles are applied in ZYX order. I.e a vector is first rotated 
+  /// about X then Y and then Z
+  inline void setEulerZYX(FCL_REAL eulerX, FCL_REAL eulerY, FCL_REAL eulerZ)
+  {
+    FCL_REAL ci(cos(eulerX));
+    FCL_REAL cj(cos(eulerY));
+    FCL_REAL ch(cos(eulerZ));
+    FCL_REAL si(sin(eulerX));
+    FCL_REAL sj(sin(eulerY));
+    FCL_REAL sh(sin(eulerZ));
+    FCL_REAL cc = ci * ch;
+    FCL_REAL cs = ci * sh;
+    FCL_REAL sc = si * ch;
+    FCL_REAL ss = si * sh;
+
+    setValue(cj * ch, sj * sc - cs, sj * cc + ss,
+             cj * sh, sj * ss + cc, sj * cs - sc, 
+             -sj,     cj * si,      cj * ci);
+
+  }
+
+  /// @brief Set the matrix from euler angles using YPR around YXZ respectively
+  /// @param yaw Yaw about Y axis
+  /// @param pitch Pitch about X axis
+  /// @param roll Roll about Z axis 
+  void setEulerYPR(FCL_REAL yaw, FCL_REAL pitch, FCL_REAL roll)
+  {
+    setEulerZYX(roll, pitch, yaw);
+  }
+
+  inline U determinant() const
+  {
+    return data.determinant();
+  }
+
+  Matrix3fX<T>& transpose() 
+  {
+    data.transpose();
+    return *this;
+  }
+
+  Matrix3fX<T>& inverse()
+  {
+    data.inverse();
+    return *this;
+  }
+
+  Matrix3fX<T>& abs()
+  {
+    data.abs();
+    return *this;
+  }
+
+  static const Matrix3fX<T>& getIdentity()
+  {
+    static const Matrix3fX<T> I((U)1, (U)0, (U)0,
+                                (U)0, (U)1, (U)0,
+                                (U)0, (U)0, (U)1);
+    return I;
+  }
+
+  Matrix3fX<T> transposeTimes(const Matrix3fX<T>& other) const
+  {
+    return Matrix3fX<T>(data.transposeTimes(other.data));
+  }
+
+  Matrix3fX<T> timesTranspose(const Matrix3fX<T>& other) const
+  {
+    return Matrix3fX<T>(data.timesTranspose(other.data));
+  }
+
+  Vec3fX<S> transposeTimes(const Vec3fX<S>& v) const
+  {
+    return Vec3fX<S>(data.transposeTimes(v.data));
+  }
+
+  Matrix3fX<T> tensorTransform(const Matrix3fX<T>& m) const
+  {
+    Matrix3fX<T> res(*this);
+    res *= m;
+    return res.timesTranspose(*this);
+  }
+
+  // (1 0 0)^T (*this)^T v
+  inline U transposeDotX(const Vec3fX<S>& v) const
+  {
+    return data.transposeDot(0, v.data);
+  }
+
+  // (0 1 0)^T (*this)^T v
+  inline U transposeDotY(const Vec3fX<S>& v) const
+  {
+    return data.transposeDot(1, v.data);
+  }
+
+  // (0 0 1)^T (*this)^T v
+  inline U transposeDotZ(const Vec3fX<S>& v) const
+  {
+    return data.transposeDot(2, v.data);
+  }
+
+  // (\delta_{i3})^T (*this)^T v
+  inline U transposeDot(size_t i, const Vec3fX<S>& v) const
+  {
+    return data.transposeDot(i, v.data);
+  }
+
+  // (1 0 0)^T (*this) v
+  inline U dotX(const Vec3fX<S>& v) const
+  {
+    return data.dot(0, v.data);
+  }
+
+  // (0 1 0)^T (*this) v
+  inline U dotY(const Vec3fX<S>& v) const
+  {
+    return data.dot(1, v.data);
+  }
+
+  // (0 0 1)^T (*this) v
+  inline U dotZ(const Vec3fX<S>& v) const
+  {
+    return data.dot(2, v.data);
+  }
+
+  // (\delta_{i3})^T (*this) v
+  inline U dot(size_t i, const Vec3fX<S>& v) const
+  {
+    return data.dot(i, v.data);
+  }
+
+  inline void setValue(U xx, U xy, U xz,
+                       U yx, U yy, U yz,
+                       U zx, U zy, U zz)
+  {
+    data.setValue(xx, xy, xz, 
+                  yx, yy, yz,
+                  zx, zy, zz);
+  }
+
+  inline void setValue(U x)
+  {
+    data.setValue(x);
+  }
+};
+
+template<typename T>
+void hat(Matrix3fX<T>& mat, const Vec3fX<typename T::vector_type>& vec)
+{
+  mat.setValue(0, -vec[2], vec[1], vec[2], 0, -vec[0], -vec[1], vec[0], 0);
+}
+
+template<typename T>
+void relativeTransform(const Matrix3fX<T>& R1, const Vec3fX<typename T::vector_type>& t1,
+                       const Matrix3fX<T>& R2, const Vec3fX<typename T::vector_type>& t2,
+                       Matrix3fX<T>& R, Vec3fX<typename T::vector_type>& t)
+{
+  R = R1.transposeTimes(R2);
+  t = R1.transposeTimes(t2 - t1);
+}
+
+/// @brief compute the eigen vector and eigen vector of a matrix. dout is the eigen values, vout is the eigen vectors
+template<typename T>
+void eigen(const Matrix3fX<T>& m, typename T::meta_type dout[3], Vec3fX<typename T::vector_type> vout[3])
+{
+  Matrix3fX<T> R(m);
+  int n = 3;
+  int j, iq, ip, i;
+  typename T::meta_type tresh, theta, tau, t, sm, s, h, g, c;
+  int nrot;
+  typename T::meta_type b[3];
+  typename T::meta_type z[3];
+  typename T::meta_type v[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
+  typename T::meta_type d[3];
+
+  for(ip = 0; ip < n; ++ip)
+  {
+    b[ip] = d[ip] = R(ip, ip);
+    z[ip] = 0;
+  }
+
+  nrot = 0;
+
+  for(i = 0; i < 50; ++i)
+  {
+    sm = 0;
+    for(ip = 0; ip < n; ++ip)
+      for(iq = ip + 1; iq < n; ++iq)
+        sm += std::abs(R(ip, iq));
+    if(sm == 0.0)
+    {
+      vout[0].setValue(v[0][0], v[0][1], v[0][2]);
+      vout[1].setValue(v[1][0], v[1][1], v[1][2]);
+      vout[2].setValue(v[2][0], v[2][1], v[2][2]);
+      dout[0] = d[0]; dout[1] = d[1]; dout[2] = d[2];
+      return;
+    }
+
+    if(i < 3) tresh = 0.2 * sm / (n * n);
+    else tresh = 0.0;
+
+    for(ip = 0; ip < n; ++ip)
+    {
+      for(iq= ip + 1; iq < n; ++iq)
+      {
+        g = 100.0 * std::abs(R(ip, iq));
+        if(i > 3 &&
+           std::abs(d[ip]) + g == std::abs(d[ip]) &&
+           std::abs(d[iq]) + g == std::abs(d[iq]))
+          R(ip, iq) = 0.0;
+        else if(std::abs(R(ip, iq)) > tresh)
+        {
+          h = d[iq] - d[ip];
+          if(std::abs(h) + g == std::abs(h)) t = (R(ip, iq)) / h;
+          else
+          {
+            theta = 0.5 * h / (R(ip, iq));
+            t = 1.0 /(std::abs(theta) + std::sqrt(1.0 + theta * theta));
+            if(theta < 0.0) t = -t;
+          }
+          c = 1.0 / std::sqrt(1 + t * t);
+          s = t * c;
+          tau = s / (1.0 + c);
+          h = t * R(ip, iq);
+          z[ip] -= h;
+          z[iq] += h;
+          d[ip] -= h;
+          d[iq] += h;
+          R(ip, iq) = 0.0;
+          for(j = 0; j < ip; ++j) { g = R(j, ip); h = R(j, iq); R(j, ip) = g - s * (h + g * tau); R(j, iq) = h + s * (g - h * tau); }
+          for(j = ip + 1; j < iq; ++j) { g = R(ip, j); h = R(j, iq); R(ip, j) = g - s * (h + g * tau); R(j, iq) = h + s * (g - h * tau); }
+          for(j = iq + 1; j < n; ++j) { g = R(ip, j); h = R(iq, j); R(ip, j) = g - s * (h + g * tau); R(iq, j) = h + s * (g - h * tau); }
+          for(j = 0; j < n; ++j) { g = v[j][ip]; h = v[j][iq]; v[j][ip] = g - s * (h + g * tau); v[j][iq] = h + s * (g - h * tau); }
+          nrot++;
+        }
+      }
+    }
+    for(ip = 0; ip < n; ++ip)
+    {
+      b[ip] += z[ip];
+      d[ip] = b[ip];
+      z[ip] = 0.0;
+    }
+  }
+
+  std::cerr << "eigen: too many iterations in Jacobi transform." << std::endl;
+
+  return;
+}
+
+template<typename T>
+Matrix3fX<T> abs(const Matrix3fX<T>& R) 
+{
+  return Matrix3fX<T>(abs(R.data));
+}
+
+template<typename T>
+Matrix3fX<T> transpose(const Matrix3fX<T>& R)
+{
+  return Matrix3fX<T>(transpose(R.data));
+}
+
+template<typename T>
+Matrix3fX<T> inverse(const Matrix3fX<T>& R)
+{
+  return Matrix3fX<T>(inverse(R.data));
+}
+
+template<typename T>
+typename T::meta_type quadraticForm(const Matrix3fX<T>& R, const Vec3fX<typename T::vector_type>& v)
+{
+  return v.dot(R * v);
+}
+
+}
+
+#endif
diff --git a/include/hpp/fcl/math/vec_3f.h b/include/hpp/fcl/math/vec_3f.h
index 555d12b6249f3d447ef86ff7ca22d36a8add2277..f81e6da128d6ed07db88736b87c7e5d817e71d60 100644
--- a/include/hpp/fcl/math/vec_3f.h
+++ b/include/hpp/fcl/math/vec_3f.h
@@ -40,10 +40,19 @@
 
 #include <hpp/fcl/config-fcl.hh>
 #include <hpp/fcl/data_types.h>
-#include <hpp/fcl/math/math_details.h>
 
-#if FCL_HAVE_SSE
-#include <hpp/fcl/simd/math_simd_details.h>
+#if FCL_HAVE_EIGEN
+#  include <hpp/fcl/eigen/math_details.h>
+#elif FCL_HAVE_SSE
+# include <hpp/fcl/simd/math_simd_details.h>
+#else
+# include <hpp/fcl/math/math_details.h>
+#endif
+
+#if FCL_HAVE_EIGEN
+# include <hpp/fcl/eigen/vec_3fx.h>
+#else
+# include <hpp/fcl/math/vec_3fx.h>
 #endif
 
 #include <cmath>
@@ -54,186 +63,9 @@
 namespace fcl
 {
 
-/// @brief Vector3 class wrapper. The core data is in the template parameter class.
-template <typename T>
-class Vec3fX
-{
-public:
-  typedef typename T::meta_type U;
-
-  /// @brief interval vector3 data
-  T data;
-
-  Vec3fX() {}
-  Vec3fX(const Vec3fX& other) : data(other.data) {}
-
-  /// @brief create Vector (x, y, z)
-  Vec3fX(U x, U y, U z) : data(x, y, z) {}
-
-  /// @brief create vector (x, x, x)
-  Vec3fX(U x) : data(x) {}
-
-  /// @brief create vector using the internal data type
-  Vec3fX(const T& data_) : data(data_) {}
-
-  inline U operator [] (size_t i) const { return data[i]; }
-  inline U& operator [] (size_t i) { return data[i]; }
-
-  inline Vec3fX operator + (const Vec3fX& other) const { return Vec3fX(data + other.data); }
-  inline Vec3fX operator - (const Vec3fX& other) const { return Vec3fX(data - other.data); }
-  inline Vec3fX operator * (const Vec3fX& other) const { return Vec3fX(data * other.data); }
-  inline Vec3fX operator / (const Vec3fX& other) const { return Vec3fX(data / other.data); }
-  inline Vec3fX& operator += (const Vec3fX& other) { data += other.data; return *this; }
-  inline Vec3fX& operator -= (const Vec3fX& other) { data -= other.data; return *this; }
-  inline Vec3fX& operator *= (const Vec3fX& other) { data *= other.data; return *this; }
-  inline Vec3fX& operator /= (const Vec3fX& other) { data /= other.data; return *this; }
-  inline Vec3fX operator + (U t) const { return Vec3fX(data + t); }
-  inline Vec3fX operator - (U t) const { return Vec3fX(data - t); }
-  inline Vec3fX operator * (U t) const { return Vec3fX(data * t); }
-  inline Vec3fX operator / (U t) const { return Vec3fX(data / t); }
-  inline Vec3fX& operator += (U t) { data += t; return *this; }
-  inline Vec3fX& operator -= (U t) { data -= t; return *this; }
-  inline Vec3fX& operator *= (U t) { data *= t; return *this; }
-  inline Vec3fX& operator /= (U t) { data /= t; return *this; }
-  inline Vec3fX operator - () const { return Vec3fX(-data); }
-  inline Vec3fX cross(const Vec3fX& other) const { return Vec3fX(details::cross_prod(data, other.data)); }
-  inline U dot(const Vec3fX& other) const { return details::dot_prod3(data, other.data); }
-  inline Vec3fX& normalize()
-  {
-    U sqr_length = details::dot_prod3(data, data);
-    if(sqr_length > 0)
-      *this /= (U)sqrt(sqr_length);
-    return *this;
-  }
-
-  inline Vec3fX& normalize(bool* signal)
-  {
-    U sqr_length = details::dot_prod3(data, data);
-    if(sqr_length > 0)
-    {
-      *this /= (U)sqrt(sqr_length);
-      *signal = true;
-    }
-    else
-      *signal = false;
-    return *this;
-  }
-
-  inline Vec3fX& abs() 
-  {
-    data = abs(data);
-    return *this;
-  }
-
-  inline U length() const { return sqrt(details::dot_prod3(data, data)); }
-  inline U norm() const { return sqrt(details::dot_prod3(data, data)); }
-  inline U sqrLength() const { return details::dot_prod3(data, data); }
-  inline U squaredNorm() const { return details::dot_prod3(data, data); }
-  inline void setValue(U x, U y, U z) { data.setValue(x, y, z); }
-  inline void setValue(U x) { data.setValue(x); }
-  inline void setZero () {data.setValue (0); }
-  inline bool equal(const Vec3fX& other, U epsilon = std::numeric_limits<U>::epsilon() * 100) const { return details::equal(data, other.data, epsilon); }
-  inline Vec3fX<T>& negate() { data.negate(); return *this; }
-
-  bool operator == (const Vec3fX& other) const
-  {
-    return equal(other, 0);
-  }
-
-  bool operator != (const Vec3fX& other) const
-  {
-    return !(*this == other);
-  }
-
-
-  inline Vec3fX<T>& ubound(const Vec3fX<T>& u)
-  {
-    data.ubound(u.data);
-    return *this;
-  }
-
-  inline Vec3fX<T>& lbound(const Vec3fX<T>& l)
-  {
-    data.lbound(l.data);
-    return *this;
-  }
-
-  bool isZero() const
-  {
-    return (data[0] == 0) && (data[1] == 0) && (data[2] == 0);
-  }
-
-};
-
-template<typename T>
-static inline Vec3fX<T> normalize(const Vec3fX<T>& v)
-{
-  typename T::meta_type sqr_length = details::dot_prod3(v.data, v.data);
-  if(sqr_length > 0)
-    return v / (typename T::meta_type)sqrt(sqr_length);
-  else
-    return v;
-}
-
-template <typename T>
-static inline typename T::meta_type triple(const Vec3fX<T>& x, const Vec3fX<T>& y, const Vec3fX<T>& z)
-{
-  return x.dot(y.cross(z));
-}
-
-template <typename T>
-std::ostream& operator << (std::ostream& out, const Vec3fX<T>& x)
-{
-  out << x[0] << " " << x[1] << " " << x[2];
-  return out;
-}
-
-template <typename T>
-static inline Vec3fX<T> min(const Vec3fX<T>& x, const Vec3fX<T>& y)
-{
-  return Vec3fX<T>(details::min(x.data, y.data));
-}
-
-template <typename T>
-static inline Vec3fX<T> max(const Vec3fX<T>& x, const Vec3fX<T>& y)
-{
-  return Vec3fX<T>(details::max(x.data, y.data));
-}
-
-template <typename T>
-static inline Vec3fX<T> abs(const Vec3fX<T>& x)
-{
-  return Vec3fX<T>(details::abs(x.data));
-}
-
-template <typename T>
-void generateCoordinateSystem(const Vec3fX<T>& w, Vec3fX<T>& u, Vec3fX<T>& v)
-{
-  typedef typename T::meta_type U;
-  U inv_length;
-  if(std::abs(w[0]) >= std::abs(w[1]))
-  {
-    inv_length = (U)1.0 / sqrt(w[0] * w[0] + w[2] * w[2]);
-    u[0] = -w[2] * inv_length;
-    u[1] = (U)0;
-    u[2] = w[0] * inv_length;
-    v[0] = w[1] * u[2];
-    v[1] = w[2] * u[0] - w[0] * u[2];
-    v[2] = -w[1] * u[0];
-  }
-  else
-  {
-    inv_length = (U)1.0 / sqrt(w[1] * w[1] + w[2] * w[2]);
-    u[0] = (U)0;
-    u[1] = w[2] * inv_length;
-    u[2] = -w[1] * inv_length;
-    v[0] = w[1] * u[2] - w[2] * u[1];
-    v[1] = -w[0] * u[2];
-    v[2] = w[0] * u[1];
-  }
-}
-
-#if FCL_HAVE_SSE
+#if FCL_HAVE_EIGEN
+  typedef Eigen::FclMatrix<FCL_REAL, 1> Vec3f;
+#elif FCL_HAVE_SSE
   typedef Vec3fX<details::sse_meta_f4> Vec3f;
 #else
   typedef Vec3fX<details::Vec3Data<FCL_REAL> > Vec3f;
@@ -245,14 +77,6 @@ static inline std::ostream& operator << (std::ostream& o, const Vec3f& v)
   return o;
 }
 
- template <typename T>
-   inline Vec3fX <T> operator * (const typename Vec3fX <T>::U& t,
-				 const Vec3fX <T>& v)
-   {
-     return Vec3fX <T> (v.data * t);
-   }
-
-
 }
 
 
diff --git a/include/hpp/fcl/math/vec_3fx.h b/include/hpp/fcl/math/vec_3fx.h
new file mode 100644
index 0000000000000000000000000000000000000000..4cc8d86907cb73442dc1650d3f38771616034917
--- /dev/null
+++ b/include/hpp/fcl/math/vec_3fx.h
@@ -0,0 +1,241 @@
+/*
+ * Software License Agreement (BSD License)
+ *
+ *  Copyright (c) 2011-2014, Willow Garage, Inc.
+ *  Copyright (c) 2014-2015, Open Source Robotics Foundation
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of Open Source Robotics Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** \author Jia Pan */
+
+#ifndef FCL_VEC_3FX_H
+#define FCL_VEC_3FX_H
+
+#include <hpp/fcl/config-fcl.hh>
+#include <hpp/fcl/data_types.h>
+
+#include <cmath>
+#include <iostream>
+#include <limits>
+
+
+namespace fcl
+{
+
+/// @brief Vector3 class wrapper. The core data is in the template parameter class.
+template <typename T>
+class Vec3fX
+{
+public:
+  typedef typename T::meta_type U;
+
+  /// @brief interval vector3 data
+  T data;
+
+  Vec3fX() {}
+  Vec3fX(const Vec3fX& other) : data(other.data) {}
+
+  /// @brief create Vector (x, y, z)
+  Vec3fX(U x, U y, U z) : data(x, y, z) {}
+
+  /// @brief create vector (x, x, x)
+  Vec3fX(U x) : data(x) {}
+
+  /// @brief create vector using the internal data type
+  Vec3fX(const T& data_) : data(data_) {}
+
+  inline U operator [] (size_t i) const { return data[i]; }
+  inline U& operator [] (size_t i) { return data[i]; }
+
+  inline Vec3fX operator + (const Vec3fX& other) const { return Vec3fX(data + other.data); }
+  inline Vec3fX operator - (const Vec3fX& other) const { return Vec3fX(data - other.data); }
+  inline Vec3fX operator * (const Vec3fX& other) const { return Vec3fX(data * other.data); }
+  inline Vec3fX operator / (const Vec3fX& other) const { return Vec3fX(data / other.data); }
+  inline Vec3fX& operator += (const Vec3fX& other) { data += other.data; return *this; }
+  inline Vec3fX& operator -= (const Vec3fX& other) { data -= other.data; return *this; }
+  inline Vec3fX& operator *= (const Vec3fX& other) { data *= other.data; return *this; }
+  inline Vec3fX& operator /= (const Vec3fX& other) { data /= other.data; return *this; }
+  inline Vec3fX operator + (U t) const { return Vec3fX(data + t); }
+  inline Vec3fX operator - (U t) const { return Vec3fX(data - t); }
+  inline Vec3fX operator * (U t) const { return Vec3fX(data * t); }
+  inline Vec3fX operator / (U t) const { return Vec3fX(data / t); }
+  inline Vec3fX& operator += (U t) { data += t; return *this; }
+  inline Vec3fX& operator -= (U t) { data -= t; return *this; }
+  inline Vec3fX& operator *= (U t) { data *= t; return *this; }
+  inline Vec3fX& operator /= (U t) { data /= t; return *this; }
+  inline Vec3fX operator - () const { return Vec3fX(-data); }
+  inline Vec3fX cross(const Vec3fX& other) const { return Vec3fX(details::cross_prod(data, other.data)); }
+  inline U dot(const Vec3fX& other) const { return details::dot_prod3(data, other.data); }
+  inline Vec3fX& normalize()
+  {
+    U sqr_length = details::dot_prod3(data, data);
+    if(sqr_length > 0)
+      *this /= (U)sqrt(sqr_length);
+    return *this;
+  }
+
+  inline Vec3fX& normalize(bool* signal)
+  {
+    U sqr_length = details::dot_prod3(data, data);
+    if(sqr_length > 0)
+    {
+      *this /= (U)sqrt(sqr_length);
+      *signal = true;
+    }
+    else
+      *signal = false;
+    return *this;
+  }
+
+  inline Vec3fX& abs() 
+  {
+    data = abs(data);
+    return *this;
+  }
+
+  inline U length() const { return sqrt(details::dot_prod3(data, data)); }
+  inline U norm() const { return sqrt(details::dot_prod3(data, data)); }
+  inline U sqrLength() const { return details::dot_prod3(data, data); }
+  inline U squaredNorm() const { return details::dot_prod3(data, data); }
+  inline void setValue(U x, U y, U z) { data.setValue(x, y, z); }
+  inline void setValue(U x) { data.setValue(x); }
+  inline void setZero () {data.setValue (0); }
+  inline bool equal(const Vec3fX& other, U epsilon = std::numeric_limits<U>::epsilon() * 100) const { return details::equal(data, other.data, epsilon); }
+  inline Vec3fX<T>& negate() { data.negate(); return *this; }
+
+  bool operator == (const Vec3fX& other) const
+  {
+    return equal(other, 0);
+  }
+
+  bool operator != (const Vec3fX& other) const
+  {
+    return !(*this == other);
+  }
+
+
+  inline Vec3fX<T>& ubound(const Vec3fX<T>& u)
+  {
+    data.ubound(u.data);
+    return *this;
+  }
+
+  inline Vec3fX<T>& lbound(const Vec3fX<T>& l)
+  {
+    data.lbound(l.data);
+    return *this;
+  }
+
+  bool isZero() const
+  {
+    return (data[0] == 0) && (data[1] == 0) && (data[2] == 0);
+  }
+
+};
+
+template<typename T>
+static inline Vec3fX<T> normalize(const Vec3fX<T>& v)
+{
+  typename T::meta_type sqr_length = details::dot_prod3(v.data, v.data);
+  if(sqr_length > 0)
+    return v / (typename T::meta_type)sqrt(sqr_length);
+  else
+    return v;
+}
+
+template <typename T>
+static inline typename T::meta_type triple(const Vec3fX<T>& x, const Vec3fX<T>& y, const Vec3fX<T>& z)
+{
+  return x.dot(y.cross(z));
+}
+
+template <typename T>
+std::ostream& operator << (std::ostream& out, const Vec3fX<T>& x)
+{
+  out << x[0] << " " << x[1] << " " << x[2];
+  return out;
+}
+
+template <typename T>
+static inline Vec3fX<T> min(const Vec3fX<T>& x, const Vec3fX<T>& y)
+{
+  return Vec3fX<T>(details::min(x.data, y.data));
+}
+
+template <typename T>
+static inline Vec3fX<T> max(const Vec3fX<T>& x, const Vec3fX<T>& y)
+{
+  return Vec3fX<T>(details::max(x.data, y.data));
+}
+
+template <typename T>
+static inline Vec3fX<T> abs(const Vec3fX<T>& x)
+{
+  return Vec3fX<T>(details::abs(x.data));
+}
+
+template <typename T>
+void generateCoordinateSystem(const Vec3fX<T>& w, Vec3fX<T>& u, Vec3fX<T>& v)
+{
+  typedef typename T::meta_type U;
+  U inv_length;
+  if(std::abs(w[0]) >= std::abs(w[1]))
+  {
+    inv_length = (U)1.0 / sqrt(w[0] * w[0] + w[2] * w[2]);
+    u[0] = -w[2] * inv_length;
+    u[1] = (U)0;
+    u[2] = w[0] * inv_length;
+    v[0] = w[1] * u[2];
+    v[1] = w[2] * u[0] - w[0] * u[2];
+    v[2] = -w[1] * u[0];
+  }
+  else
+  {
+    inv_length = (U)1.0 / sqrt(w[1] * w[1] + w[2] * w[2]);
+    u[0] = (U)0;
+    u[1] = w[2] * inv_length;
+    u[2] = -w[1] * inv_length;
+    v[0] = w[1] * u[2] - w[2] * u[1];
+    v[1] = -w[0] * u[2];
+    v[2] = w[0] * u[1];
+  }
+}
+
+ template <typename T>
+   inline Vec3fX <T> operator * (const typename Vec3fX <T>::U& t,
+				 const Vec3fX <T>& v)
+   {
+     return Vec3fX <T> (v.data * t);
+   }
+
+}
+
+
+#endif
diff --git a/include/hpp/fcl/narrowphase/narrowphase.h b/include/hpp/fcl/narrowphase/narrowphase.h
index 0db42cdf967319f37a5be93f7a2d3dc0dcce02b7..eb308a1ce9f81d77d4f36d99ec2cc2f6f110ce85 100644
--- a/include/hpp/fcl/narrowphase/narrowphase.h
+++ b/include/hpp/fcl/narrowphase/narrowphase.h
@@ -209,12 +209,12 @@ struct GJKSolver_libccd
   }
 
 
-  void enableCachedGuess(bool if_enable) const
+  void enableCachedGuess(bool /*if_enable*/) const
   {
     // TODO: need change libccd to exploit spatial coherence
   }
 
-  void setCachedGuess(const Vec3f& guess) const
+  void setCachedGuess(const Vec3f& /*guess*/) const
   {
     // TODO: need change libccd to exploit spatial coherence
   }
diff --git a/include/hpp/fcl/shape/geometric_shapes.h b/include/hpp/fcl/shape/geometric_shapes.h
index 7d9322a0d5f7dc20b8362eb17270ba24886bdf42..6c8717ad522ca2edd5c6b93e10694205ca1cdf00 100644
--- a/include/hpp/fcl/shape/geometric_shapes.h
+++ b/include/hpp/fcl/shape/geometric_shapes.h
@@ -271,7 +271,7 @@ public:
          FCL_REAL* plane_dis_,
          int num_planes_,
          Vec3f* points_,
-         int num_points_,
+         int /*num_points_*/,
          int* polygons_) : ShapeBase()
   {
     plane_normals = plane_normals_;
diff --git a/include/hpp/fcl/traversal/traversal_node_base.h b/include/hpp/fcl/traversal/traversal_node_base.h
index 2208b0ab7fc077df553e12b9e4e3a12420864105..edaf35e340b4253fd3017c0ae6a94a009b963f97 100644
--- a/include/hpp/fcl/traversal/traversal_node_base.h
+++ b/include/hpp/fcl/traversal/traversal_node_base.h
@@ -106,7 +106,7 @@ public:
   virtual bool BVTesting(int b1, int b2, FCL_REAL& sqrDistLowerBound) const = 0;
 
   /// @brief Leaf test between node b1 and b2, if they are both leafs
-  virtual void leafTesting(int b1, int b2, FCL_REAL& sqrDistLowerBound) const
+  virtual void leafTesting(int /*b1*/, int /*b2*/, FCL_REAL& /*sqrDistLowerBound*/) const
   {
     throw std::runtime_error ("Not implemented");
   }
diff --git a/include/hpp/fcl/traversal/traversal_node_bvh_shape.h b/include/hpp/fcl/traversal/traversal_node_bvh_shape.h
index fe61f5f84540aa2bfc339434a67031765a4c0da5..119a549b40b3f11d3d4b4042d8c978c5b02bb493 100644
--- a/include/hpp/fcl/traversal/traversal_node_bvh_shape.h
+++ b/include/hpp/fcl/traversal/traversal_node_bvh_shape.h
@@ -723,7 +723,7 @@ public:
   }
 
   /// @brief BV culling test in one BVTT node
-  FCL_REAL BVTesting(int b1, int b2) const
+  FCL_REAL BVTesting(int b1, int /*b2*/) const
   {
     return model1->getBV(b1).bv.distance(model2_bv);
   }
@@ -803,7 +803,7 @@ public:
   }
 
   /// @brief Distance testing between leaves (one triangle and one shape)
-  void leafTesting(int b1, int b2) const
+  void leafTesting(int b1, int /*b2*/) const
   {
     if(this->enable_statistics) this->num_leaf_tests++;
     
@@ -987,7 +987,7 @@ public:
     
   }
 
-  FCL_REAL BVTesting(int b1, int b2) const
+  FCL_REAL BVTesting(int b1, int /*b2*/) const
   {
     if(this->enable_statistics) this->num_bv_tests++;
     return distance(this->tf1.getRotation(), this->tf1.getTranslation(), this->model2_bv, this->model1->getBV(b1).bv);
diff --git a/src/BV/OBB.cpp b/src/BV/OBB.cpp
index 8fb9e8dedf1229844d485197ff1e12bddcf5b4db..c89883caca70f6dc92aa669a666ba820f479b95a 100644
--- a/src/BV/OBB.cpp
+++ b/src/BV/OBB.cpp
@@ -610,7 +610,7 @@ OBB OBB::operator + (const OBB& other) const
 }
 
 
-FCL_REAL OBB::distance(const OBB& other, Vec3f* P, Vec3f* Q) const
+FCL_REAL OBB::distance(const OBB& /*other*/, Vec3f* /*P*/, Vec3f* /*Q*/) const
 {
   std::cerr << "OBB distance not implemented!" << std::endl;
   return 0.0;
diff --git a/src/BV/kDOP.cpp b/src/BV/kDOP.cpp
index 5c6f2ddd2fc0037949431e84703fd13d4d15fa75..dbdbc5fcc42d4e52b27883009e7292da578df565 100644
--- a/src/BV/kDOP.cpp
+++ b/src/BV/kDOP.cpp
@@ -220,7 +220,7 @@ KDOP<N> KDOP<N>::operator + (const KDOP<N>& other) const
 
 
 template<size_t N>
-FCL_REAL KDOP<N>::distance(const KDOP<N>& other, Vec3f* P, Vec3f* Q) const
+FCL_REAL KDOP<N>::distance(const KDOP<N>& /*other*/, Vec3f* /*P*/, Vec3f* /*Q*/) const
 {
   std::cerr << "KDOP distance not implemented!" << std::endl;
   return 0.0;
diff --git a/src/BV/kIOS.cpp b/src/BV/kIOS.cpp
index 111aecb40e8d4d82e546b69155e1ffbbe56e06fc..9a1ae33e743cbb443e9598f1d287c4a7446da2b1 100644
--- a/src/BV/kIOS.cpp
+++ b/src/BV/kIOS.cpp
@@ -63,7 +63,7 @@ bool kIOS::overlap(const kIOS& other) const
   return true;
 }
 
-  bool kIOS::overlap(const kIOS& other, FCL_REAL& sqrDistLowerBound) const
+  bool kIOS::overlap(const kIOS& /*other*/, FCL_REAL& /*sqrDistLowerBound*/) const
   {
     throw std::runtime_error ("Not implemented yet.");
   }
diff --git a/src/ccd/interpolation/interpolation_linear.cpp b/src/ccd/interpolation/interpolation_linear.cpp
index 3821531d2ed7388176db8e8606d61cf81294ff12..a9635dad0f15bcf00592cdac939981a6f0d18715 100644
--- a/src/ccd/interpolation/interpolation_linear.cpp
+++ b/src/ccd/interpolation/interpolation_linear.cpp
@@ -84,7 +84,7 @@ FCL_REAL InterpolationLinear::getMovementLengthBound(FCL_REAL time) const
   return getValueUpperBound() - getValue(time);
 }
 
-FCL_REAL InterpolationLinear::getVelocityBound(FCL_REAL time) const
+FCL_REAL InterpolationLinear::getVelocityBound(FCL_REAL /*time*/) const
 {
   return (value_1_ - value_0_);
 }
diff --git a/src/collision.cpp b/src/collision.cpp
index d71c1231919afef403732b3f2046460d487a30a0..6934af5da62ec2839754b5d61f633bf997a5ca58 100644
--- a/src/collision.cpp
+++ b/src/collision.cpp
@@ -50,7 +50,7 @@ CollisionFunctionMatrix<GJKSolver>& getCollisionFunctionLookTable()
 {
   static CollisionFunctionMatrix<GJKSolver> table;
   return table;
-};
+}
 
 template<typename NarrowPhaseSolver>
 std::size_t collide(const CollisionObject* o1, const CollisionObject* o2,
diff --git a/src/distance_func_matrix.cpp b/src/distance_func_matrix.cpp
index 84a182a1d549b511beeb51a1e88a02d452f1dd54..07d4feb10e39fc15ff6cde96815c6cc221baace7 100644
--- a/src/distance_func_matrix.cpp
+++ b/src/distance_func_matrix.cpp
@@ -280,7 +280,7 @@ FCL_REAL BVHDistance<OBBRSS>(const CollisionGeometry* o1, const Transform3f& tf1
 
 template<typename T_BVH, typename NarrowPhaseSolver>
 FCL_REAL BVHDistance(const CollisionGeometry* o1, const Transform3f& tf1, const CollisionGeometry* o2, const Transform3f& tf2,
-                     const NarrowPhaseSolver* nsolver,
+                     const NarrowPhaseSolver* /*nsolver*/,
                      const DistanceRequest& request, DistanceResult& result)
 {
   return BVHDistance<T_BVH>(o1, tf1, o2, tf2, request, result);
diff --git a/src/narrowphase/narrowphase.cpp b/src/narrowphase/narrowphase.cpp
index 4d2eb0a3ffd04a6540e28aad1bd3de3c313c5cc4..dfa5da3c10ff82a777a81dc5615a7b1d71d03c33 100644
--- a/src/narrowphase/narrowphase.cpp
+++ b/src/narrowphase/narrowphase.cpp
@@ -1882,7 +1882,7 @@ bool spherePlaneIntersect(const Sphere& s1, const Transform3f& tf1,
   FCL_REAL depth = - std::abs(signed_dist) + s1.radius;
   if(depth >= 0)
   {
-    if(normal) *normal = (signed_dist > 0) ? -new_s2.n : new_s2.n;
+    if(normal) { if (signed_dist > 0) *normal = -new_s2.n; else *normal = new_s2.n; }
     if(penetration_depth) *penetration_depth = depth;
     if(contact_points) *contact_points = center - new_s2.n * signed_dist;
 
@@ -1958,7 +1958,7 @@ bool boxPlaneIntersect(const Box& s1, const Transform3f& tf1,
 
   // compute the contact point by project the deepest point onto the plane
   if(penetration_depth) *penetration_depth = depth;
-  if(normal) *normal = (signed_dist > 0) ? -new_s2.n : new_s2.n;
+  if(normal) { if (signed_dist > 0) *normal = -new_s2.n; else *normal = new_s2.n; }
   if(contact_points) *contact_points = p - new_s2.n * new_s2.signedDistance(p);
 
   return true;
@@ -2025,13 +2025,13 @@ bool capsulePlaneIntersect(const Capsule& s1, const Transform3f& tf1,
       {
         if(penetration_depth) *penetration_depth = abs_d1 + s1.radius;
         if(contact_points) *contact_points = p1 * (abs_d2 / (abs_d1 + abs_d2)) + p2 * (abs_d1 / (abs_d1 + abs_d2));
-        if(normal) *normal = (d1 < 0) ? -new_s2.n : new_s2.n;
+        if(normal) { if (d1 < 0) *normal = -new_s2.n; else *normal = new_s2.n; }
       }
       else
       {
         if(penetration_depth) *penetration_depth = abs_d2 + s1.radius;
         if(contact_points) *contact_points = p1 * (abs_d2 / (abs_d1 + abs_d2)) + p2 * (abs_d1 / (abs_d1 + abs_d2));
-        if(normal) *normal = (d2 < 0) ? -new_s2.n : new_s2.n;
+        if(normal) { if (d2 < 0) *normal = -new_s2.n; else *normal = new_s2.n; }
       }
       return true;
     }
@@ -2062,7 +2062,7 @@ bool capsulePlaneIntersect(const Capsule& s1, const Transform3f& tf1,
         }
       }
         
-      if(normal) *normal = (d1 < 0) ? new_s2.n : -new_s2.n;
+      if(normal) { if (d1 < 0) *normal = new_s2.n; else *normal = -new_s2.n; }
       return true;
     }
   }
@@ -2117,7 +2117,7 @@ bool cylinderPlaneIntersect(const Cylinder& s1, const Transform3f& tf1,
       else
       {
         if(penetration_depth) *penetration_depth = depth;
-        if(normal) *normal = (d < 0) ? new_s2.n : -new_s2.n;
+        if(normal) { if (d < 0) *normal = new_s2.n; else *normal = -new_s2.n; }
         if(contact_points) *contact_points = T - new_s2.n * d;
         return true;
       }
@@ -2161,13 +2161,13 @@ bool cylinderPlaneIntersect(const Cylinder& s1, const Transform3f& tf1,
         {
           if(penetration_depth) *penetration_depth = abs_d2;
           if(contact_points) *contact_points = c2 - new_s2.n * d2;
-          if(normal) *normal = (d2 < 0) ? -new_s2.n : new_s2.n;
+          if(normal) { if (d2 < 0) *normal = -new_s2.n; else *normal = new_s2.n; }
         }
         else
         {
           if(penetration_depth) *penetration_depth = abs_d1;
           if(contact_points) *contact_points = c1 - new_s2.n * d1;
-          if(normal) *normal = (d1 < 0) ? -new_s2.n : new_s2.n;
+          if(normal) { if (d1 < 0) *normal = -new_s2.n; else *normal = new_s2.n; }
         }
         return true;
       }
@@ -2197,7 +2197,7 @@ bool conePlaneIntersect(const Cone& s1, const Transform3f& tf1,
     else
     {
       if(penetration_depth) *penetration_depth = depth;
-      if(normal) *normal = (d < 0) ? new_s2.n : -new_s2.n;
+      if(normal) { if (d < 0) *normal = new_s2.n; else *normal = -new_s2.n; }
       if(contact_points) *contact_points = T - dir_z * (0.5 * s1.lz) + dir_z * (0.5 * depth / s1.radius * s1.lz) - new_s2.n * d;
       return true;
     }
@@ -2248,7 +2248,7 @@ bool conePlaneIntersect(const Cone& s1, const Transform3f& tf1,
       }
 
       if(penetration_depth) *penetration_depth = std::min(d_positive, d_negative);
-      if(normal) *normal = (d_positive > d_negative) ? -new_s2.n : new_s2.n;
+      if(normal) { if (d_positive > d_negative) *normal = -new_s2.n; else *normal = new_s2.n; }
       if(contact_points)
       {
         Vec3f p[2];
@@ -2367,7 +2367,7 @@ bool planeTriangleIntersect(const Plane& s1, const Transform3f& tf1,
     }
 
     if(penetration_depth) *penetration_depth = std::min(d_positive, d_negative);
-    if(normal) *normal = (d_positive > d_negative) ? new_s1.n : -new_s1.n;
+    if(normal) { if (d_positive > d_negative) *normal = new_s1.n; else *normal = -new_s1.n; }
     if(contact_points)
     {
       Vec3f p[2];
@@ -2416,7 +2416,7 @@ bool halfspacePlaneIntersect(const Halfspace& s1, const Transform3f& tf1,
 
 bool planeIntersect(const Plane& s1, const Transform3f& tf1,
                     const Plane& s2, const Transform3f& tf2,
-                    Vec3f* contact_points, FCL_REAL* penetration_depth, Vec3f* normal)
+                    Vec3f* /*contact_points*/, FCL_REAL* /*penetration_depth*/, Vec3f* /*normal*/)
 {
   Plane new_s1 = transform(s1, tf1);
   Plane new_s2 = transform(s2, tf2);
@@ -2583,7 +2583,7 @@ bool GJKSolver_libccd::shapeIntersect<Halfspace, Cone>(const Halfspace& s1, cons
 template<>
 bool GJKSolver_libccd::shapeIntersect<Halfspace, Halfspace>(const Halfspace& s1, const Transform3f& tf1,
                                                             const Halfspace& s2, const Transform3f& tf2,
-                                                            Vec3f* contact_points, FCL_REAL* penetration_depth, Vec3f* normal) const
+                                                            Vec3f* /*contact_points*/, FCL_REAL* /*penetration_depth*/, Vec3f* /*normal*/) const
 {
   Halfspace s;
   Vec3f p, d;
@@ -2595,7 +2595,7 @@ bool GJKSolver_libccd::shapeIntersect<Halfspace, Halfspace>(const Halfspace& s1,
 template<>
 bool GJKSolver_libccd::shapeIntersect<Plane, Halfspace>(const Plane& s1, const Transform3f& tf1,
                                                         const Halfspace& s2, const Transform3f& tf2,
-                                                        Vec3f* contact_points, FCL_REAL* penetration_depth, Vec3f* normal) const
+                                                        Vec3f* /*contact_points*/, FCL_REAL* /*penetration_depth*/, Vec3f* /*normal*/) const
 {
   Plane pl;
   Vec3f p, d;
@@ -2607,7 +2607,7 @@ bool GJKSolver_libccd::shapeIntersect<Plane, Halfspace>(const Plane& s1, const T
 template<>
 bool GJKSolver_libccd::shapeIntersect<Halfspace, Plane>(const Halfspace& s1, const Transform3f& tf1,
                                                         const Plane& s2, const Transform3f& tf2,
-                                                        Vec3f* contact_points, FCL_REAL* penetration_depth, Vec3f* normal) const
+                                                        Vec3f* /*contact_points*/, FCL_REAL* /*penetration_depth*/, Vec3f* /*normal*/) const
 {
   Plane pl;
   Vec3f p, d;
@@ -2792,9 +2792,9 @@ bool GJKSolver_libccd::shapeDistance<Sphere, Sphere>(const Sphere& s1, const Tra
 }
 
 template<>
-bool GJKSolver_libccd::shapeDistance<Capsule, Capsule>(const Capsule& s1, const Transform3f& tf1,
-                                                       const Capsule& s2, const Transform3f& tf2,
-                                                       FCL_REAL* dist, Vec3f* p1, Vec3f* p2) const
+bool GJKSolver_libccd::shapeDistance<Capsule, Capsule>(const Capsule& /*s1*/, const Transform3f& /*tf1*/,
+                                                       const Capsule& /*s2*/, const Transform3f& /*tf2*/,
+                                                       FCL_REAL* /*dist*/, Vec3f* /*p1*/, Vec3f* /*p2*/) const
 {
   abort ();
 }
@@ -2967,7 +2967,7 @@ bool GJKSolver_indep::shapeIntersect<Halfspace, Cone>(const Halfspace& s1, const
 template<>
 bool GJKSolver_indep::shapeIntersect<Halfspace, Halfspace>(const Halfspace& s1, const Transform3f& tf1,
                                                            const Halfspace& s2, const Transform3f& tf2,
-                                                           Vec3f* contact_points, FCL_REAL* penetration_depth, Vec3f* normal) const
+                                                           Vec3f* /*contact_points*/, FCL_REAL* /*penetration_depth*/, Vec3f* /*normal*/) const
 {
   Halfspace s;
   Vec3f p, d;
@@ -2979,7 +2979,7 @@ bool GJKSolver_indep::shapeIntersect<Halfspace, Halfspace>(const Halfspace& s1,
 template<>
 bool GJKSolver_indep::shapeIntersect<Plane, Halfspace>(const Plane& s1, const Transform3f& tf1,
                                                        const Halfspace& s2, const Transform3f& tf2,
-                                                       Vec3f* contact_points, FCL_REAL* penetration_depth, Vec3f* normal) const
+                                                       Vec3f* /*contact_points*/, FCL_REAL* /*penetration_depth*/, Vec3f* /*normal*/) const
 {
   Plane pl;
   Vec3f p, d;
@@ -2991,7 +2991,7 @@ bool GJKSolver_indep::shapeIntersect<Plane, Halfspace>(const Plane& s1, const Tr
 template<>
 bool GJKSolver_indep::shapeIntersect<Halfspace, Plane>(const Halfspace& s1, const Transform3f& tf1,
                                                        const Plane& s2, const Transform3f& tf2,
-                                                       Vec3f* contact_points, FCL_REAL* penetration_depth, Vec3f* normal) const
+                                                       Vec3f* /*contact_points*/, FCL_REAL* /*penetration_depth*/, Vec3f* /*normal*/) const
 {
   Plane pl;
   Vec3f p, d;
@@ -3176,9 +3176,9 @@ bool GJKSolver_indep::shapeDistance<Sphere, Sphere>(const Sphere& s1, const Tran
 }
 
 template<>
-bool GJKSolver_indep::shapeDistance<Capsule, Capsule>(const Capsule& s1, const Transform3f& tf1,
-                                                      const Capsule& s2, const Transform3f& tf2,
-                                                      FCL_REAL* dist, Vec3f* p1, Vec3f* p2) const
+bool GJKSolver_indep::shapeDistance<Capsule, Capsule>(const Capsule& /*s1*/, const Transform3f& /*tf1*/,
+                                                      const Capsule& /*s2*/, const Transform3f& /*tf2*/,
+                                                      FCL_REAL* /*dist*/, Vec3f* /*p1*/, Vec3f* /*p2*/) const
 {
   abort ();
 }
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 5ee7213a634a5967e13b8e0046af3b9ee99856aa..ed1da73fe4671a66ef6a3c6b4261772d218b7f3f 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -1,5 +1,13 @@
 config_files(fcl_resources/config.h)
 
+macro(add_fcl_template_test test_name)
+  add_executable(${ARGV})
+  target_link_libraries(${test_name}
+    ${Boost_LIBRARIES}
+    )
+  add_test(${test_name} ${EXECUTABLE_OUTPUT_PATH}/${test_name})
+endmacro(add_fcl_template_test)
+
 macro(add_fcl_test test_name)
   add_executable(${ARGV})
   target_link_libraries(${test_name}
diff --git a/test/test_fcl_eigen.cpp b/test/test_fcl_eigen.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7db1958a888e2e2db5cc4ba5266d0e3739a8d641
--- /dev/null
+++ b/test/test_fcl_eigen.cpp
@@ -0,0 +1,120 @@
+/*
+ * Software License Agreement (BSD License)
+ *
+ *  Copyright (c) 2011-2014, Willow Garage, Inc.
+ *  Copyright (c) 2014-2015, Open Source Robotics Foundation
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of Open Source Robotics Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define BOOST_TEST_MODULE "FCL_EIGEN"
+#include <boost/test/included/unit_test.hpp>
+
+#include <hpp/fcl/config-fcl.hh>
+#include <hpp/fcl/eigen/vec_3fx.h>
+
+using namespace fcl;
+
+#define PRINT_VECTOR(a) std::cout << #a": " << a.base().transpose() << std::endl;
+#define PRINT_MATRIX(a) std::cout << #a": " << a << std::endl;
+
+BOOST_AUTO_TEST_CASE(fcl_eigen_vec3fx)
+{
+  typedef Eigen::FclMatrix <double, 1, 0> Vec3f;
+  Vec3f a (0, 1, 2);
+  Vec3f b (1, 2, 3);
+
+  std::cout << (Vec3f::Base&) a - (Vec3f::Base&) b << std::endl;
+  std::cout << a - b << std::endl;
+  Vec3f c = a - b;
+  std::cout << c << std::endl;
+  c.normalize ();
+
+  Vec3f l = (a - b).normalize ();
+
+  std::cout << l << std::endl;
+  std::cout << c << std::endl;
+
+  Vec3f d = -b;
+  std::cout << d << std::endl;
+
+  d += b;
+  std::cout << d << std::endl;
+
+  d += 1;
+  std::cout << d << std::endl;
+
+  d *= b;
+  std::cout << d << std::endl;
+
+  // std::cout << d * b << std::endl;
+  // std::cout << d / b << std::endl;
+  // std::cout << d + 3.4 << std::endl;
+  // std::cout << d - 3.4 << std::endl;
+  // std::cout << d * 2 << std::endl;
+  // std::cout << d / 3 << std::endl;
+  // std::cout << (d - 3.4).abs().sqrLength() << std::endl;
+
+  // std::cout << (((d - 3.4).abs() + 1) + 3).sqrLength() << std::endl;
+  PRINT_VECTOR(a)
+  PRINT_VECTOR(b)
+  PRINT_VECTOR(min(a,b))
+  PRINT_VECTOR(max(a,b))
+  a.lbound(b);
+  PRINT_VECTOR(a)
+  std::cout << (a+1).lbound(b) << std::endl;
+  std::cout << (a+1).ubound(b) << std::endl;
+
+  std::cout << a.getRow(1) << std::endl;
+}
+
+BOOST_AUTO_TEST_CASE(fcl_eigen_matrix3fx)
+{
+  typedef Eigen::FclMatrix <double, 3, 0> Matrix3fX;
+  Matrix3fX a (0, 1, 2, 3, 4, 5, 6, 7, 8);
+
+  PRINT_MATRIX(a);
+  a.transpose ();
+  PRINT_MATRIX(a);
+  a += a;
+  PRINT_MATRIX(a);
+  a *= a;
+  PRINT_MATRIX(a);
+
+  Matrix3fX b = a; b.inverse ();
+  a += a + a * b;
+  PRINT_MATRIX(a);
+
+  b = a; b.inverse ();
+  a.transpose ();
+  PRINT_MATRIX(a);
+  PRINT_MATRIX(a.transposeTimes (b));
+  PRINT_MATRIX(a.timesTranspose (b));
+  PRINT_MATRIX(a.tensorTransform (b));
+}
diff --git a/test/test_fcl_math.cpp b/test/test_fcl_math.cpp
index e35c21d09755461ecafcb9c3f09df7d67dc8b5a9..18ee66bb85251e3c17665ae62172d21294053f79 100644
--- a/test/test_fcl_math.cpp
+++ b/test/test_fcl_math.cpp
@@ -37,6 +37,9 @@
 #define BOOST_TEST_MODULE "FCL_MATH"
 #include <boost/test/included/unit_test.hpp>
 
+#if FCL_HAVE_EIGEN
+#include <hpp/fcl/eigen/math_details.h>
+#endif
 #if FCL_HAVE_SSE
 #include <hpp/fcl/simd/math_simd_details.h>
 #endif
@@ -163,6 +166,471 @@ BOOST_AUTO_TEST_CASE(vec_test_basic_vec64)
   BOOST_CHECK(v1.dot(v2) == 26);
 }
 
+#if FCL_HAVE_EIGEN
+
+BOOST_AUTO_TEST_CASE(vec_test_eigen_vec32)
+{
+  typedef Vec3fX<details::eigen_wrapper_v3 <float> > Vec3f32;
+  Vec3f32 v1(1.0f, 2.0f, 3.0f);
+  BOOST_CHECK(v1[0] == 1.0f);
+  BOOST_CHECK(v1[1] == 2.0f);
+  BOOST_CHECK(v1[2] == 3.0f);
+
+  Vec3f32 v2 = v1;
+  Vec3f32 v3(3.3f, 4.3f, 5.3f);
+  v1 += v3;
+  BOOST_CHECK(v1.equal(v2 + v3));
+  v1 -= v3;
+  BOOST_CHECK(v1.equal(v2));
+  v1 -= v3;
+  BOOST_CHECK(v1.equal(v2 - v3));
+  v1 += v3;
+
+  v1 *= v3;
+  BOOST_CHECK(v1.equal(v2 * v3));
+  v1 /= v3;
+  BOOST_CHECK(v1.equal(v2));
+  v1 /= v3;
+  BOOST_CHECK(v1.equal(v2 / v3));
+  v1 *= v3;
+
+  v1 *= 2.0f;
+  BOOST_CHECK(v1.equal(v2 * 2.0f));
+  v1 /= 2.0f;
+  BOOST_CHECK(v1.equal(v2));
+  v1 /= 2.0f;
+  BOOST_CHECK(v1.equal(v2 / 2.0f));
+  v1 *= 2.0f;
+
+  v1 += 2.0f;
+  BOOST_CHECK(v1.equal(v2 + 2.0f));
+  v1 -= 2.0f;
+  BOOST_CHECK(v1.equal(v2));
+  v1 -= 2.0f;
+  BOOST_CHECK(v1.equal(v2 - 2.0f));
+  v1 += 2.0f;
+  
+  BOOST_CHECK((-Vec3f32(1.0f, 2.0f, 3.0f)).equal(Vec3f32(-1.0f, -2.0f, -3.0f)));
+
+  v1 = Vec3f32(1.0f, 2.0f, 3.0f);
+  v2 = Vec3f32(3.0f, 4.0f, 5.0f);
+  BOOST_CHECK((v1.cross(v2)).equal(Vec3f32(-2.0f, 4.0f, -2.0f)));
+  BOOST_CHECK(std::abs(v1.dot(v2) - 26) < 1e-5);
+
+  v1 = Vec3f32(3.0f, 4.0f, 5.0f);
+  BOOST_CHECK(std::abs(v1.sqrLength() - 50) < 1e-5);
+  BOOST_CHECK(std::abs(v1.length() - sqrt(50)) < 1e-5);
+  BOOST_CHECK(normalize(v1).equal(v1 / v1.length()));
+}
+
+BOOST_AUTO_TEST_CASE(vec_test_eigen_vec64)
+{
+  typedef Vec3fX<details::eigen_wrapper_v3<double> > Vec3f64;
+  Vec3f64 v1(1.0, 2.0, 3.0);
+  BOOST_CHECK(v1[0] == 1.0);
+  BOOST_CHECK(v1[1] == 2.0);
+  BOOST_CHECK(v1[2] == 3.0);
+
+  Vec3f64 v2 = v1;
+  Vec3f64 v3(3.3, 4.3, 5.3);
+  v1 += v3;
+  BOOST_CHECK(v1.equal(v2 + v3));
+  v1 -= v3;
+  BOOST_CHECK(v1.equal(v2));
+  v1 -= v3;
+  BOOST_CHECK(v1.equal(v2 - v3));
+  v1 += v3;
+
+  v1 *= v3;
+  BOOST_CHECK(v1.equal(v2 * v3));
+  v1 /= v3;
+  BOOST_CHECK(v1.equal(v2));
+  v1 /= v3;
+  BOOST_CHECK(v1.equal(v2 / v3));
+  v1 *= v3;
+
+  v1 *= 2.0;
+  BOOST_CHECK(v1.equal(v2 * 2.0));
+  v1 /= 2.0;
+  BOOST_CHECK(v1.equal(v2));
+  v1 /= 2.0;
+  BOOST_CHECK(v1.equal(v2 / 2.0));
+  v1 *= 2.0;
+
+  v1 += 2.0;
+  BOOST_CHECK(v1.equal(v2 + 2.0));
+  v1 -= 2.0;
+  BOOST_CHECK(v1.equal(v2));
+  v1 -= 2.0;
+  BOOST_CHECK(v1.equal(v2 - 2.0));
+  v1 += 2.0;
+
+  BOOST_CHECK((-Vec3f64(1.0, 2.0, 3.0)).equal(Vec3f64(-1.0, -2.0, -3.0)));
+
+  v1 = Vec3f64(1.0, 2.0, 3.0);
+  v2 = Vec3f64(3.0, 4.0, 5.0);
+  BOOST_CHECK((v1.cross(v2)).equal(Vec3f64(-2.0, 4.0, -2.0)));
+  BOOST_CHECK(std::abs(v1.dot(v2) - 26) < 1e-5);
+
+  v1 = Vec3f64(3.0, 4.0, 5.0);
+  BOOST_CHECK(std::abs(v1.sqrLength() - 50) < 1e-5);
+  BOOST_CHECK(std::abs(v1.length() - sqrt(50)) < 1e-5);
+  BOOST_CHECK(normalize(v1).equal(v1 / v1.length()));
+
+
+  v1 = Vec3f64(1.0, 2.0, 3.0);
+  v2 = Vec3f64(3.0, 4.0, 5.0);
+  BOOST_CHECK((v1.cross(v2)).equal(Vec3f64(-2.0, 4.0, -2.0)));
+  BOOST_CHECK(v1.dot(v2) == 26);
+}
+
+BOOST_AUTO_TEST_CASE(eigen_mat32_consistent)
+{
+  typedef Vec3fX<details::Vec3Data<float> > Vec3f32;
+  typedef Vec3fX<details::eigen_wrapper_v3 <float> > Vec3f32Eigen;
+
+  typedef Matrix3fX<details::Matrix3Data<details::Vec3Data<float> > > Matrix3f32;
+  typedef Matrix3fX<details::eigen_wrapper_m3<details::eigen_wrapper_v3<float> > > Matrix3f32Eigen;
+
+  Vec3f32 v1(1, 2, 3);
+  Vec3f32Eigen v2(1, 2, 3);
+
+  Matrix3f32 m1(-1, 3, -3, 0, -6, 6, -5, -3, 1);
+  Matrix3f32Eigen m2(-1, 3, -3, 0, -6, 6, -5, -3, 1);
+
+  for(size_t i = 0; i < 3; ++i)
+    for(size_t j = 0; j < 3; ++j)
+      BOOST_CHECK((m1(i, j) - m2(i, j) < 1e-1));
+  
+  Matrix3f32 m3(transpose(m1));
+  Matrix3f32Eigen m4(transpose(m2));
+        
+  for(size_t i = 0; i < 3; ++i)
+    for(size_t j = 0; j < 3; ++j)
+      BOOST_CHECK((m3(i, j) - m4(i, j) < 1e-1));
+
+  m3 = m1; m3.transpose();
+  m4 = m2; m4.transpose();
+
+  for(size_t i = 0; i < 3; ++i)
+    for(size_t j = 0; j < 3; ++j)
+      BOOST_CHECK((m3(i, j) - m4(i, j) < 1e-1));
+
+  m3 = inverse(m1);
+  m4 = inverse(m2);
+  
+  for(size_t i = 0; i < 3; ++i)
+    for(size_t j = 0; j < 3; ++j)
+      BOOST_CHECK((m3(i, j) - m4(i, j) < 1e-1));
+
+  m3 = m1; m3.inverse();
+  m4 = m2; m4.inverse();
+
+  for(size_t i = 0; i < 3; ++i)
+    for(size_t j = 0; j < 3; ++j)
+      BOOST_CHECK((m3(i, j) - m4(i, j) < 1e-1));
+}
+
+BOOST_AUTO_TEST_CASE(vec_test_eigen_vec32_consistent)
+{
+  typedef Vec3fX<details::Vec3Data<float> > Vec3f32;
+  typedef Vec3fX<details::eigen_wrapper_v3<float> > Vec3f32Eigen;
+
+  Vec3f32 v1(3.4f, 4.2f, 10.5f), v2(3.1f, 0.1f, -50.4f);
+  Vec3f32Eigen v3(3.4f, 4.2f, 10.5f), v4(3.1f, 0.1f, -50.4f);
+  Vec3f32 v12 = v1 + v2;
+  Vec3f32Eigen v34 = v3 + v4;
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+  v12 = v1 - v2;
+  v34 = v3 - v4;
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+  v12 = v1 * v2;
+  v34 = v3 * v4;
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+  v12 = v1 / v2;
+  v34 = v3 / v4;
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+  float t = 1234.433f;
+  v12 = v1 + t;
+  v34 = v3 + t;
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+  v12 = v1 - t;
+  v34 = v3 - t;
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+  v12 = v1 * t;
+  v34 = v3 * t;
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+  v12 = v1 / t;
+  v34 = v3 / t;
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+
+  v12 = v1; v12 += v2;
+  v34 = v3; v34 += v4;
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+  v12 = v1; v12 -= v2;
+  v34 = v3; v34 -= v4;
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+  v12 = v1; v12 *= v2;
+  v34 = v3; v34 *= v4;
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+  v12 = v1; v12 /= v2;
+  v34 = v3; v34 /= v4;
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+  v12 = v1; v12 += t;
+  v34 = v3; v34 += t;
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+  v12 = v1; v12 -= t;
+  v34 = v3; v34 -= t;
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+  v12 = v1; v12 *= t;
+  v34 = v3; v34 *= t;
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+  v12 = v1; v12 /= t;
+  v34 = v3; v34 /= t;
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+
+  v12 = -v1;
+  v34 = -v3;
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+
+  v12 = v1.cross(v2);
+  v34 = v3.cross(v4);
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+
+  // Difference if about 6e-5
+  BOOST_CHECK(std::abs(v1.dot(v2) - v3.dot(v4)) < 1e-4);
+
+  v12 = min(v1, v2);
+  v34 = min(v3, v4);
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+  v12 = max(v1, v2);
+  v34 = max(v3, v4);
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+
+  v12 = abs(v2);
+  v34 = abs(v4);
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+
+  Vec3f32 delta1(1e-9f, 1e-9f, 1e-9f);
+  Vec3f32Eigen delta2(1e-9f, 1e-9f, 1e-9f);
+  BOOST_CHECK((v1 + delta1).equal(v1));
+  BOOST_CHECK((v3 + delta2).equal(v3));
+
+  BOOST_CHECK(std::abs(v1.length() - v3.length()) < 1e-5);
+  BOOST_CHECK(std::abs(v1.sqrLength() - v3.sqrLength()) < 1e-5);
+ 
+  v12 = v1; v12.negate();
+  v34 = v3; v34.negate();
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+
+  v12 = v1; v12.normalize();
+  v34 = v3; v34.normalize();
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+  
+  v12 = normalize(v1);
+  v34 = normalize(v3);
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);  
+}
+
+BOOST_AUTO_TEST_CASE(vec_test_eigen_vec64_consistent)
+{
+  typedef Vec3fX<details::Vec3Data<double> > Vec3f64;
+  typedef Vec3fX<details::eigen_wrapper_v3<double> > Vec3f64Eigen;
+
+  Vec3f64 v1(3.4, 4.2, 10.5), v2(3.1, 0.1, -50.4);
+  Vec3f64Eigen v3(3.4, 4.2, 10.5), v4(3.1, 0.1, -50.4);
+  Vec3f64 v12 = v1 + v2;
+  Vec3f64Eigen v34 = v3 + v4;
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+  v12 = v1 - v2;
+  v34 = v3 - v4;
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+  v12 = v1 * v2;
+  v34 = v3 * v4;
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+  v12 = v1 / v2;
+  v34 = v3 / v4;
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+  double t = 1234.433;
+  v12 = v1 + t;
+  v34 = v3 + t;
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+  v12 = v1 - t;
+  v34 = v3 - t;
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+  v12 = v1 * t;
+  v34 = v3 * t;
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+  v12 = v1 / t;
+  v34 = v3 / t;
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+
+  v12 = v1; v12 += v2;
+  v34 = v3; v34 += v4;
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+  v12 = v1; v12 -= v2;
+  v34 = v3; v34 -= v4;
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+  v12 = v1; v12 *= v2;
+  v34 = v3; v34 *= v4;
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+  v12 = v1; v12 /= v2;
+  v34 = v3; v34 /= v4;
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+  v12 = v1; v12 += t;
+  v34 = v3; v34 += t;
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+  v12 = v1; v12 -= t;
+  v34 = v3; v34 -= t;
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+  v12 = v1; v12 *= t;
+  v34 = v3; v34 *= t;
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+  v12 = v1; v12 /= t;
+  v34 = v3; v34 /= t;
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+
+  v12 = -v1;
+  v34 = -v3;
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+
+  v12 = v1.cross(v2);
+  v34 = v3.cross(v4);
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+
+  BOOST_CHECK(std::abs(v1.dot(v2) - v3.dot(v4)) < 1e-5);
+
+  v12 = min(v1, v2);
+  v34 = min(v3, v4);
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+  v12 = max(v1, v2);
+  v34 = max(v3, v4);
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+
+  v12 = abs(v2);
+  v34 = abs(v4);
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+
+  Vec3f64 delta1(1e-15, 1e-15, 1e-15);
+  Vec3f64Eigen delta2(1e-15, 1e-15, 1e-15);
+  BOOST_CHECK((v1 + delta1).equal(v1));
+  BOOST_CHECK((v3 + delta2).equal(v3));
+
+  BOOST_CHECK(std::abs(v1.length() - v3.length()) < 1e-5);
+  BOOST_CHECK(std::abs(v1.sqrLength() - v3.sqrLength()) < 1e-5);
+ 
+  v12 = v1; v12.negate();
+  v34 = v3; v34.negate();
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+
+  v12 = v1; v12.normalize();
+  v34 = v3; v34.normalize();
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);
+  
+  v12 = normalize(v1);
+  v34 = normalize(v3);
+  BOOST_CHECK(std::abs(v12[0] - v34[0]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[1] - v34[1]) < 1e-5);
+  BOOST_CHECK(std::abs(v12[2] - v34[2]) < 1e-5);  
+}
+
+#endif
+
+
 #if FCL_HAVE_SSE
 
 BOOST_AUTO_TEST_CASE(vec_test_sse_vec32)