Add an Options template paramter to Transform to enable/disable alignment

This commit is contained in:
Gael Guennebaud 2011-01-27 16:07:33 +01:00
parent e3306953ef
commit a954a0fbd5
8 changed files with 234 additions and 159 deletions

View File

@ -246,7 +246,7 @@ template<typename Scalar,int Dim> class Scaling;
#endif #endif
#if EIGEN2_SUPPORT_STAGE > STAGE20_RESOLVE_API_CONFLICTS #if EIGEN2_SUPPORT_STAGE > STAGE20_RESOLVE_API_CONFLICTS
template<typename Scalar,int Dim,int Mode> class Transform; template<typename Scalar,int Dim,int Mode,int _Options=AutoAlign> class Transform;
template <typename _Scalar, int _AmbientDim> class ParametrizedLine; template <typename _Scalar, int _AmbientDim> class ParametrizedLine;
template <typename _Scalar, int _AmbientDim> class Hyperplane; template <typename _Scalar, int _AmbientDim> class Hyperplane;
template<typename Scalar> class UniformScaling; template<typename Scalar> class UniformScaling;

View File

@ -112,12 +112,12 @@ template<typename MatrixType,int _Direction> class Homogeneous
return internal::homogeneous_left_product_impl<Homogeneous,Lhs>(lhs.derived(),rhs.m_matrix); return internal::homogeneous_left_product_impl<Homogeneous,Lhs>(lhs.derived(),rhs.m_matrix);
} }
template<typename Scalar, int Dim, int Mode> friend template<typename Scalar, int Dim, int Mode, int Options> friend
inline const internal::homogeneous_left_product_impl<Homogeneous,Transform<Scalar,Dim,Mode> > inline const internal::homogeneous_left_product_impl<Homogeneous,Transform<Scalar,Dim,Mode,Options> >
operator* (const Transform<Scalar,Dim,Mode>& lhs, const Homogeneous& rhs) operator* (const Transform<Scalar,Dim,Mode,Options>& lhs, const Homogeneous& rhs)
{ {
eigen_assert(int(Direction)==Vertical); eigen_assert(int(Direction)==Vertical);
return internal::homogeneous_left_product_impl<Homogeneous,Transform<Scalar,Dim,Mode> >(lhs,rhs.m_matrix); return internal::homogeneous_left_product_impl<Homogeneous,Transform<Scalar,Dim,Mode,Options> >(lhs,rhs.m_matrix);
} }
protected: protected:
@ -212,18 +212,18 @@ struct take_matrix_for_product
static const type& run(const type &x) { return x; } static const type& run(const type &x) { return x; }
}; };
template<typename Scalar, int Dim, int Mode> template<typename Scalar, int Dim, int Mode,int Options>
struct take_matrix_for_product<Transform<Scalar, Dim, Mode> > struct take_matrix_for_product<Transform<Scalar, Dim, Mode, Options> >
{ {
typedef Transform<Scalar, Dim, Mode> TransformType; typedef Transform<Scalar, Dim, Mode, Options> TransformType;
typedef typename TransformType::ConstAffinePart type; typedef typename TransformType::ConstAffinePart type;
static const type run (const TransformType& x) { return x.affine(); } static const type run (const TransformType& x) { return x.affine(); }
}; };
template<typename Scalar, int Dim> template<typename Scalar, int Dim, int Options>
struct take_matrix_for_product<Transform<Scalar, Dim, Projective> > struct take_matrix_for_product<Transform<Scalar, Dim, Projective, Options> >
{ {
typedef Transform<Scalar, Dim, Projective> TransformType; typedef Transform<Scalar, Dim, Projective, Options> TransformType;
typedef typename TransformType::MatrixType type; typedef typename TransformType::MatrixType type;
static const type& run (const TransformType& x) { return x.matrix(); } static const type& run (const TransformType& x) { return x.matrix(); }
}; };

View File

@ -229,7 +229,8 @@ public:
* or a more generic Affine transformation. The default is Affine. * or a more generic Affine transformation. The default is Affine.
* Other kind of transformations are not supported. * Other kind of transformations are not supported.
*/ */
inline Hyperplane& transform(const Transform<Scalar,AmbientDimAtCompileTime,Affine>& t, template<int TrOptions>
inline Hyperplane& transform(const Transform<Scalar,AmbientDimAtCompileTime,Affine,TrOptions>& t,
TransformTraits traits = Affine) TransformTraits traits = Affine)
{ {
transform(t.linear(), traits); transform(t.linear(), traits);

View File

@ -98,8 +98,8 @@ class RotationBase
} }
/** \returns the concatenation of the rotation \c *this with a transformation \a t */ /** \returns the concatenation of the rotation \c *this with a transformation \a t */
template<int Mode> template<int Mode, int Options>
inline Transform<Scalar,Dim,Mode> operator*(const Transform<Scalar,Dim,Mode>& t) const inline Transform<Scalar,Dim,Mode> operator*(const Transform<Scalar,Dim,Mode,Options>& t) const
{ return toRotationMatrix() * t; } { return toRotationMatrix() * t; }
template<typename OtherVectorType> template<typename OtherVectorType>

View File

