Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

vptransform.cpp

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 // ChangeLog
00006 // Sep 15/2004 - Bruno de Oliveira Schneider
00007 // - File created.
00008 
00009 // Internal matrix element organization reference
00010 //             [ matrix[0] matrix[4] matrix[8]  matrix[12] ]
00011 // Transform = [ matrix[1] matrix[5] matrix[9]  matrix[13] ]
00012 //             [ matrix[2] matrix[6] matrix[10] matrix[14] ]
00013 //             [ matrix[3] matrix[7] matrix[11] matrix[15] ]
00014 
00015 #include "vptransform.h"
00016 
00017 #ifdef VP_OGL
00018 #include <GL/gl.h>
00019 #endif
00020 
00021 using namespace std;
00022 
00023 VPTransform::VPTransform()
00024 {
00025 }
00026 
00027 VPTransform::VPTransform(const VPTransform &trans)
00028 {
00029     for (int i=0; i<16; ++i)
00030         matrix[i] = trans.matrix[i];
00031 }
00032 
00033 void VPTransform::MakeIdentity()
00034 {
00035     for (int i=0; i<16; ++i)
00036         matrix[i] = 0.0;
00037     matrix[0] = matrix[5] = matrix[10] = matrix[15] = 1.0;
00038 }
00039 
00040 void VPTransform::MakeTranslation(const VPPoint4D& translationVector)
00041 {
00042     MakeIdentity();
00043     matrix[12] = translationVector.GetX();
00044     matrix[13] = translationVector.GetY();
00045     matrix[14] = translationVector.GetZ();
00046 }
00047 
00048 void VPTransform::MakeXRotation(double radians)
00049 {
00050     MakeIdentity();
00051     matrix[5] =   cos(radians);
00052     matrix[9] =  -sin(radians);
00053     matrix[6] =   sin(radians);
00054     matrix[10] =  cos(radians);
00055 }
00056 
00057 void VPTransform::MakeYRotation(double radians)
00058 {
00059     MakeIdentity();
00060     matrix[0] =   cos(radians);
00061     matrix[8] =   sin(radians);
00062     matrix[2] =  -sin(radians);
00063     matrix[10] =  cos(radians);
00064 }
00065 
00066 void VPTransform::MakeZRotation(double radians)
00067 {
00068     MakeIdentity();
00069     matrix[0] =  cos(radians);
00070     matrix[4] = -sin(radians);
00071     matrix[1] =  sin(radians);
00072     matrix[5] =  cos(radians);
00073 }
00074 
00075 void VPTransform::MakeScale(double sX, double sY, double sZ)
00076 {
00077     MakeIdentity();
00078     matrix[0] =  sX;
00079     matrix[5] =  sY;
00080     matrix[10] = sZ;
00081 }
00082 
00083 void VPTransform::MakeShear(double shX, double shY)
00084 {
00085     MakeIdentity();
00086     matrix[8] = shX;
00087     matrix[9] = shY;
00088 }
00089 
00090 VPPoint4D VPTransform::operator *(const VPPoint4D& point) const
00091 {
00092     VPPoint4D result;
00093 
00094     return VPPoint4D(  matrix[0]*point.GetX()  + matrix[4]*point.GetY()
00095                      + matrix[8]*point.GetZ()  + matrix[12]*point.GetW(),
00096                        matrix[1]*point.GetX()  + matrix[5]*point.GetY()
00097                      + matrix[9]*point.GetZ()  + matrix[13]*point.GetW(),
00098                        matrix[2]*point.GetX()  + matrix[6]*point.GetY()
00099                      + matrix[10]*point.GetZ() + matrix[14]*point.GetW(),
00100                        matrix[3]*point.GetX()  + matrix[7]*point.GetY()
00101                      + matrix[11]*point.GetZ() + matrix[15]*point.GetW());
00102 }
00103 
00104 VPTransform VPTransform::operator*(const VPTransform &t) const
00105 {
00106     VPTransform resultado;
00107     for (int i=0; i < 16; ++i)
00108         resultado.matrix[i] =
00109               matrix[i%4]    *t.matrix[i/4*4]  +matrix[(i%4)+4] *t.matrix[i/4*4+1]
00110             + matrix[(i%4)+8]*t.matrix[i/4*4+2]+matrix[(i%4)+12]*t.matrix[i/4*4+3];
00111     return resultado;
00112 }
00113 
00114 VPTransform& VPTransform::operator=(const VPTransform& t)
00115 {
00116     for (int i=0; i < 16; ++i)
00117         matrix[i] = t.matrix[i];
00118     return *this;
00119 }
00120 
00121 void VPTransform::ApplyTo(VPPoint4D* ptPoint) const
00122 {
00123     ptPoint->SetXYZW(
00124         matrix[0]*ptPoint->GetX()
00125             + matrix[4]*ptPoint->GetY()
00126             + matrix[8]*ptPoint->GetZ()
00127             + matrix[12]*ptPoint->GetW(),
00128         matrix[1]*ptPoint->GetX()
00129             + matrix[5]*ptPoint->GetY()
00130             + matrix[9]*ptPoint->GetZ()
00131             + matrix[13]*ptPoint->GetW(),
00132         matrix[2]*ptPoint->GetX()
00133             + matrix[6]*ptPoint->GetY()
00134             + matrix[10]*ptPoint->GetZ()
00135             + matrix[14]*ptPoint->GetW(),
00136         matrix[3]*ptPoint->GetX()
00137             + matrix[7]*ptPoint->GetY()
00138             + matrix[11]*ptPoint->GetZ()
00139             + matrix[15]*ptPoint->GetW()
00140         );
00141 }
00142 
00143 void VPTransform::MakeRotation(const VPPoint4D& refVec, const float radians)
00144 {
00145     VPPoint4D projEmY;
00146     VPPoint4D vetTemp;
00147     VPTransform tTemp;
00148     double anguloY;
00149     double anguloZ;
00150 
00151     //Decompor refVec
00152     //Angulo em Y (para levar o vetor ao plano XY)
00153     if (Zero(refVec.GetZ()))
00154     {
00155         anguloY = 0.0;
00156         this->MakeIdentity();
00157         vetTemp = refVec;
00158     }
00159     else
00160     {
00161         // se o vetor nao esta no plano XY...
00162         projEmY.SetXYZW(refVec.GetX(), 0, refVec.GetZ(), 0);
00163         projEmY.Normalize();
00164         if (refVec.GetZ() < 0)
00165             anguloY = -(projEmY.AngleTo(VPPoint4D(1,0,0,0)));
00166         else
00167             anguloY = projEmY.AngleTo(VPPoint4D(1,0,0,0));
00168         this->MakeYRotation(anguloY);
00169         vetTemp = (*this) * refVec; //refVec no plano XY
00170     }
00171     //Angulo em Z (para levar o vetor ao X)
00172     if (vetTemp.GetY() < 0)
00173         anguloZ = vetTemp.AngleTo(VPPoint4D(1,0,0,0));
00174     else
00175         anguloZ = -(vetTemp.AngleTo(VPPoint4D(1,0,0,0)));
00176     tTemp.MakeZRotation(anguloZ);
00177     (*this) = tTemp * (*this);
00178     //Rodar
00179     tTemp.MakeXRotation(radians);
00180     (*this) = tTemp * (*this);
00181     //voltar
00182     tTemp.MakeZRotation(-anguloZ);
00183     (*this) = tTemp * (*this);
00184     tTemp.MakeYRotation(-anguloY);
00185     (*this) = tTemp * (*this);
00186 }
00187 
00188 void VPTransform::MakeRotation(const VPPoint4D& refPoint, const VPPoint4D& refVec,
00189                                const float radians)
00190 {
00191     VPTransform tTemp;
00192 
00193     this->MakeTranslation(-refPoint);
00194     tTemp.MakeRotation(refVec, radians);
00195     (*this) = tTemp * (*this);
00196     tTemp.MakeTranslation(refPoint);
00197     (*this) = tTemp * (*this);
00198 }
00199 
00200 void VPTransform::GetVectorX(VPPoint4D* result) const
00201 {
00202     result->SetX(matrix[0]);
00203     result->SetY(matrix[1]);
00204     result->SetZ(matrix[2]);
00205     result->SetW(matrix[3]);
00206 }
00207 
00208 void VPTransform::GetVectorY(VPPoint4D* result) const
00209 {
00210     result->SetX(matrix[4]);
00211     result->SetY(matrix[5]);
00212     result->SetZ(matrix[6]);
00213     result->SetW(matrix[7]);
00214 }
00215 
00216 void VPTransform::GetVectorZ(VPPoint4D* result) const
00217 {
00218     result->SetX(matrix[8]);
00219     result->SetY(matrix[9]);
00220     result->SetZ(matrix[10]);
00221     result->SetW(matrix[11]);
00222 }
00223 
00224 void VPTransform::GetTranslation(VPPoint4D* result) const
00225 {
00226     result->SetX(matrix[12]);
00227     result->SetY(matrix[13]);
00228     result->SetZ(matrix[14]);
00229     result->SetW(matrix[15]);
00230 }
00231 
00232 bool VPTransform::DrawOGL() const
00233 {
00234 #ifdef VP_OGL
00235     bool result = true;
00236     list<const VPSceneNode*>::const_iterator iter;
00237 
00238     glPushMatrix();
00239     glMultMatrixd(matrix);
00240     for (iter = childList.begin(); iter != childList.end(); ++iter)
00241         result = (result && (*iter)->DrawOGL());
00242     glPopMatrix();
00243     return result;
00244 #else
00245     return false;
00246 #endif
00247 }
00248 
00249 ostream& operator<<(ostream& output, const VPTransform& t)
00250 {
00251     int i, j;
00252 
00253     output.setf(ios::showpoint|ios::fixed);
00254     output.precision(6);
00255     for (i=0; i<4; ++i)
00256     {
00257         for (j=0; j<4; ++j)
00258             output << setw(12) << t.matrix[i+j*4] << " ";
00259         output << endl;
00260     }
00261     output.unsetf(ios::showpoint|ios::fixed);
00262     return output;
00263 }

Generated on Tue Sep 6 10:00:07 2005 for VPAT by  doxygen 1.4.4