Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 #ifndef __SP_SCENE_TRANSFORMATION_3D_H__
00009 #define __SP_SCENE_TRANSFORMATION_3D_H__
00010 
00011 
00012 #include "Base/spStandard.hpp"
00013 #include "Base/spDimensionVector3D.hpp"
00014 #include "Base/spDimensionMatrix4.hpp"
00015 #include "Base/spDimensionQuaternion.hpp"
00016 
00017 
00018 namespace sp
00019 {
00020 namespace scene
00021 {
00022 
00023 
00034 template <typename T> class Transformation3D
00035 {
00036     
00037     public:
00038         
00039         Transformation3D() :
00040             Scale_      (T(1)),
00041             HasChanged_ (true)
00042         {
00043         }
00044         Transformation3D(const dim::matrix4<T> &Matrix) :
00045             Position_   (Matrix.getPosition()       ),
00046             Rotation_   (Matrix.getRotationMatrix() ),
00047             Scale_      (Matrix.getScale()          ),
00048             Matrix_     (Matrix                     ),
00049             HasChanged_ (false                      )
00050         {
00051         }
00052         Transformation3D(
00053             const dim::vector3d<T> &Position, const dim::quaternion4<T> &Rotation, const dim::vector3d<T> &Scale = T(1)) :
00054             Position_   (Position   ),
00055             Rotation_   (Rotation   ),
00056             Scale_      (Scale      ),
00057             HasChanged_ (true       )
00058         {
00059         }
00060         Transformation3D(const Transformation3D<T> &Other) :
00061             Position_   (Other.Position_    ),
00062             Rotation_   (Other.Rotation_    ),
00063             Scale_      (Other.Scale_       ),
00064             Matrix_     (Other.Matrix_      ),
00065             HasChanged_ (Other.HasChanged_  )
00066         {
00067         }
00068         ~Transformation3D()
00069         {
00070         }
00071         
00072         
00073         
00074         Transformation3D<T>& operator = (const Transformation3D<T> &Other)
00075         {
00076             Position_   = Other.Position_;
00077             Rotation_   = Other.Rotation_;
00078             Scale_      = Other.Scale_;
00079             Matrix_     = Other.Matrix_;
00080             HasChanged_ = Other.HasChanged_;
00081             return *this;
00082         }
00083         
00084         Transformation3D<T>& operator *= (const Transformation3D<T> &Other)
00085         {
00086             operator = (getMatrix() * Other.getMatrix());
00087             return *this;
00088         }
00089         
00090         Transformation3D<T> operator * (const Transformation3D<T> &Other) const
00091         {
00092             Transformation3D<T> Temp(*this);
00093             Temp *= Other;
00094             return Temp;
00095         }
00096         
00097         
00098         
00100         const dim::matrix4<T>& getMatrix() const
00101         {
00102             if (HasChanged_)
00103             {
00104                 Matrix_.reset(Position_);
00105                 Matrix_ *= Rotation_.getMatrixTransposed();
00106                 Matrix_.scale(Scale_);
00107                 HasChanged_ = false;
00108             }
00109             return Matrix_;
00110         }
00111         
00113         Transformation3D<T> getInverse() const
00114         {
00115             dim::matrix4<T> Mat;
00116             getMatrix(Mat);
00117             Mat.setInverse();
00118             return Transformation3D<T>(Mat);
00119         }
00120         
00122         void interpolate(const Transformation3D<T> &From, const Transformation3D<T> &To, const T &Interpolation)
00123         {
00124             math::Lerp(Position_,   From.Position_, To.Position_,   Interpolation);
00125             math::Lerp(Scale_,      From.Scale_,    To.Scale_,      Interpolation);
00126             Rotation_.slerp(From.Rotation_, To.Rotation_, Interpolation);
00127             HasChanged_ = true;
00128         }
00129         
00131         void move(const dim::vector3d<T> &Direction)
00132         {
00133             Position_ += (Rotation_.getMatrixTransposed() * Direction);
00134             HasChanged_ = true;
00135         }
00137         void turn(const dim::vector3d<T> &Rotation)
00138         {
00139             dim::matrix4<T> Mat;
00140             Mat.setRotation(Rotation);
00141             Rotation_ *= dim::quaternion4<T>(Mat);
00142             HasChanged_ = true;
00143         }
00144         
00145         
00146         
00148         inline void setPosition(const dim::vector3d<T> &Position)
00149         {
00150             Position_ = Position;
00151             HasChanged_ = true;
00152         }
00154         inline const dim::vector3d<T>& getPosition() const
00155         {
00156             return Position_;
00157         }
00158         
00160         inline void setRotation(const dim::quaternion4<T> &Rotation)
00161         {
00162             Rotation_ = Rotation;
00163             HasChanged_ = true;
00164         }
00166         inline const dim::quaternion4<T>& getRotation() const
00167         {
00168             return Rotation_;
00169         }
00171         inline dim::matrix4<T> getRotationMatrix() const
00172         {
00173             return Rotation_.getMatrixTransposed();
00174         }
00175         
00177         inline void setScale(const dim::vector3d<T> &Scale)
00178         {
00179             Scale_ = Scale;
00180             HasChanged_ = true;
00181         }
00183         inline const dim::vector3d<T>& getScale() const
00184         {
00185             return Scale_;
00186         }
00187         
00189         inline void translate(const dim::vector3d<T> &Direction)
00190         {
00191             Position_ += Direction;
00192             HasChanged_ = true;
00193         }
00195         inline void transform(const dim::vector3d<T> &Size)
00196         {
00197             Scale_ += Size;
00198             HasChanged_ = true;
00199         }
00200         
00202         inline void getMatrix(dim::matrix4<T> &Matrix) const
00203         {
00204             Matrix *= getMatrix();
00205         }
00206         
00211         inline dim::matrix4<T> getInverseMatrix() const
00212         {
00213             return getMatrix().getInverse();
00214         }
00215         
00220         inline void setMatrixDirect(const dim::matrix4<T> &Matrix)
00221         {
00222             Matrix_ = Matrix;
00223         }
00225         inline dim::matrix4<T>& getMatrixDirect()
00226         {
00227             return Matrix_;
00228         }
00230         inline const dim::matrix4<T>& getMatrixDirect() const
00231         {
00232             return Matrix_;
00233         }
00234         
00236         inline dim::vector3df getDirection(const dim::vector3df &upVector = dim::vector3df(0, 0, 1)) const
00237         {
00238             return Rotation_.getInverse() * upVector;
00239         }
00240         
00241     private:
00242         
00243         
00244         
00245         dim::vector3d<T> Position_;
00246         dim::quaternion4<T> Rotation_;
00247         dim::vector3d<T> Scale_;
00248         
00249         mutable dim::matrix4<T> Matrix_;
00250         mutable bool HasChanged_;
00251         
00252 };
00253 
00254 
00255 typedef Transformation3D<f32> Transformation;
00256 
00257 
00258 } 
00259 
00260 } 
00261 
00262 
00263 #endif
00264 
00265 
00266 
00267