diff --git a/vcg/math/eigen.h b/vcg/math/eigen.h index d2eb1235..56e73e12 100644 --- a/vcg/math/eigen.h +++ b/vcg/math/eigen.h @@ -42,11 +42,11 @@ template + int Rows = ei_traits::RowsAtCompileTime, + int Cols = ei_traits::ColsAtCompileTime, + int StorageOrder = ei_traits::Flags&1, + int MRows = ei_traits::MaxRowsAtCompileTime, + int MCols = ei_traits::MaxColsAtCompileTime> struct ei_to_vcgtype; } diff --git a/vcg/math/matrix44.h b/vcg/math/matrix44.h index e186aa48..f202b4e4 100644 --- a/vcg/math/matrix44.h +++ b/vcg/math/matrix44.h @@ -81,6 +81,13 @@ for 'column' vectors. */ +// Note that we have to pass Dim and HDim because it is not allowed to use a template +// parameter to define a template specialization. To be more precise, in the following +// specializations, it is not allowed to use Dim+1 instead of HDim. +template< typename Other, + int OtherRows=Eigen::ei_traits::RowsAtCompileTime, + int OtherCols=Eigen::ei_traits::ColsAtCompileTime> +struct ei_matrix44_product_impl; /** \deprecated use Eigen::Matrix (or the typedef) you want a real 4x4 matrix, or use Eigen::Transform if you want a transformation matrix for a 3D space (a Eigen::Transform is internally a 4x4 col-major matrix) * @@ -101,7 +108,6 @@ public: _EIGEN_GENERIC_PUBLIC_INTERFACE(Matrix44,_Base); typedef _Scalar ScalarType; - VCG_EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Matrix44) Matrix44() : Base() {} @@ -142,6 +148,24 @@ public: Matrix44 &SetRotateDeg(Scalar AngleDeg, const Point3 & axis); Matrix44 &SetRotateRad(Scalar AngleRad, const Point3 & axis); + /** taken from Eigen::Transform + * \returns the product between the transform \c *this and a matrix expression \a other + * + * The right hand side \a other might be either: + * \li a matrix expression with 4 rows + * \li a 3D vector/point + */ + // note: this function is defined here because some compilers cannot find the respective declaration + template + inline const typename ei_matrix44_product_impl::ResultType + operator * (const MatrixBase &other) const + { return ei_matrix44_product_impl::run(*this,other.derived()); } + + /** Contatenates two transformations */ + inline const typename Eigen::ProductReturnType::Type + operator * (const Matrix44& other) const + { return (*this) * other; } + // template Point3 operator*(const Point3 &p) { // T w; // Point3 s; @@ -153,16 +177,16 @@ public: // return s; // } - Eigen::Matrix operator * (const Eigen::Matrix& p) const { - Scalar w; - Eigen::Matrix s; - s[0] = ElementAt(0, 0)*p[0] + ElementAt(0, 1)*p[1] + ElementAt(0, 2)*p[2] + ElementAt(0, 3); - s[1] = ElementAt(1, 0)*p[0] + ElementAt(1, 1)*p[1] + ElementAt(1, 2)*p[2] + ElementAt(1, 3); - s[2] = ElementAt(2, 0)*p[0] + ElementAt(2, 1)*p[1] + ElementAt(2, 2)*p[2] + ElementAt(2, 3); - w = ElementAt(3, 0)*p[0] + ElementAt(3, 1)*p[1] + ElementAt(3, 2)*p[2] + ElementAt(3, 3); - if(w!= 0) s /= w; - return s; - } + //Eigen::Matrix operator * (const Eigen::Matrix& p) const { + // Scalar w; + // Eigen::Matrix s; + // s[0] = ElementAt(0, 0)*p[0] + ElementAt(0, 1)*p[1] + ElementAt(0, 2)*p[2] + ElementAt(0, 3); + // s[1] = ElementAt(1, 0)*p[0] + ElementAt(1, 1)*p[1] + ElementAt(1, 2)*p[2] + ElementAt(1, 3); + // s[2] = ElementAt(2, 0)*p[0] + ElementAt(2, 1)*p[1] + ElementAt(2, 2)*p[2] + ElementAt(2, 3); + // w = ElementAt(3, 0)*p[0] + ElementAt(3, 1)*p[1] + ElementAt(3, 2)*p[2] + ElementAt(3, 3); + // if(w!= 0) s /= w; + // return s; + //} void print() {std::cout << *this << "\n\n";} @@ -465,6 +489,32 @@ template Matrix44 Inverse(const Matrix44 &m) { return m.lu().inverse(); } +template +struct ei_matrix44_product_impl +{ + typedef typename Other::Scalar Scalar; + typedef typename Eigen::ProductReturnType,Other>::Type ResultType; + static ResultType run(const Matrix44& tr, const Other& other) + { return tr * other; } +}; + +template +struct ei_matrix44_product_impl +{ + typedef typename Other::Scalar Scalar; + typedef Eigen::Matrix ResultType; + static ResultType run(const Matrix44& tr, const Other& p) + { + Scalar w; + Eigen::Matrix s; + s[0] = tr.ElementAt(0, 0)*p[0] + tr.ElementAt(0, 1)*p[1] + tr.ElementAt(0, 2)*p[2] + tr.ElementAt(0, 3); + s[1] = tr.ElementAt(1, 0)*p[0] + tr.ElementAt(1, 1)*p[1] + tr.ElementAt(1, 2)*p[2] + tr.ElementAt(1, 3); + s[2] = tr.ElementAt(2, 0)*p[0] + tr.ElementAt(2, 1)*p[1] + tr.ElementAt(2, 2)*p[2] + tr.ElementAt(2, 3); + w = tr.ElementAt(3, 0)*p[0] + tr.ElementAt(3, 1)*p[1] + tr.ElementAt(3, 2)*p[2] + tr.ElementAt(3, 3); + if(w!= 0) s /= w; + return s; + } +}; } //namespace #endif