diff --git a/CMakeLists.txt b/CMakeLists.txt
index 80adcfdf123ee6db15f378ab6dff8979a0504f87..38bb394cb4ed2dfe60f7a2864f67b005333cbb18 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -48,6 +48,7 @@ setup_project()
 
 set(FCL_HAVE_SSE FALSE CACHE BOOL "Enable SSE vectorization")
 set(FCL_HAVE_EIGEN FALSE CACHE BOOL "Use eigen wrappers")
+set(FCL_USE_NATIVE_EIGEN FALSE CACHE BOOL "Use native eigen matrix type when possible")
 
 add_optional_dependency("eigen3 >= 3.0.0")
 if (EIGEN3_FOUND)
diff --git a/include/hpp/fcl/config-fcl.hh.in b/include/hpp/fcl/config-fcl.hh.in
index fa302b1b802558eb6c5a2676397b43d404444024..0b1506c71d9d091626037585156e5ab61da6decd 100644
--- a/include/hpp/fcl/config-fcl.hh.in
+++ b/include/hpp/fcl/config-fcl.hh.in
@@ -38,6 +38,8 @@
 # include "config.h"
 
 #cmakedefine01 FCL_HAVE_EIGEN
+#cmakedefine01 FCL_USE_NATIVE_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
index 3867583ddf733d01db6103caae9a868d216a8395..207e797d4e5045e814405fd9ae6755bb04ed029f 100644
--- a/include/hpp/fcl/eigen/math_details.h
+++ b/include/hpp/fcl/eigen/math_details.h
@@ -33,6 +33,8 @@
  *  POSSIBILITY OF SUCH DAMAGE.
  */
 
+/** \author Joseph Mirabel */
+
 #ifndef FCL_EIGEN_DETAILS_H
 #define FCL_EIGEN_DETAILS_H
 
