Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members   Examples  

Transform.H

Go to the documentation of this file.
00001 
00014 #ifndef _TRANSFORM_H
00015 #define _TRANSFORM_H
00016 
00017 
00018 #include <Matrix.H>
00019 
00020 
00021 namespace xchen
00022 {
00024   class Transform {
00025       enum { TRANSFORM_POINT, TRANSFORM_VECTOR, INV_TRANSFORM_POINT, INV_TRANSFORM_VECTOR, TRANSFORM_NORMAL };
00026   public:
00027       Transform();
00028 
00029       void SetIdentity() { M.SetIdentity(); validCache() = false; }
00030 
00031       void ShearXY(double a, double b);
00032       void ShearXZ(double a, double b);
00033       void ShearYZ(double a, double b);
00034 
00035       void Translate(double x, double y, double z);
00036       void Translate(const dVector3D& v)                                  { Translate(v[0], v[1], v[2]); }
00037       void TranslateX(double x)                                           { Translate(x, 0, 0); }
00038       void TranslateY(double y)                                           { Translate(0, y, 0); }
00039       void TranslateZ(double z)                                           { Translate(0, 0, z); }
00040 
00041       void Rotate(double dx, double dy, double dz, double angle);
00042       void RotateX(double x);
00043       void RotateY(double y);
00044       void RotateZ(double z);
00045 
00046       void Rotate2Frame(const class Frame&);
00047     
00048       void Scale(double sx, double sy, double sz);
00049       void ScaleX(double x)                                               { Scale(x, 1, 1); }
00050       void ScaleY(double y)                                               { Scale(1, y, 1); }
00051       void ScaleZ(double z)                                               { Scale(1, 1, z); }
00052 
00053       void Rotate(const dVector3D& v, double angle)                       { Rotate(v[0], v[1], v[2], angle); }
00054       void Scale(const dVector3D& v)                                      { Scale(v[0], v[1], v[2]); }
00055 
00056       void RotateTo(const dVector3D& from, const dVector3D& to)           { Rotate(from^to, from.Angle(to)); }
00057 
00058       void GetGLMatrix(double* m) const                                   { M.GetColumnMajorData(m); }
00059       double* GetGLMatrix() const                                         { double *m = new double[16]; GetGLMatrix(m); return m; }
00060       const HMatrix& GetMatrix() const                                    { return M; }
00061     
00062       double GetMeasureScale() const                                      { return measure_scale; }
00063 
00064       dVector4D operator()(dVector4D const& p) const                      { return M * p; }
00065       dVector4D operator*(dVector4D const& p) const                       { return M * p; }
00066 
00067       //      Transform& operator*(Transform const& rhs)                          { M *= rhs.M; return *this; }
00068 
00069       void TransformPoint(dVector3D& p) const                             { transform(p, TRANSFORM_POINT); }
00070       void TransformVector(dVector3D& v) const                            { transform(v, TRANSFORM_VECTOR); }
00071       void TransformNormal(dVector3D& n) const                            { transform(n, TRANSFORM_NORMAL); }
00072 
00073       void InvTransformPoint(dVector3D& p) const                          { transform(p, INV_TRANSFORM_POINT); }
00074       void InvTransformVector(dVector3D& v) const                         { transform(v, INV_TRANSFORM_VECTOR); }
00075 
00076       friend ostream& operator << (ostream& os, const Transform& trans);
00077 
00078   private:
00079       void transform(dVector3D& p, int trans) const;
00080 
00081       HMatrix M, invM, itM;
00082       bool valid_cache;
00083       bool& validCache() const                                             { return (bool&) valid_cache; }
00084 
00085       double measure_scale;
00086 
00087       HMatrix m;                                                           // tempary working matrix.
00088   };
00089 
00090 
00091 
00092   inline void Transform :: transform(dVector3D& p, int trans) const
00093   {
00094     dVector4D p2(p);
00095 
00096     if(trans == TRANSFORM_POINT || trans == INV_TRANSFORM_POINT)
00097       p2[3] = 1.0;
00098 
00099     const HMatrix* m = &M;
00100 
00101     if( (trans == TRANSFORM_NORMAL || trans == INV_TRANSFORM_POINT || trans == INV_TRANSFORM_VECTOR) &&
00102         (! validCache() ) )
00103     {
00104       Transform* This = (Transform*) this;
00105       M.GetInverse(&This->invM);
00106       M.GetTranspose(&This->itM);
00107       This->validCache() = true;
00108     }
00109 
00110     if(trans == TRANSFORM_NORMAL) 
00111       m = &itM;
00112     else if(trans == INV_TRANSFORM_POINT || trans == INV_TRANSFORM_VECTOR)
00113       m = &invM;
00114   
00115     dVector4D p3 = (*m) * p2;
00116     assert( approx_eq(p3[3], p2[3]) );
00117 
00118     p = dVector3D(p3);
00119   }
00120 
00121   inline Transform :: Transform() : valid_cache(false), measure_scale(1.0)
00122   {
00123     M.SetIdentity();
00124   }
00125 
00126 
00127 
00128 
00129 
00130   inline Transform scale(double s)
00131   {
00132     Transform tr; tr.Scale(s,s,s); return tr;
00133   }
00134 
00135   inline Transform rotateX(double ang) 
00136   {
00137     Transform tr; tr.RotateX(ang); return tr;
00138   }
00139 
00140   inline Transform rotateY(double ang) 
00141   {
00142     Transform tr; tr.RotateY(ang); return tr;
00143   }
00144 
00145   inline Transform rotateZ(double ang) 
00146   {
00147     Transform tr; tr.RotateZ(ang); return tr;
00148   }
00149 
00150   inline Transform tX(double d) 
00151   {
00152     Transform tr; tr.TranslateX(d); return tr;
00153   }
00154   inline Transform tY(double d) 
00155   {
00156     Transform tr; tr.TranslateY(d); return tr;
00157   }
00158   inline Transform tZ(double d) 
00159   {
00160     Transform tr; tr.TranslateZ(d); return tr;
00161   }
00162 
00163 
00164 #define sc scale
00165 #define rX rotateX
00166 #define rY rotateY
00167 #define rZ rotateZ
00168 
00169 
00170 }//end namespace xchen
00171 
00172 
00173 #endif

Generated on Wed Apr 7 21:40:49 2004 by doxygen1.2.18