@ -72,8 +72,8 @@ public:
inline Transform<Scalar,Dim,Affine> operator* (const Translation<Scalar,Dim>& t) const; inline Transform<Scalar,Dim,Affine> operator* (const Translation<Scalar,Dim>& t) const;
/** Concatenates a uniform scaling and an affine transformation */ /** Concatenates a uniform scaling and an affine transformation */
template<int Dim, int Mode> template<int Dim, int Mode, int Options>
inline Transform<Scalar,Dim,Mode> operator* (const Transform<Scalar,Dim, Mode>& t) const; inline Transform<Scalar,Dim,Mode> operator* (const Transform<Scalar,Dim, Mode, Options>& t) const;
/** Concatenates a uniform scaling and a linear transformation matrix */ /** Concatenates a uniform scaling and a linear transformation matrix */
// TODO returns an expression // TODO returns an expression
@ -170,9 +170,9 @@ UniformScaling<Scalar>::operator* (const Translation<Scalar,Dim>& t) const
} }
template<typename Scalar> template<typename Scalar>
template<int Dim,int Mode> template<int Dim,int Mode,int Options>
inline Transform<Scalar,Dim,Mode> inline Transform<Scalar,Dim,Mode>
UniformScaling<Scalar>::operator* (const Transform<Scalar,Dim, Mode>& t) const UniformScaling<Scalar>::operator* (const Transform<Scalar,Dim, Mode, Options>& t) const
{ {
Transform<Scalar,Dim,Mode> res = t; Transform<Scalar,Dim,Mode> res = t;
res.prescale(factor()); res.prescale(factor());

View File

@ -48,6 +48,7 @@ struct transform_right_product_impl;
template< typename Other, template< typename Other,
int Mode, int Mode,
int Options,
int Dim, int Dim,
int HDim, int HDim,
int OtherRows=Other::RowsAtCompileTime, int OtherRows=Other::RowsAtCompileTime,
@ -63,6 +64,7 @@ struct transform_transform_product_impl;
template< typename Other, template< typename Other,
int Mode, int Mode,
int Options,
int Dim, int Dim,
int HDim, int HDim,
int OtherRows=Other::RowsAtCompileTime, int OtherRows=Other::RowsAtCompileTime,
@ -88,6 +90,7 @@ template<typename TransformType> struct transform_take_affine_part;
* - AffineCompact: the transformation is stored as a (Dim)x(Dim+1) matrix. * - AffineCompact: the transformation is stored as a (Dim)x(Dim+1) matrix.
* - Projective: the transformation is stored as a (Dim+1)^2 matrix * - Projective: the transformation is stored as a (Dim+1)^2 matrix
* without any assumption. * without any assumption.
* \param _Options can be \b AutoAlign or \b DontAlign. Default is \b AutoAlign
* *
* The homography is internally represented and stored by a matrix which * The homography is internally represented and stored by a matrix which
* is available through the matrix() method. To understand the behavior of * is available through the matrix() method. To understand the behavior of
@ -177,13 +180,14 @@ template<typename TransformType> struct transform_take_affine_part;
* *
* \sa class Matrix, class Quaternion * \sa class Matrix, class Quaternion
*/ */
template<typename _Scalar, int _Dim, int _Mode> template<typename _Scalar, int _Dim, int _Mode, int _Options>
class Transform class Transform
{ {
public: public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_Dim==Dynamic ? Dynamic : (_Dim+1)*(_Dim+1)) EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_Dim==Dynamic ? Dynamic : (_Dim+1)*(_Dim+1))
enum { enum {
Mode = _Mode, Mode = _Mode,
Options = _Options,
Dim = _Dim, ///< space dimension in which the transformation holds Dim = _Dim, ///< space dimension in which the transformation holds
HDim = _Dim+1, ///< size of a respective homogeneous vector HDim = _Dim+1, ///< size of a respective homogeneous vector
Rows = int(Mode)==(AffineCompact) ? Dim : HDim Rows = int(Mode)==(AffineCompact) ? Dim : HDim
@ -192,7 +196,7 @@ public:
typedef _Scalar Scalar; typedef _Scalar Scalar;
typedef DenseIndex Index; typedef DenseIndex Index;
/** type of the matrix used to represent the transformation */ /** type of the matrix used to represent the transformation */
typedef Matrix<Scalar,Rows,HDim> MatrixType; typedef Matrix<Scalar,Rows,HDim,Options&DontAlign> MatrixType;
/** constified MatrixType */ /** constified MatrixType */
typedef const MatrixType ConstMatrixType; typedef const MatrixType ConstMatrixType;
/** type of the matrix used to represent the linear part of the transformation */ /** type of the matrix used to represent the linear part of the transformation */
@ -233,19 +237,33 @@ public:
* If Mode==Affine, then the last row is set to [0 ... 0 1] */ * If Mode==Affine, then the last row is set to [0 ... 0 1] */
inline Transform() inline Transform()
{ {
check_template_params();
if (int(Mode)==Affine) if (int(Mode)==Affine)
makeAffine(); makeAffine();
} }
inline Transform(const Transform& other) inline Transform(const Transform& other)
{ {
check_template_params();
m_matrix = other.m_matrix; m_matrix = other.m_matrix;
} }
inline explicit Transform(const TranslationType& t) { *this = t; } inline explicit Transform(const TranslationType& t)
inline explicit Transform(const UniformScaling<Scalar>& s) { *this = s; } {
check_template_params();
*this = t;
}
inline explicit Transform(const UniformScaling<Scalar>& s)
{
check_template_params();
*this = s;
}
template<typename Derived> template<typename Derived>
inline explicit Transform(const RotationBase<Derived, Dim>& r) { *this = r; } inline explicit Transform(const RotationBase<Derived, Dim>& r)
{
check_template_params();
*this = r;
}
inline Transform& operator=(const Transform& other) inline Transform& operator=(const Transform& other)
{ m_matrix = other.m_matrix; return *this; } { m_matrix = other.m_matrix; return *this; }
@ -256,20 +274,30 @@ public:
template<typename OtherDerived> template<typename OtherDerived>
inline explicit Transform(const EigenBase<OtherDerived>& other) inline explicit Transform(const EigenBase<OtherDerived>& other)
{ {
internal::transform_construct_from_matrix<OtherDerived,Mode,Dim,HDim>::run(this, other.derived()); check_template_params();
internal::transform_construct_from_matrix<OtherDerived,Mode,Options,Dim,HDim>::run(this, other.derived());
} }
/** Set \c *this from a Dim^2 or (Dim+1)^2 matrix. */ /** Set \c *this from a Dim^2 or (Dim+1)^2 matrix. */
template<typename OtherDerived> template<typename OtherDerived>
inline Transform& operator=(const EigenBase<OtherDerived>& other) inline Transform& operator=(const EigenBase<OtherDerived>& other)
{ {
internal::transform_construct_from_matrix<OtherDerived,Mode,Dim,HDim>::run(this, other.derived()); internal::transform_construct_from_matrix<OtherDerived,Mode,Options,Dim,HDim>::run(this, other.derived());
return *this; return *this;
} }
template<int OtherMode> template<int OtherOptions>
inline Transform(const Transform<Scalar,Dim,OtherMode>& other) inline Transform(const Transform<Scalar,Dim,Mode,OtherOptions>& other)
{ {
check_template_params();
// only the options change, we can directly copy the matrices
m_matrix = other.matrix();
}
template<int OtherMode,int OtherOptions>
inline Transform(const Transform<Scalar,Dim,OtherMode,OtherOptions>& other)
{
check_template_params();
// prevent conversions as: // prevent conversions as:
// Affine | AffineCompact | Isometry = Projective // Affine | AffineCompact | Isometry = Projective
EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(OtherMode==int(Projective), Mode==int(Projective)), EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(OtherMode==int(Projective), Mode==int(Projective)),
@ -294,8 +322,8 @@ public:
} }
else if(OtherModeIsAffineCompact) else if(OtherModeIsAffineCompact)
{ {
typedef typename Transform<Scalar,Dim,OtherMode>::MatrixType OtherMatrixType; typedef typename Transform<Scalar,Dim,OtherMode,OtherOptions>::MatrixType OtherMatrixType;
internal::transform_construct_from_matrix<OtherMatrixType,Mode,Dim,HDim>::run(this, other.matrix()); internal::transform_construct_from_matrix<OtherMatrixType,Mode,Options,Dim,HDim>::run(this, other.matrix());
} }
else else
{ {
@ -310,6 +338,7 @@ public:
template<typename OtherDerived> template<typename OtherDerived>
Transform(const ReturnByValue<OtherDerived>& other) Transform(const ReturnByValue<OtherDerived>& other)
{ {
check_template_params();
other.evalTo(*this); other.evalTo(*this);
} }
@ -381,9 +410,9 @@ public:
* \li a general transformation matrix of size Dim+1 x Dim+1. * \li a general transformation matrix of size Dim+1 x Dim+1.
*/ */
template<typename OtherDerived> friend template<typename OtherDerived> friend
inline const typename internal::transform_left_product_impl<OtherDerived,Mode,_Dim,_Dim+1>::ResultType inline const typename internal::transform_left_product_impl<OtherDerived,Mode,Options,_Dim,_Dim+1>::ResultType
operator * (const EigenBase<OtherDerived> &a, const Transform &b) operator * (const EigenBase<OtherDerived> &a, const Transform &b)
{ return internal::transform_left_product_impl<OtherDerived,Mode,Dim,HDim>::run(a.derived(),b); } { return internal::transform_left_product_impl<OtherDerived,Mode,Options,Dim,HDim>::run(a.derived(),b); }
/** \returns The product expression of a transform \a a times a diagonal matrix \a b /** \returns The product expression of a transform \a a times a diagonal matrix \a b
* *
@ -428,12 +457,12 @@ public:
} }
/** Concatenates two different transformations */ /** Concatenates two different transformations */
template<int OtherMode> template<int OtherMode,int OtherOptions>
inline const typename internal::transform_transform_product_impl< inline const typename internal::transform_transform_product_impl<
Transform,Transform<Scalar,Dim,OtherMode> >::ResultType Transform,Transform<Scalar,Dim,OtherMode,OtherOptions> >::ResultType
operator * (const Transform<Scalar,Dim,OtherMode>& other) const operator * (const Transform<Scalar,Dim,OtherMode,OtherOptions>& other) const
{ {
return internal::transform_transform_product_impl<Transform,Transform<Scalar,Dim,OtherMode> >::run(*this,other); return internal::transform_transform_product_impl<Transform,Transform<Scalar,Dim,OtherMode,OtherOptions> >::run(*this,other);
} }
/** \sa MatrixBase::setIdentity() */ /** \sa MatrixBase::setIdentity() */
@ -512,13 +541,16 @@ public:
* then this function smartly returns a const reference to \c *this. * then this function smartly returns a const reference to \c *this.
*/ */
template<typename NewScalarType> template<typename NewScalarType>
inline typename internal::cast_return_type<Transform,Transform<NewScalarType,Dim,Mode> >::type cast() const inline typename internal::cast_return_type<Transform,Transform<NewScalarType,Dim,Mode,Options> >::type cast() const
{ return typename internal::cast_return_type<Transform,Transform<NewScalarType,Dim,Mode> >::type(*this); } { return typename internal::cast_return_type<Transform,Transform<NewScalarType,Dim,Mode,Options> >::type(*this); }
/** Copy constructor with scalar type conversion */ /** Copy constructor with scalar type conversion */
template<typename OtherScalarType> template<typename OtherScalarType>
inline explicit Transform(const Transform<OtherScalarType,Dim,Mode>& other) inline explicit Transform(const Transform<OtherScalarType,Dim,Mode,Options>& other)
{ m_matrix = other.matrix().template cast<Scalar>(); } {
check_template_params();
m_matrix = other.matrix().template cast<Scalar>();
}
/** \returns \c true if \c *this is approximately equal to \a other, within the precision /** \returns \c true if \c *this is approximately equal to \a other, within the precision
* determined by \a prec. * determined by \a prec.
@ -568,6 +600,14 @@ public:
#ifdef EIGEN_TRANSFORM_PLUGIN #ifdef EIGEN_TRANSFORM_PLUGIN
#include EIGEN_TRANSFORM_PLUGIN #include EIGEN_TRANSFORM_PLUGIN
#endif #endif
protected:
#ifndef EIGEN_PARSED_BY_DOXYGEN
EIGEN_STRONG_INLINE static void check_template_params()
{
EIGEN_STATIC_ASSERT((Options & (DontAlign)) == Options, INVALID_MATRIX_TEMPLATE_PARAMETERS)
}
#endif
}; };
@ -616,9 +656,10 @@ typedef Transform<double,3,Projective> Projective3d;
* *
* This function is available only if the token EIGEN_QT_SUPPORT is defined. * This function is available only if the token EIGEN_QT_SUPPORT is defined.
*/ */
template<typename Scalar, int Dim, int Mode> template<typename Scalar, int Dim, int Mode,int Options>
Transform<Scalar,Dim,Mode>::Transform(const QMatrix& other) Transform<Scalar,Dim,Mode,Options>::Transform(const QMatrix& other)
{ {
check_template_params();
*this = other; *this = other;
} }
@ -626,8 +667,8 @@ Transform<Scalar,Dim,Mode>::Transform(const QMatrix& other)
* *
* This function is available only if the token EIGEN_QT_SUPPORT is defined. * This function is available only if the token EIGEN_QT_SUPPORT is defined.
*/ */
template<typename Scalar, int Dim, int Mode> template<typename Scalar, int Dim, int Mode,int Otpions>
Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode>::operator=(const QMatrix& other) Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const QMatrix& other)
{ {
EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE) EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
m_matrix << other.m11(), other.m21(), other.dx(), m_matrix << other.m11(), other.m21(), other.dx(),
@ -642,9 +683,10 @@ Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode>::operator=(const QMatrix&
* *
* This function is available only if the token EIGEN_QT_SUPPORT is defined. * This function is available only if the token EIGEN_QT_SUPPORT is defined.
*/ */
template<typename Scalar, int Dim, int Mode> template<typename Scalar, int Dim, int Mode, int Options>
QMatrix Transform<Scalar,Dim,Mode>::toQMatrix(void) const QMatrix Transform<Scalar,Dim,Mode,Options>::toQMatrix(void) const
{ {
check_template_params();
EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE) EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
return QMatrix(m_matrix.coeff(0,0), m_matrix.coeff(1,0), return QMatrix(m_matrix.coeff(0,0), m_matrix.coeff(1,0),
m_matrix.coeff(0,1), m_matrix.coeff(1,1), m_matrix.coeff(0,1), m_matrix.coeff(1,1),
@ -655,9 +697,10 @@ QMatrix Transform<Scalar,Dim,Mode>::toQMatrix(void) const
* *
* This function is available only if the token EIGEN_QT_SUPPORT is defined. * This function is available only if the token EIGEN_QT_SUPPORT is defined.
*/ */
template<typename Scalar, int Dim, int Mode> template<typename Scalar, int Dim, int Mode,int Options>
Transform<Scalar,Dim,Mode>::Transform(const QTransform& other) Transform<Scalar,Dim,Mode,Options>::Transform(const QTransform& other)
{ {
check_template_params();
*this = other; *this = other;
} }
@ -665,9 +708,10 @@ Transform<Scalar,Dim,Mode>::Transform(const QTransform& other)
* *
* This function is available only if the token EIGEN_QT_SUPPORT is defined. * This function is available only if the token EIGEN_QT_SUPPORT is defined.
*/ */
template<typename Scalar, int Dim, int Mode> template<typename Scalar, int Dim, int Mode, int Options>
Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode>::operator=(const QTransform& other) Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const QTransform& other)
{ {
check_template_params();
EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE) EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
m_matrix << other.m11(), other.m21(), other.dx(), m_matrix << other.m11(), other.m21(), other.dx(),
other.m12(), other.m22(), other.dy(), other.m12(), other.m22(), other.dy(),
@ -679,8 +723,8 @@ Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode>::operator=(const QTransfo
* *
* This function is available only if the token EIGEN_QT_SUPPORT is defined. * This function is available only if the token EIGEN_QT_SUPPORT is defined.
*/ */
template<typename Scalar, int Dim, int Mode> template<typename Scalar, int Dim, int Mode, int Options>
QTransform Transform<Scalar,Dim,Mode>::toQTransform(void) const QTransform Transform<Scalar,Dim,Mode,Options>::toQTransform(void) const
{ {
EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE) EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
return QTransform(matrix.coeff(0,0), matrix.coeff(1,0), matrix.coeff(2,0) return QTransform(matrix.coeff(0,0), matrix.coeff(1,0), matrix.coeff(2,0)
@ -697,10 +741,10 @@ QTransform Transform<Scalar,Dim,Mode>::toQTransform(void) const
* by the vector \a other to \c *this and returns a reference to \c *this. * by the vector \a other to \c *this and returns a reference to \c *this.
* \sa prescale() * \sa prescale()
*/ */
template<typename Scalar, int Dim, int Mode> template<typename Scalar, int Dim, int Mode, int Options>
template<typename OtherDerived> template<typename OtherDerived>
Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode,Options>&
Transform<Scalar,Dim,Mode>::scale(const MatrixBase<OtherDerived> &other) Transform<Scalar,Dim,Mode,Options>::scale(const MatrixBase<OtherDerived> &other)
{ {
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim)) EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS) EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
@ -712,8 +756,8 @@ Transform<Scalar,Dim,Mode>::scale(const MatrixBase<OtherDerived> &other)
* and returns a reference to \c *this. * and returns a reference to \c *this.
* \sa prescale(Scalar) * \sa prescale(Scalar)
*/ */
template<typename Scalar, int Dim, int Mode> template<typename Scalar, int Dim, int Mode, int Options>
inline Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode>::scale(Scalar s) inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::scale(Scalar s)
{ {
EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS) EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
linearExt() *= s; linearExt() *= s;
@ -724,10 +768,10 @@ inline Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode>::scale(Scalar s)
* by the vector \a other to \c *this and returns a reference to \c *this. * by the vector \a other to \c *this and returns a reference to \c *this.
* \sa scale() * \sa scale()
*/ */
template<typename Scalar, int Dim, int Mode> template<typename Scalar, int Dim, int Mode, int Options>
template<typename OtherDerived> template<typename OtherDerived>
Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode,Options>&
Transform<Scalar,Dim,Mode>::prescale(const MatrixBase<OtherDerived> &other) Transform<Scalar,Dim,Mode,Options>::prescale(const MatrixBase<OtherDerived> &other)
{ {
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim)) EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS) EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
@ -739,8 +783,8 @@ Transform<Scalar,Dim,Mode>::prescale(const MatrixBase<OtherDerived> &other)
* and returns a reference to \c *this. * and returns a reference to \c *this.
* \sa scale(Scalar) * \sa scale(Scalar)
*/ */
template<typename Scalar, int Dim, int Mode> template<typename Scalar, int Dim, int Mode, int Options>
inline Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode>::prescale(Scalar s) inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::prescale(Scalar s)
{ {
EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS) EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
m_matrix.template topRows<Dim>() *= s; m_matrix.template topRows<Dim>() *= s;
@ -751,10 +795,10 @@ inline Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode>::prescale(Scalar s
* to \c *this and returns a reference to \c *this. * to \c *this and returns a reference to \c *this.
* \sa pretranslate() * \sa pretranslate()
*/ */
template<typename Scalar, int Dim, int Mode> template<typename Scalar, int Dim, int Mode, int Options>
template<typename OtherDerived> template<typename OtherDerived>
Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode,Options>&
Transform<Scalar,Dim,Mode>::translate(const MatrixBase<OtherDerived> &other) Transform<Scalar,Dim,Mode,Options>::translate(const MatrixBase<OtherDerived> &other)
{ {
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim)) EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
translationExt() += linearExt() * other; translationExt() += linearExt() * other;
@ -765,10 +809,10 @@ Transform<Scalar,Dim,Mode>::translate(const MatrixBase<OtherDerived> &other)
* to \c *this and returns a reference to \c *this. * to \c *this and returns a reference to \c *this.
* \sa translate() * \sa translate()
*/ */
template<typename Scalar, int Dim, int Mode> template<typename Scalar, int Dim, int Mode, int Options>
template<typename OtherDerived> template<typename OtherDerived>
Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode,Options>&
Transform<Scalar,Dim,Mode>::pretranslate(const MatrixBase<OtherDerived> &other) Transform<Scalar,Dim,Mode,Options>::pretranslate(const MatrixBase<OtherDerived> &other)
{ {
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim)) EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
if(int(Mode)==int(Projective)) if(int(Mode)==int(Projective))
@ -795,10 +839,10 @@ Transform<Scalar,Dim,Mode>::pretranslate(const MatrixBase<OtherDerived> &other)
* *
* \sa rotate(Scalar), class Quaternion, class AngleAxis, prerotate(RotationType) * \sa rotate(Scalar), class Quaternion, class AngleAxis, prerotate(RotationType)
*/ */
template<typename Scalar, int Dim, int Mode> template<typename Scalar, int Dim, int Mode, int Options>
template<typename RotationType> template<typename RotationType>
Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode,Options>&
Transform<Scalar,Dim,Mode>::rotate(const RotationType& rotation) Transform<Scalar,Dim,Mode,Options>::rotate(const RotationType& rotation)
{ {
linearExt() *= internal::toRotationMatrix<Scalar,Dim>(rotation); linearExt() *= internal::toRotationMatrix<Scalar,Dim>(rotation);
return *this; return *this;
@ -811,10 +855,10 @@ Transform<Scalar,Dim,Mode>::rotate(const RotationType& rotation)
* *
* \sa rotate() * \sa rotate()
*/ */
template<typename Scalar, int Dim, int Mode> template<typename Scalar, int Dim, int Mode, int Options>
template<typename RotationType> template<typename RotationType>
Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode,Options>&
Transform<Scalar,Dim,Mode>::prerotate(const RotationType& rotation) Transform<Scalar,Dim,Mode,Options>::prerotate(const RotationType& rotation)
{ {
m_matrix.template block<Dim,HDim>(0,0) = internal::toRotationMatrix<Scalar,Dim>(rotation) m_matrix.template block<Dim,HDim>(0,0) = internal::toRotationMatrix<Scalar,Dim>(rotation)
* m_matrix.template block<Dim,HDim>(0,0); * m_matrix.template block<Dim,HDim>(0,0);
@ -826,9 +870,9 @@ Transform<Scalar,Dim,Mode>::prerotate(const RotationType& rotation)
* \warning 2D only. * \warning 2D only.
* \sa preshear() * \sa preshear()
*/ */
template<typename Scalar, int Dim, int Mode> template<typename Scalar, int Dim, int Mode, int Options>
Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode,Options>&
Transform<Scalar,Dim,Mode>::shear(Scalar sx, Scalar sy) Transform<Scalar,Dim,Mode,Options>::shear(Scalar sx, Scalar sy)
{ {
EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE) EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS) EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
@ -842,9 +886,9 @@ Transform<Scalar,Dim,Mode>::shear(Scalar sx, Scalar sy)
* \warning 2D only. * \warning 2D only.
* \sa shear() * \sa shear()
*/ */
template<typename Scalar, int Dim, int Mode> template<typename Scalar, int Dim, int Mode, int Options>
Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode,Options>&
Transform<Scalar,Dim,Mode>::preshear(Scalar sx, Scalar sy) Transform<Scalar,Dim,Mode,Options>::preshear(Scalar sx, Scalar sy)
{ {
EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE) EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS) EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
@ -856,8 +900,8 @@ Transform<Scalar,Dim,Mode>::preshear(Scalar sx, Scalar sy)
*** Scaling, Translation and Rotation compatibility *** *** Scaling, Translation and Rotation compatibility ***
******************************************************/ ******************************************************/
template<typename Scalar, int Dim, int Mode> template<typename Scalar, int Dim, int Mode, int Options>
inline Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode>::operator=(const TranslationType& t) inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const TranslationType& t)
{ {
linear().setIdentity(); linear().setIdentity();
translation() = t.vector(); translation() = t.vector();
@ -865,16 +909,16 @@ inline Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode>::operator=(const T
return *this; return *this;
} }
template<typename Scalar, int Dim, int Mode> template<typename Scalar, int Dim, int Mode, int Options>
inline Transform<Scalar,Dim,Mode> Transform<Scalar,Dim,Mode>::operator*(const TranslationType& t) const inline Transform<Scalar,Dim,Mode,Options> Transform<Scalar,Dim,Mode,Options>::operator*(const TranslationType& t) const
{ {
Transform res = *this; Transform res = *this;
res.translate(t.vector()); res.translate(t.vector());
return res; return res;
} }
template<typename Scalar, int Dim, int Mode> template<typename Scalar, int Dim, int Mode, int Options>
inline Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode>::operator=(const UniformScaling<Scalar>& s) inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const UniformScaling<Scalar>& s)
{ {
m_matrix.setZero(); m_matrix.setZero();
linear().diagonal().fill(s.factor()); linear().diagonal().fill(s.factor());
@ -882,17 +926,17 @@ inline Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode>::operator=(const U
return *this; return *this;
} }
template<typename Scalar, int Dim, int Mode> template<typename Scalar, int Dim, int Mode, int Options>
inline Transform<Scalar,Dim,Mode> Transform<Scalar,Dim,Mode>::operator*(const UniformScaling<Scalar>& s) const inline Transform<Scalar,Dim,Mode,Options> Transform<Scalar,Dim,Mode,Options>::operator*(const UniformScaling<Scalar>& s) const
{ {
Transform res = *this; Transform res = *this;
res.scale(s.factor()); res.scale(s.factor());
return res; return res;
} }
template<typename Scalar, int Dim, int Mode> template<typename Scalar, int Dim, int Mode, int Options>
template<typename Derived> template<typename Derived>
inline Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode>::operator=(const RotationBase<Derived,Dim>& r) inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const RotationBase<Derived,Dim>& r)
{ {
linear() = internal::toRotationMatrix<Scalar,Dim>(r); linear() = internal::toRotationMatrix<Scalar,Dim>(r);
translation().setZero(); translation().setZero();
@ -900,9 +944,9 @@ inline Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode>::operator=(const R
return *this; return *this;
} }
template<typename Scalar, int Dim, int Mode> template<typename Scalar, int Dim, int Mode, int Options>
template<typename Derived> template<typename Derived>
inline Transform<Scalar,Dim,Mode> Transform<Scalar,Dim,Mode>::operator*(const RotationBase<Derived,Dim>& r) const inline Transform<Scalar,Dim,Mode,Options> Transform<Scalar,Dim,Mode,Options>::operator*(const RotationBase<Derived,Dim>& r) const
{ {
Transform res = *this; Transform res = *this;
res.rotate(r.derived()); res.rotate(r.derived());
@ -920,9 +964,9 @@ inline Transform<Scalar,Dim,Mode> Transform<Scalar,Dim,Mode>::operator*(const Ro
* *
* \sa computeRotationScaling(), computeScalingRotation(), class SVD * \sa computeRotationScaling(), computeScalingRotation(), class SVD
*/ */
template<typename Scalar, int Dim, int Mode> template<typename Scalar, int Dim, int Mode, int Options>
typename Transform<Scalar,Dim,Mode>::LinearMatrixType typename Transform<Scalar,Dim,Mode,Options>::LinearMatrixType
Transform<Scalar,Dim,Mode>::rotation() const Transform<Scalar,Dim,Mode,Options>::rotation() const
{ {
LinearMatrixType result; LinearMatrixType result;
computeRotationScaling(&result, (LinearMatrixType*)0); computeRotationScaling(&result, (LinearMatrixType*)0);
@ -941,9 +985,9 @@ Transform<Scalar,Dim,Mode>::rotation() const
* *
* \sa computeScalingRotation(), rotation(), class SVD * \sa computeScalingRotation(), rotation(), class SVD
*/ */
template<typename Scalar, int Dim, int Mode> template<typename Scalar, int Dim, int Mode, int Options>
template<typename RotationMatrixType, typename ScalingMatrixType> template<typename RotationMatrixType, typename ScalingMatrixType>
void Transform<Scalar,Dim,Mode>::computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const void Transform<Scalar,Dim,Mode,Options>::computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const
{ {
JacobiSVD<LinearMatrixType> svd(linear(), ComputeFullU | ComputeFullV); JacobiSVD<LinearMatrixType> svd(linear(), ComputeFullU | ComputeFullV);
@ -970,9 +1014,9 @@ void Transform<Scalar,Dim,Mode>::computeRotationScaling(RotationMatrixType *rota
* *
* \sa computeRotationScaling(), rotation(), class SVD * \sa computeRotationScaling(), rotation(), class SVD
*/ */
template<typename Scalar, int Dim, int Mode> template<typename Scalar, int Dim, int Mode, int Options>
template<typename ScalingMatrixType, typename RotationMatrixType> template<typename ScalingMatrixType, typename RotationMatrixType>
void Transform<Scalar,Dim,Mode>::computeScalingRotation(ScalingMatrixType *scaling, RotationMatrixType *rotation) const void Transform<Scalar,Dim,Mode,Options>::computeScalingRotation(ScalingMatrixType *scaling, RotationMatrixType *rotation) const
{ {
JacobiSVD<LinearMatrixType> svd(linear(), ComputeFullU | ComputeFullV); JacobiSVD<LinearMatrixType> svd(linear(), ComputeFullU | ComputeFullV);
@ -991,10 +1035,10 @@ void Transform<Scalar,Dim,Mode>::computeScalingRotation(ScalingMatrixType *scali
/** Convenient method to set \c *this from a position, orientation and scale /** Convenient method to set \c *this from a position, orientation and scale
* of a 3D object. * of a 3D object.
*/ */
template<typename Scalar, int Dim, int Mode> template<typename Scalar, int Dim, int Mode, int Options>
template<typename PositionDerived, typename OrientationType, typename ScaleDerived> template<typename PositionDerived, typename OrientationType, typename ScaleDerived>
Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode,Options>&
Transform<Scalar,Dim,Mode>::fromPositionOrientationScale(const MatrixBase<PositionDerived> &position, Transform<Scalar,Dim,Mode,Options>::fromPositionOrientationScale(const MatrixBase<PositionDerived> &position,
const OrientationType& orientation, const MatrixBase<ScaleDerived> &scale) const OrientationType& orientation, const MatrixBase<ScaleDerived> &scale)
{ {
linear() = internal::toRotationMatrix<Scalar,Dim>(orientation); linear() = internal::toRotationMatrix<Scalar,Dim>(orientation);
@ -1045,9 +1089,9 @@ struct projective_transform_inverse<TransformType, Projective>
* *
* \sa MatrixBase::inverse() * \sa MatrixBase::inverse()
*/ */
template<typename Scalar, int Dim, int Mode> template<typename Scalar, int Dim, int Mode, int Options>
Transform<Scalar,Dim,Mode> Transform<Scalar,Dim,Mode,Options>
Transform<Scalar,Dim,Mode>::inverse(TransformTraits hint) const Transform<Scalar,Dim,Mode,Options>::inverse(TransformTraits hint) const
{ {
Transform res; Transform res;
if (hint == Projective) if (hint == Projective)
@ -1103,10 +1147,10 @@ struct transform_take_affine_part<Transform<Scalar,Dim,AffineCompact> > {
*** Specializations of construct from matrix *** *** Specializations of construct from matrix ***
*****************************************************/ *****************************************************/
template<typename Other, int Mode, int Dim, int HDim> template<typename Other, int Mode, int Options, int Dim, int HDim>
struct transform_construct_from_matrix<Other, Mode,Dim,HDim, Dim,Dim> struct transform_construct_from_matrix<Other, Mode,Options,Dim,HDim, Dim,Dim>
{ {
static inline void run(Transform<typename Other::Scalar,Dim,Mode> *transform, const Other& other) static inline void run(Transform<typename Other::Scalar,Dim,Mode,Options> *transform, const Other& other)
{ {
transform->linear() = other; transform->linear() = other;
transform->translation().setZero(); transform->translation().setZero();
@ -1114,25 +1158,25 @@ struct transform_construct_from_matrix<Other, Mode,Dim,HDim, Dim,Dim>
} }
}; };
template<typename Other, int Mode, int Dim, int HDim> template<typename Other, int Mode, int Options, int Dim, int HDim>
struct transform_construct_from_matrix<Other, Mode,Dim,HDim, Dim,HDim> struct transform_construct_from_matrix<Other, Mode,Options,Dim,HDim, Dim,HDim>
{ {
static inline void run(Transform<typename Other::Scalar,Dim,Mode> *transform, const Other& other) static inline void run(Transform<typename Other::Scalar,Dim,Mode,Options> *transform, const Other& other)
{ {
transform->affine() = other; transform->affine() = other;
transform->makeAffine(); transform->makeAffine();
} }
}; };
template<typename Other, int Mode, int Dim, int HDim> template<typename Other, int Mode, int Options, int Dim, int HDim>
struct transform_construct_from_matrix<Other, Mode,Dim,HDim, HDim,HDim> struct transform_construct_from_matrix<Other, Mode,Options,Dim,HDim, HDim,HDim>
{ {
static inline void run(Transform<typename Other::Scalar,Dim,Mode> *transform, const Other& other) static inline void run(Transform<typename Other::Scalar,Dim,Mode,Options> *transform, const Other& other)
{ transform->matrix() = other; } { transform->matrix() = other; }
}; };
template<typename Other, int Dim, int HDim> template<typename Other, int Options, int Dim, int HDim>
struct transform_construct_from_matrix<Other, AffineCompact,Dim,HDim, HDim,HDim> struct transform_construct_from_matrix<Other, AffineCompact,Options,Dim,HDim, HDim,HDim>
{ {
static inline void run(Transform<typename Other::Scalar,Dim,AffineCompact> *transform, const Other& other) static inline void run(Transform<typename Other::Scalar,Dim,AffineCompact> *transform, const Other& other)
{ transform->matrix() = other.template block<Dim,HDim>(0,0); } { transform->matrix() = other.template block<Dim,HDim>(0,0); }
@ -1204,23 +1248,23 @@ struct transform_right_product_impl< TransformType, MatrixType, false >
**********************************************************/ **********************************************************/
// generic HDim x HDim matrix * T => Projective // generic HDim x HDim matrix * T => Projective
template<typename Other,int Mode, int Dim, int HDim> template<typename Other,int Mode, int Options, int Dim, int HDim>
struct transform_left_product_impl<Other,Mode,Dim,HDim, HDim,HDim> struct transform_left_product_impl<Other,Mode,Options,Dim,HDim, HDim,HDim>
{ {
typedef Transform<typename Other::Scalar,Dim,Mode> TransformType; typedef Transform<typename Other::Scalar,Dim,Mode,Options> TransformType;
typedef typename TransformType::MatrixType MatrixType; typedef typename TransformType::MatrixType MatrixType;
typedef Transform<typename Other::Scalar,Dim,Projective> ResultType; typedef Transform<typename Other::Scalar,Dim,Projective,Options> ResultType;
static ResultType run(const Other& other,const TransformType& tr) static ResultType run(const Other& other,const TransformType& tr)
{ return ResultType(other * tr.matrix()); } { return ResultType(other * tr.matrix()); }
}; };
// generic HDim x HDim matrix * AffineCompact => Projective // generic HDim x HDim matrix * AffineCompact => Projective
template<typename Other, int Dim, int HDim> template<typename Other, int Options, int Dim, int HDim>
struct transform_left_product_impl<Other,AffineCompact,Dim,HDim, HDim,HDim> struct transform_left_product_impl<Other,AffineCompact,Options,Dim,HDim, HDim,HDim>
{ {
typedef Transform<typename Other::Scalar,Dim,AffineCompact> TransformType; typedef Transform<typename Other::Scalar,Dim,AffineCompact,Options> TransformType;
typedef typename TransformType::MatrixType MatrixType; typedef typename TransformType::MatrixType MatrixType;
typedef Transform<typename Other::Scalar,Dim,Projective> ResultType; typedef Transform<typename Other::Scalar,Dim,Projective,Options> ResultType;
static ResultType run(const Other& other,const TransformType& tr) static ResultType run(const Other& other,const TransformType& tr)
{ {
ResultType res; ResultType res;
@ -1231,10 +1275,10 @@ struct transform_left_product_impl<Other,AffineCompact,Dim,HDim, HDim,HDim>
}; };
// affine matrix * T // affine matrix * T
template<typename Other,int Mode, int Dim, int HDim> template<typename Other,int Mode, int Options, int Dim, int HDim>
struct transform_left_product_impl<Other,Mode,Dim,HDim, Dim,HDim> struct transform_left_product_impl<Other,Mode,Options,Dim,HDim, Dim,HDim>
{ {
typedef Transform<typename Other::Scalar,Dim,Mode> TransformType; typedef Transform<typename Other::Scalar,Dim,Mode,Options> TransformType;
typedef typename TransformType::MatrixType MatrixType; typedef typename TransformType::MatrixType MatrixType;
typedef TransformType ResultType; typedef TransformType ResultType;
static ResultType run(const Other& other,const TransformType& tr) static ResultType run(const Other& other,const TransformType& tr)
@ -1247,10 +1291,10 @@ struct transform_left_product_impl<Other,Mode,Dim,HDim, Dim,HDim>
}; };
// affine matrix * AffineCompact // affine matrix * AffineCompact
template<typename Other, int Dim, int HDim> template<typename Other, int Options, int Dim, int HDim>
struct transform_left_product_impl<Other,AffineCompact,Dim,HDim, Dim,HDim> struct transform_left_product_impl<Other,AffineCompact,Options,Dim,HDim, Dim,HDim>
{ {
typedef Transform<typename Other::Scalar,Dim,AffineCompact> TransformType; typedef Transform<typename Other::Scalar,Dim,AffineCompact,Options> TransformType;
typedef typename TransformType::MatrixType MatrixType; typedef typename TransformType::MatrixType MatrixType;
typedef TransformType ResultType; typedef TransformType ResultType;
static ResultType run(const Other& other,const TransformType& tr) static ResultType run(const Other& other,const TransformType& tr)
@ -1263,10 +1307,10 @@ struct transform_left_product_impl<Other,AffineCompact,Dim,HDim, Dim,HDim>
}; };
// linear matrix * T // linear matrix * T
template<typename Other,int Mode, int Dim, int HDim> template<typename Other,int Mode, int Options, int Dim, int HDim>
struct transform_left_product_impl<Other,Mode,Dim,HDim, Dim,Dim> struct transform_left_product_impl<Other,Mode,Options,Dim,HDim, Dim,Dim>
{ {
typedef Transform<typename Other::Scalar,Dim,Mode> TransformType; typedef Transform<typename Other::Scalar,Dim,Mode,Options> TransformType;
typedef typename TransformType::MatrixType MatrixType; typedef typename TransformType::MatrixType MatrixType;
typedef TransformType ResultType; typedef TransformType ResultType;
static ResultType run(const Other& other, const TransformType& tr) static ResultType run(const Other& other, const TransformType& tr)
@ -1284,13 +1328,13 @@ struct transform_left_product_impl<Other,Mode,Dim,HDim, Dim,Dim>
*** Specializations of operator* with another Transform *** *** Specializations of operator* with another Transform ***
**********************************************************/ **********************************************************/
template<typename Scalar, int Dim, int LhsMode, int RhsMode> template<typename Scalar, int Dim, int LhsMode, int LhsOptions, int RhsMode, int RhsOptions>
struct transform_transform_product_impl<Transform<Scalar,Dim,LhsMode>,Transform<Scalar,Dim,RhsMode>,false > struct transform_transform_product_impl<Transform<Scalar,Dim,LhsMode,LhsOptions>,Transform<Scalar,Dim,RhsMode,RhsOptions>,false >
{ {
enum { ResultMode = transform_product_result<LhsMode,RhsMode>::Mode }; enum { ResultMode = transform_product_result<LhsMode,RhsMode>::Mode };
typedef Transform<Scalar,Dim,LhsMode> Lhs; typedef Transform<Scalar,Dim,LhsMode,LhsOptions> Lhs;
typedef Transform<Scalar,Dim,RhsMode> Rhs; typedef Transform<Scalar,Dim,RhsMode,RhsOptions> Rhs;
typedef Transform<Scalar,Dim,ResultMode> ResultType; typedef Transform<Scalar,Dim,ResultMode,LhsOptions> ResultType;
static ResultType run(const Lhs& lhs, const Rhs& rhs) static ResultType run(const Lhs& lhs, const Rhs& rhs)
{ {
ResultType res; ResultType res;
@ -1301,11 +1345,11 @@ struct transform_transform_product_impl<Transform<Scalar,Dim,LhsMode>,Transform<
} }
}; };
template<typename Scalar, int Dim, int LhsMode, int RhsMode> template<typename Scalar, int Dim, int LhsMode, int LhsOptions, int RhsMode, int RhsOptions>
struct transform_transform_product_impl<Transform<Scalar,Dim,LhsMode>,Transform<Scalar,Dim,RhsMode>,true > struct transform_transform_product_impl<Transform<Scalar,Dim,LhsMode,LhsOptions>,Transform<Scalar,Dim,RhsMode,RhsOptions>,true >
{ {
typedef Transform<Scalar,Dim,LhsMode> Lhs; typedef Transform<Scalar,Dim,LhsMode,LhsOptions> Lhs;
typedef Transform<Scalar,Dim,RhsMode> Rhs; typedef Transform<Scalar,Dim,RhsMode,RhsOptions> Rhs;
typedef Transform<Scalar,Dim,Projective> ResultType; typedef Transform<Scalar,Dim,Projective> ResultType;
static ResultType run(const Lhs& lhs, const Rhs& rhs) static ResultType run(const Lhs& lhs, const Rhs& rhs)
{ {

View File

@ -132,8 +132,8 @@ public:
} }
/** Concatenates a translation and a transformation */ /** Concatenates a translation and a transformation */
template<int Mode> template<int Mode, int Options>
inline Transform<Scalar,Dim,Mode> operator* (const Transform<Scalar,Dim,Mode>& t) const inline Transform<Scalar,Dim,Mode> operator* (const Transform<Scalar,Dim,Mode,Options>& t) const
{ {
Transform<Scalar,Dim,Mode> res = t; Transform<Scalar,Dim,Mode> res = t;
res.pretranslate(m_coeffs); res.pretranslate(m_coeffs);

View File

@ -27,7 +27,7 @@
#include <Eigen/LU> #include <Eigen/LU>
#include <Eigen/SVD> #include <Eigen/SVD>
template<typename Scalar, int Mode> void non_projective_only(void) template<typename Scalar, int Mode, int Options> void non_projective_only()
{ {
/* this test covers the following files: /* this test covers the following files:
Cross.h Quaternion.h, Transform.cpp Cross.h Quaternion.h, Transform.cpp
@ -40,10 +40,10 @@ template<typename Scalar, int Mode> void non_projective_only(void)
typedef Matrix<Scalar,4,1> Vector4; typedef Matrix<Scalar,4,1> Vector4;
typedef Quaternion<Scalar> Quaternionx; typedef Quaternion<Scalar> Quaternionx;
typedef AngleAxis<Scalar> AngleAxisx; typedef AngleAxis<Scalar> AngleAxisx;
typedef Transform<Scalar,2,Mode> Transform2; typedef Transform<Scalar,2,Mode,Options> Transform2;
typedef Transform<Scalar,3,Mode> Transform3; typedef Transform<Scalar,3,Mode,Options> Transform3;
typedef Transform<Scalar,2,Isometry> Isometry2; typedef Transform<Scalar,2,Isometry,Options> Isometry2;
typedef Transform<Scalar,3,Isometry> Isometry3; typedef Transform<Scalar,3,Isometry,Options> Isometry3;
typedef typename Transform3::MatrixType MatrixType; typedef typename Transform3::MatrixType MatrixType;
typedef DiagonalMatrix<Scalar,2> AlignedScaling2; typedef DiagonalMatrix<Scalar,2> AlignedScaling2;
typedef DiagonalMatrix<Scalar,3> AlignedScaling3; typedef DiagonalMatrix<Scalar,3> AlignedScaling3;
@ -102,7 +102,7 @@ template<typename Scalar, int Mode> void non_projective_only(void)
VERIFY_IS_APPROX((t0 * v1).template head<3>(), AlignedScaling3(v0) * v1); VERIFY_IS_APPROX((t0 * v1).template head<3>(), AlignedScaling3(v0) * v1);
} }
template<typename Scalar, int Mode> void transformations(void) template<typename Scalar, int Mode, int Options> void transformations()
{ {
/* this test covers the following files: /* this test covers the following files:
Cross.h Quaternion.h, Transform.cpp Cross.h Quaternion.h, Transform.cpp
@ -115,10 +115,10 @@ template<typename Scalar, int Mode> void transformations(void)
typedef Matrix<Scalar,4,1> Vector4; typedef Matrix<Scalar,4,1> Vector4;
typedef Quaternion<Scalar> Quaternionx; typedef Quaternion<Scalar> Quaternionx;
typedef AngleAxis<Scalar> AngleAxisx; typedef AngleAxis<Scalar> AngleAxisx;
typedef Transform<Scalar,2,Mode> Transform2; typedef Transform<Scalar,2,Mode,Options> Transform2;
typedef Transform<Scalar,3,Mode> Transform3; typedef Transform<Scalar,3,Mode,Options> Transform3;
typedef Transform<Scalar,2,Isometry> Isometry2; typedef Transform<Scalar,2,Isometry,Options> Isometry2;
typedef Transform<Scalar,3,Isometry> Isometry3; typedef Transform<Scalar,3,Isometry,Options> Isometry3;
typedef typename Transform3::MatrixType MatrixType; typedef typename Transform3::MatrixType MatrixType;
typedef DiagonalMatrix<Scalar,2> AlignedScaling2; typedef DiagonalMatrix<Scalar,2> AlignedScaling2;
typedef DiagonalMatrix<Scalar,3> AlignedScaling3; typedef DiagonalMatrix<Scalar,3> AlignedScaling3;
@ -427,15 +427,45 @@ template<typename Scalar, int Mode> void transformations(void)
} }
template<typename Scalar> void transform_alignment()
{
typedef Transform<Scalar,3,Projective,AutoAlign> Projective4a;
typedef Transform<Scalar,3,Projective,DontAlign> Projective4u;
EIGEN_ALIGN16 Scalar array1[16];
EIGEN_ALIGN16 Scalar array2[16];
EIGEN_ALIGN16 Scalar array3[16+1];
Scalar* array3u = array3+1;
Projective4a *p1 = ::new(reinterpret_cast<void*>(array1)) Projective4a;
Projective4u *p2 = ::new(reinterpret_cast<void*>(array2)) Projective4u;
Projective4u *p3 = ::new(reinterpret_cast<void*>(array3u)) Projective4u;
p1->matrix().setRandom();
*p2 = *p1;
*p3 = *p1;
VERIFY_IS_APPROX(p1->matrix(), p2->matrix());
VERIFY_IS_APPROX(p1->matrix(), p3->matrix());
VERIFY_IS_APPROX( (*p1) * (*p1), (*p2)*(*p3));
#ifdef EIGEN_VECTORIZE
VERIFY_RAISES_ASSERT((::new(reinterpret_cast<void*>(array3u)) Projective4a));
#endif
}
void test_geo_transformations() void test_geo_transformations()
{ {
for(int i = 0; i < g_repeat; i++) { for(int i = 0; i < g_repeat; i++) {
CALL_SUBTEST_1(( transformations<double,Affine>() )); CALL_SUBTEST_1(( transformations<double,Affine,AutoAlign>() ));
CALL_SUBTEST_1(( non_projective_only<double,Affine>() )); CALL_SUBTEST_1(( non_projective_only<double,Affine,AutoAlign>() ));
CALL_SUBTEST_2(( transformations<float,AffineCompact>() )); CALL_SUBTEST_2(( transformations<float,AffineCompact,AutoAlign>() ));
CALL_SUBTEST_2(( non_projective_only<float,AffineCompact>() )); CALL_SUBTEST_2(( non_projective_only<float,AffineCompact,AutoAlign>() ));
CALL_SUBTEST_3(( transformations<double,Projective>() )); CALL_SUBTEST_3(( transformations<double,Projective,AutoAlign>() ));
CALL_SUBTEST_3(( transformations<double,Projective,DontAlign>() ));
CALL_SUBTEST_3(( transform_alignment<double>() ));
} }
} }