diff --git a/include/hpp/fcl/eigen/matrix_3fx.h b/include/hpp/fcl/eigen/matrix_3fx.h
new file mode 100644
index 0000000000000000000000000000000000000000..8e9356ce94043b8f9ed709ff4ebbbc8998add19e
--- /dev/null
+++ b/include/hpp/fcl/eigen/matrix_3fx.h
@@ -0,0 +1,469 @@
+/*
+ * 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_EIGEN_MATRIX_3F_H
+#define FCL_EIGEN_MATRIX_3F_H
+
+namespace fcl
+{
+
+/// @brief Matrix2 class wrapper. the core data is in the template parameter class
+template<typename T>
+class Matrix3fX
+  : Eigen::Matrix <T, 3, 1>
+{
+public:
+  // typedef typename T::vector_type S;
+  
+  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/eigen/vec_3fx.h b/include/hpp/fcl/eigen/vec_3fx.h
new file mode 100644
index 0000000000000000000000000000000000000000..da68282678a4cc779b9eacdeee353f2a3aeedfda
--- /dev/null
+++ b/include/hpp/fcl/eigen/vec_3fx.h
@@ -0,0 +1,268 @@
+/*
+ * 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 <hpp/fcl/eigen/math_details.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 :
+  Eigen::Matrix <T, 3, 1>
+{
+public:
+  typedef Eigen::Matrix <T, 3, 1> Base;
+
+  Vec3fX(void): Base() {}
+
+  // This constructor allows you to construct MyVectorType from Eigen expressions
+  template<typename OtherDerived>
+    Vec3fX(const Eigen::MatrixBase<OtherDerived>& other)
+    : Base(other)
+    {}
+
+  // This method allows you to assign Eigen expressions to MyVectorType
+  template<typename OtherDerived>
+    Vec3fX& operator=(const Eigen::MatrixBase <OtherDerived>& other)
+    {
+      this->Base::operator=(other);
+      return *this;
+    }
+
+  /// @brief create Vector (x, y, z)
+  Vec3fX(T x, T y, T z) : Base(x, y, z) {}
+
+  /// @brief create vector (x, x, x)
+  Vec3fX(U 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]; }
+
+  // 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()
+  {
+    T sqr_length = this->squaredNorm();
+    if(sqr_length > 0) this->operator/= ((T)sqrt(sqr_length));
+    return *this;
+  }
+
+  inline Vec3fX& normalize(bool* signal)
+  {
+    T sqr_length = this->squaredNorm();
+    if(sqr_length > 0)
+    {
+      this->operator/= ((T)sqrt(sqr_length));
+      *signal = true;
+    }
+    else
+      *signal = false;
+    return *this;
+  }
+
+  inline Vec3fX& 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) { m_storage.data() = { x, y, z } }
+  inline void setValue(T x) { this->setConstant (x); }
+  // inline void setZero () {data.setValue (0); }
+  inline bool equal(const Vec3fX& other, T epsilon = std::numeric_limits<U>::epsilon() * 100) const
+  {
+    return ((*this - other).cwiseAbs().array () < epsilon).all();
+  }
+  inline Vec3fX<T>& negate() { *this = -*this; 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)
+  {
+    *this = this->cwiseMin (u);
+    return *this;
+  }
+
+  inline Vec3fX<T>& lbound(const Vec3fX<T>& l)
+  {
+    *this = this->cwiseMax (l);
+    return *this;
+  }
+
+  bool isZero() const
+  {
+    return (m_storage.data()[0] == 0)
+      &&   (m_storage.data()[1] == 0)
+      &&   (m_storage.data()[2] == 0);
+  }
+
+};
+
+template<typename T>
+static inline Vec3fX<T> normalize(const Vec3fX<T>& v)
+{
+  typename T::meta_type sqr_length = v.squaredNorm ();
+  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)
+static inline
+const Eigen::CwiseBinaryOp <Eigen::internal::scalar_min_op<T>, const Vec3fX<T>, const Vec3fX<T> >
+ min(const Vec3fX<T>& x, const Vec3fX<T>& y)
+{
+  return x.cwiseMin (y);
+}
+
+template <typename T>
+// static inline Vec3fX<T> max(const Vec3fX<T>& x, const Vec3fX<T>& y)
+static inline
+const Eigen::CwiseBinaryOp<Eigen::internal::scalar_max_op<T>, const Vec3fX<T>, const Vec3fX<T> >
+max(const Vec3fX<T>& x, const Vec3fX<T>& y)
+{
+  return x.cwiseMax (y);
+}
+
+template <typename T>
+// static inline Vec3fX<T> abs(const Vec3fX<T>& x)
+static inline
+const Eigen::CwiseUnaryOp<Eigen::internal::scalar_abs_op<T>, const Vec3fX<T> >
+abs(const Vec3fX<T>& x)
+{
+  return x.cwiseAbs ();
+}
+
+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/math/matrix_3f.h b/include/hpp/fcl/math/matrix_3f.h
index 6a679bc09b4dfc18420982ea999ef9da58ebc6b9..03f562cab45652e3c56226e7c9d27a573650b930 100644
--- a/include/hpp/fcl/math/matrix_3f.h
+++ b/include/hpp/fcl/math/matrix_3f.h
@@ -40,434 +40,21 @@
 
 #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_USE_NATIVE_EIGEN
+# include <hpp/fcl/eigen/matrix_3fx.h>
+#else
+# 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_EIGEN
-typedef Matrix3fX<details::eigen_m3<FCL_REAL> > Matrix3f;
+# if FCL_USE_NATIVE_EIGEN
+  typedef Matrix3fX<FCL_REAL> Matrix3f;
+# else
+  typedef Matrix3fX<details::eigen_m3<FCL_REAL> > Matrix3f;
+# endif
 #elif FCL_HAVE_SSE
 typedef Matrix3fX<details::sse_meta_f12> Matrix3f;
 #else
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 5a6f481acf48b935801d10c1b56bbe501a41c7b8..f7db1ba3ff9c7aea873fab9e1cf554f0f4ddc5e5 100644
--- a/include/hpp/fcl/math/vec_3f.h
+++ b/include/hpp/fcl/math/vec_3f.h
@@ -40,12 +40,21 @@
 
 #include <hpp/fcl/config-fcl.hh>
 #include <hpp/fcl/data_types.h>
-#include <hpp/fcl/math/math_details.h>
+
+#if FCL_USE_NATIVE_EIGEN
+# include <hpp/fcl/eigen/vec_3fx.h>
+#else
+# include <hpp/fcl/math/vec_3fx.h>
+#endif
 
 #if FCL_HAVE_EIGEN
-#include <hpp/fcl/eigen/math_details.h>
+# if ! FCL_USE_NATIVE_EIGEN
+#  include <hpp/fcl/eigen/math_details.h>
+# endif
 #elif FCL_HAVE_SSE
-#include <hpp/fcl/simd/math_simd_details.h>
+# include <hpp/fcl/simd/math_simd_details.h>
+#else
+# include <hpp/fcl/math/math_details.h>
 #endif
 
 #include <cmath>
@@ -56,187 +65,12 @@
 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_EIGEN
+# if FCL_USE_NATIVE_EIGEN
+  typedef Vec3fX<FCL_REAL> Vec3f;
+# else
   typedef Vec3fX<details::eigen_v3<FCL_REAL> > Vec3f;
+# endif
 #elif FCL_HAVE_SSE
   typedef Vec3fX<details::sse_meta_f4> Vec3f;
 #else
@@ -249,14 +83,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..bfa228b0eef85a9358ff60600a145b105c48445c
--- /dev/null
+++ b/include/hpp/fcl/math/vec_3fx.h
@@ -0,0 +1,243 @@
+/*
+ * 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 <hpp/fcl/math/math_details.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