Another set of UI messages fixes and tweaks! No functional changes.
[blender.git] / extern / Eigen3 / Eigen / src / Geometry / RotationBase.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
5 //
6 // Eigen is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 3 of the License, or (at your option) any later version.
10 //
11 // Alternatively, you can redistribute it and/or
12 // modify it under the terms of the GNU General Public License as
13 // published by the Free Software Foundation; either version 2 of
14 // the License, or (at your option) any later version.
15 //
16 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
17 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public
22 // License and a copy of the GNU General Public License along with
23 // Eigen. If not, see <http://www.gnu.org/licenses/>.
24
25 #ifndef EIGEN_ROTATIONBASE_H
26 #define EIGEN_ROTATIONBASE_H
27
28 // forward declaration
29 namespace internal {
30 template<typename RotationDerived, typename MatrixType, bool IsVector=MatrixType::IsVectorAtCompileTime>
31 struct rotation_base_generic_product_selector;
32 }
33
34 /** \class RotationBase
35   *
36   * \brief Common base class for compact rotation representations
37   *
38   * \param Derived is the derived type, i.e., a rotation type
39   * \param _Dim the dimension of the space
40   */
41 template<typename Derived, int _Dim>
42 class RotationBase
43 {
44   public:
45     enum { Dim = _Dim };
46     /** the scalar type of the coefficients */
47     typedef typename internal::traits<Derived>::Scalar Scalar;
48
49     /** corresponding linear transformation matrix type */
50     typedef Matrix<Scalar,Dim,Dim> RotationMatrixType;
51     typedef Matrix<Scalar,Dim,1> VectorType;
52
53   public:
54     inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
55     inline Derived& derived() { return *static_cast<Derived*>(this); }
56
57     /** \returns an equivalent rotation matrix */
58     inline RotationMatrixType toRotationMatrix() const { return derived().toRotationMatrix(); }
59
60     /** \returns an equivalent rotation matrix 
61       * This function is added to be conform with the Transform class' naming scheme.
62       */
63     inline RotationMatrixType matrix() const { return derived().toRotationMatrix(); }
64
65     /** \returns the inverse rotation */
66     inline Derived inverse() const { return derived().inverse(); }
67
68     /** \returns the concatenation of the rotation \c *this with a translation \a t */
69     inline Transform<Scalar,Dim,Isometry> operator*(const Translation<Scalar,Dim>& t) const
70     { return Transform<Scalar,Dim,Isometry>(*this) * t; }
71
72     /** \returns the concatenation of the rotation \c *this with a uniform scaling \a s */
73     inline RotationMatrixType operator*(const UniformScaling<Scalar>& s) const
74     { return toRotationMatrix() * s.factor(); }
75
76     /** \returns the concatenation of the rotation \c *this with a generic expression \a e
77       * \a e can be:
78       *  - a DimxDim linear transformation matrix
79       *  - a DimxDim diagonal matrix (axis aligned scaling)
80       *  - a vector of size Dim
81       */
82     template<typename OtherDerived>
83     EIGEN_STRONG_INLINE typename internal::rotation_base_generic_product_selector<Derived,OtherDerived,OtherDerived::IsVectorAtCompileTime>::ReturnType
84     operator*(const EigenBase<OtherDerived>& e) const
85     { return internal::rotation_base_generic_product_selector<Derived,OtherDerived>::run(derived(), e.derived()); }
86
87     /** \returns the concatenation of a linear transformation \a l with the rotation \a r */
88     template<typename OtherDerived> friend
89     inline RotationMatrixType operator*(const EigenBase<OtherDerived>& l, const Derived& r)
90     { return l.derived() * r.toRotationMatrix(); }
91
92     /** \returns the concatenation of a scaling \a l with the rotation \a r */
93     friend inline Transform<Scalar,Dim,Affine> operator*(const DiagonalMatrix<Scalar,Dim>& l, const Derived& r)
94     { 
95       Transform<Scalar,Dim,Affine> res(r);
96       res.linear().applyOnTheLeft(l);
97       return res;
98     }
99
100     /** \returns the concatenation of the rotation \c *this with a transformation \a t */
101     template<int Mode, int Options>
102     inline Transform<Scalar,Dim,Mode> operator*(const Transform<Scalar,Dim,Mode,Options>& t) const
103     { return toRotationMatrix() * t; }
104
105     template<typename OtherVectorType>
106     inline VectorType _transformVector(const OtherVectorType& v) const
107     { return toRotationMatrix() * v; }
108 };
109
110 namespace internal {
111
112 // implementation of the generic product rotation * matrix
113 template<typename RotationDerived, typename MatrixType>
114 struct rotation_base_generic_product_selector<RotationDerived,MatrixType,false>
115 {
116   enum { Dim = RotationDerived::Dim };
117   typedef Matrix<typename RotationDerived::Scalar,Dim,Dim> ReturnType;
118   inline static ReturnType run(const RotationDerived& r, const MatrixType& m)
119   { return r.toRotationMatrix() * m; }
120 };
121
122 template<typename RotationDerived, typename Scalar, int Dim, int MaxDim>
123 struct rotation_base_generic_product_selector< RotationDerived, DiagonalMatrix<Scalar,Dim,MaxDim>, false >
124 {
125   typedef Transform<Scalar,Dim,Affine> ReturnType;
126   inline static ReturnType run(const RotationDerived& r, const DiagonalMatrix<Scalar,Dim,MaxDim>& m)
127   {
128     ReturnType res(r);
129     res.linear() *= m;
130     return res;
131   }
132 };
133
134 template<typename RotationDerived,typename OtherVectorType>
135 struct rotation_base_generic_product_selector<RotationDerived,OtherVectorType,true>
136 {
137   enum { Dim = RotationDerived::Dim };
138   typedef Matrix<typename RotationDerived::Scalar,Dim,1> ReturnType;
139   EIGEN_STRONG_INLINE static ReturnType run(const RotationDerived& r, const OtherVectorType& v)
140   {
141     return r._transformVector(v);
142   }
143 };
144
145 } // end namespace internal
146
147 /** \geometry_module
148   *
149   * \brief Constructs a Dim x Dim rotation matrix from the rotation \a r
150   */
151 template<typename _Scalar, int _Rows, int _Cols, int _Storage, int _MaxRows, int _MaxCols>
152 template<typename OtherDerived>
153 Matrix<_Scalar, _Rows, _Cols, _Storage, _MaxRows, _MaxCols>
154 ::Matrix(const RotationBase<OtherDerived,ColsAtCompileTime>& r)
155 {
156   EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Matrix,int(OtherDerived::Dim),int(OtherDerived::Dim))
157   *this = r.toRotationMatrix();
158 }
159
160 /** \geometry_module
161   *
162   * \brief Set a Dim x Dim rotation matrix from the rotation \a r
163   */
164 template<typename _Scalar, int _Rows, int _Cols, int _Storage, int _MaxRows, int _MaxCols>
165 template<typename OtherDerived>
166 Matrix<_Scalar, _Rows, _Cols, _Storage, _MaxRows, _MaxCols>&
167 Matrix<_Scalar, _Rows, _Cols, _Storage, _MaxRows, _MaxCols>
168 ::operator=(const RotationBase<OtherDerived,ColsAtCompileTime>& r)
169 {
170   EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Matrix,int(OtherDerived::Dim),int(OtherDerived::Dim))
171   return *this = r.toRotationMatrix();
172 }
173
174 namespace internal {
175
176 /** \internal
177   *
178   * Helper function to return an arbitrary rotation object to a rotation matrix.
179   *
180   * \param Scalar the numeric type of the matrix coefficients
181   * \param Dim the dimension of the current space
182   *
183   * It returns a Dim x Dim fixed size matrix.
184   *
185   * Default specializations are provided for:
186   *   - any scalar type (2D),
187   *   - any matrix expression,
188   *   - any type based on RotationBase (e.g., Quaternion, AngleAxis, Rotation2D)
189   *
190   * Currently toRotationMatrix is only used by Transform.
191   *
192   * \sa class Transform, class Rotation2D, class Quaternion, class AngleAxis
193   */
194 template<typename Scalar, int Dim>
195 inline static Matrix<Scalar,2,2> toRotationMatrix(const Scalar& s)
196 {
197   EIGEN_STATIC_ASSERT(Dim==2,YOU_MADE_A_PROGRAMMING_MISTAKE)
198   return Rotation2D<Scalar>(s).toRotationMatrix();
199 }
200
201 template<typename Scalar, int Dim, typename OtherDerived>
202 inline static Matrix<Scalar,Dim,Dim> toRotationMatrix(const RotationBase<OtherDerived,Dim>& r)
203 {
204   return r.toRotationMatrix();
205 }
206
207 template<typename Scalar, int Dim, typename OtherDerived>
208 inline static const MatrixBase<OtherDerived>& toRotationMatrix(const MatrixBase<OtherDerived>& mat)
209 {
210   EIGEN_STATIC_ASSERT(OtherDerived::RowsAtCompileTime==Dim && OtherDerived::ColsAtCompileTime==Dim,
211     YOU_MADE_A_PROGRAMMING_MISTAKE)
212   return mat;
213 }
214
215 } // end namespace internal
216
217 #endif // EIGEN_ROTATIONBASE_H