00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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
00152
00153 if (Zero(refVec.GetZ()))
00154 {
00155 anguloY = 0.0;
00156 this->MakeIdentity();
00157 vetTemp = refVec;
00158 }
00159 else
00160 {
00161
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;
00170 }
00171
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
00179 tTemp.MakeXRotation(radians);
00180 (*this) = tTemp * (*this);
00181
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 }