Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

matrix.h

Go to the documentation of this file.
00001 /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*-
00002 
00003    this file is part of rcssserver3D
00004    Fri May 9 2003
00005    Copyright (C) 2002,2003 Koblenz University
00006    Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group
00007    $Id: matrix.h,v 1.7 2004/04/15 10:03:03 rollmark Exp $
00008 
00009    This program is free software; you can redistribute it and/or modify
00010    it under the terms of the GNU General Public License as published by
00011    the Free Software Foundation; version 2 of the License.
00012 
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017 
00018    You should have received a copy of the GNU General Public License
00019    along with this program; if not, write to the Free Software
00020    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00021 */
00022 #ifndef SALT_MATRIX_H
00023 #define SALT_MATRIX_H
00024 
00025 // #ifdef HAVE_CONFIG_H
00026 // #include <config.h>
00027 // #endif
00028 
00029 #include "defines.h"
00030 #include "vector.h"
00031 #include <memory.h>
00032 
00033 namespace salt
00034 {
00035 #if 0
00036 }
00037 #endif
00038 
00042 class Matrix
00043 {
00044 public:
00046     float m[16];
00047 
00049     f_inline Matrix(){}
00050 
00052     f_inline Matrix(float *newMatrix)   {       memcpy(m, newMatrix,    sizeof(float)*16);      }
00053 
00055     f_inline Matrix(const Matrix &newMatrix)    {       memcpy(m, newMatrix.m,  sizeof(float)*16);      }
00056 
00058     f_inline Matrix(Matrix *newMatrix)                  {       memcpy(m, newMatrix->m, sizeof(float)*16);      }
00059 
00061     f_inline Matrix(float m00, float m01, float m02, float m03,
00062                     float m10, float m11, float m12, float m13,
00063                     float m20, float m21, float m22, float m23,
00064                     float m30, float m31, float m32, float m33);
00065 
00067     f_inline void Identity()                    {       memcpy(m, mIdentity,    sizeof(float)*16);      }
00068 
00070     static float* GetIdentity() { return mIdentity; }
00071 
00073     f_inline void RotationX(float inAngle);
00074 
00076     f_inline void RotationY(float inAngle);
00077 
00079     f_inline void RotationZ(float inAngle);
00080 
00082     f_inline void Translation(const Vector3f &inVector);
00083 
00085     f_inline void Scale(const Vector3f & inVector);
00086 
00090     void LookAt(const Vector3f & inEye, const Vector3f & inDirection, const Vector3f & inUp);
00091 
00093     void        Dump() const;
00094 
00096     f_inline void       Set(float m00, float m01, float m02, float m03,
00097                             float m10, float m11, float m12, float m13,
00098                             float m20, float m21, float m22, float m23,
00099                             float m30, float m31, float m32, float m33);
00100 
00102     f_inline const Matrix &     RotateX(float inAngle);
00103 
00105     f_inline const Matrix &     RotateY(float inAngle);
00106 
00108     f_inline const Matrix &     RotateZ(float inAngle);
00109 
00111     f_inline const Matrix &     Translate(const Vector3f & inVector);
00112 
00114     f_inline const Vector3f &   Right() const           { return *(const Vector3f*) &El(0, 0); }
00115 
00117     f_inline Vector3f & Right()                         { return *(Vector3f*)  &El(0, 0); }
00118 
00120     f_inline const Vector3f &   Up() const                      { return *(const Vector3f*) &El(0, 1); }
00121 
00123     f_inline Vector3f & Up()                            { return *(Vector3f*)  &El(0, 1); }
00124 
00126     f_inline const Vector3f &   Forward() const         { return *(const Vector3f*) &El(0, 2); }
00127 
00129     f_inline Vector3f & Forward()                       { return *(Vector3f*)  &El(0, 2); }
00130 
00132     f_inline const Vector3f &   Pos() const                     { return *(const Vector3f*) &El(0, 3); }
00133 
00135     f_inline Vector3f & Pos()                           { return *(Vector3f*)  &El(0, 3); }
00136 
00138     bool        IsEqual(const Matrix& matrix) const;
00139 
00141     f_inline void               InvertRotationMatrix();
00142 
00144     f_inline Vector3f   Transform(const Vector3f & inVector) const;
00145 
00147     f_inline Vector3f   Rotate(const Vector3f & inVector) const;
00148 
00150     f_inline Vector3f   InverseRotate(const Vector3f & inVector) const;
00151     // special lighting matrices
00152 
00154     void CalcAttenuationNoRotation(const Vector3f &pos, float radius);
00155 
00157     void CalcAttenuationWithRotation(const Matrix &lightWorldMatrix, float radius);
00158 
00160     void CalcInfiniteProjection(float width, float height, float fov, float zNear);
00161 
00163     void CalcInfiniteFrustum(float left, float right, float bottom, float top, float zNear);
00164 
00166     void CalcSpotLight(const Matrix &lightWorldTransform, float fov, float width, float height, float zNear);
00167 
00168     // Operators
00169 
00171     f_inline const Matrix       operator*(const Matrix &inRHS) const;
00172 
00174     f_inline const Matrix &     operator*=(const Matrix &inRHS);
00175 
00177     f_inline const Vector3f     operator*(const Vector3f &inRHS) const;
00178 
00180     f_inline const Vector3f     operator*(const Vector2f &inRHS) const;
00181 
00182     // Element access operators
00183 
00185     f_inline float& operator() (int inRow, int inColumn) {      return El(inRow, inColumn);     }
00186 
00188     f_inline const float& operator() (int inRow, int inColumn) const {  return El(inRow, inColumn);     }
00189 
00190 protected:
00192     f_inline float& El(int inRow, int inColumn) {       return m[inColumn*4 + inRow];   }
00193 
00195     f_inline const float& El(int inRow, int inColumn) const {   return m[inColumn*4 + inRow];   }
00196 
00197 private:
00199     static float mIdentity[16];
00200 };
00201 
00202 f_inline Matrix::Matrix(float m00, float m01, float m02, float m03,
00203                         float m10, float m11, float m12, float m13,
00204                         float m20, float m21, float m22, float m23,
00205                         float m30, float m31, float m32, float m33)
00206 {
00207     m[0] = m00; m[4] = m01;     m[8] = m02;     m[12] = m03;
00208     m[1] = m10; m[5] = m11;     m[9] = m12;     m[13] = m13;
00209     m[2] = m20; m[6] = m21;     m[10]= m22;     m[14] = m23;
00210     m[3] = m30; m[7] = m31;     m[11]= m32;     m[15] = m33;
00211 }
00212 
00213 f_inline void Matrix::RotationX(float inAngle)
00214 {
00215     float c=gCos(inAngle), s=gSin(inAngle);
00216 
00217     // Create X-Rotation matrix
00218     Identity();
00219     El(1, 1) = c;
00220     El(2, 1) = s;
00221     El(1, 2) = -s;
00222     El(2, 2) = c;
00223 }
00224 
00225 f_inline void Matrix::RotationY(float inAngle)
00226 {
00227     float c=gCos(inAngle), s=gSin(inAngle);
00228 
00229     // Create Y-Rotation matrix
00230     Identity();
00231     El(0, 0) = c;
00232     El(2, 0) = -s;
00233     El(0, 2) = s;
00234     El(2, 2) = c;
00235 }
00236 
00237 f_inline void Matrix::RotationZ(float inAngle)
00238 {
00239     float c=gCos(inAngle), s=gSin(inAngle);
00240 
00241     // Create Z-Rotation matrix
00242     Identity();
00243     El(0, 0) = c;
00244     El(1, 0) = s;
00245     El(0, 1) = -s;
00246     El(1, 1) = c;
00247 }
00248 
00249 f_inline void Matrix::Translation(const Vector3f & inVector)
00250 {
00251     // Create translation matrix
00252     Identity();
00253     El(0, 3) = inVector.x();
00254     El(1, 3) = inVector.y();
00255     El(2, 3) = inVector.z();
00256 }
00257 
00258 f_inline void Matrix::Scale(const Vector3f & inVector)
00259 {
00260     // Create translation matrix
00261     Identity();
00262     El(0, 0) = inVector.x();
00263     El(1, 1) = inVector.y();
00264     El(2, 2) = inVector.z();
00265 }
00266 
00267 f_inline void Matrix::Set(float m00, float m01, float m02, float m03,
00268                           float m10, float m11, float m12, float m13,
00269                           float m20, float m21, float m22, float m23,
00270                           float m30, float m31, float m32, float m33)
00271 {
00272     m[0] = m00; m[4] = m01;     m[8] = m02;     m[12] = m03;
00273     m[1] = m10; m[5] = m11;     m[9] = m12;     m[13] = m13;
00274     m[2] = m20; m[6] = m21;     m[10]= m22;     m[14] = m23;
00275     m[3] = m30; m[7] = m31;     m[11]= m32;     m[15] = m33;
00276 }
00277 
00278 
00279 // 'multiplies' the current matrix by a x-rotation matrix
00280 f_inline const Matrix & Matrix::RotateX(float inAngle)
00281 {
00282     float c=gCos(inAngle), s=gSin(inAngle);
00283 
00284     // calculate the changed values
00285     float m01 = c*El(0,1) + s*El(0,2);
00286     float m11 = c*El(1,1) + s*El(1,2);
00287     float m21 = c*El(2,1) + s*El(2,2);
00288     float m31 = c*El(3,1) + s*El(3,2);
00289     float m02 =-s*El(0,1) + c*El(0,2);
00290     float m12 =-s*El(1,1) + c*El(1,2);
00291     float m22 =-s*El(2,1) + c*El(2,2);
00292     float m32 =-s*El(3,1) + c*El(3,2);
00293 
00294     // transfer them to the matrix
00295     El(0,1) = m01;
00296     El(1,1) = m11;
00297     El(2,1) = m21;
00298     El(3,1) = m31;
00299     El(0,2) = m02;
00300     El(1,2) = m12;
00301     El(2,2) = m22;
00302     El(3,2) = m32;
00303 
00304     return (*this);
00305 }
00306 
00307 // 'multiplies' the current matrix by a y-rotation matrix
00308 f_inline const Matrix & Matrix::RotateY(float inAngle)
00309 {
00310     float c=gCos(inAngle), s=gSin(inAngle);
00311 
00312     // calculate the changed values
00313     float m00 = c*El(0,0) - s*El(0,2);
00314     float m10 = c*El(1,0) - s*El(1,2);
00315     float m20 = c*El(2,0) - s*El(2,2);
00316     float m30 = c*El(3,0) - s*El(3,2);
00317     float m02 = s*El(0,0) + c*El(0,2);
00318     float m12 = s*El(1,0) + c*El(1,2);
00319     float m22 = s*El(2,0) + c*El(2,2);
00320     float m32 = s*El(3,0) + c*El(3,2);
00321 
00322     // transfer them to the matrix
00323     El(0,0) = m00;
00324     El(1,0) = m10;
00325     El(2,0) = m20;
00326     El(3,0) = m30;
00327     El(0,2) = m02;
00328     El(1,2) = m12;
00329     El(2,2) = m22;
00330     El(3,2) = m32;
00331 
00332     return (*this);
00333 }
00334 
00335 // 'multiplies' the current matrix by a z-rotation matrix
00336 f_inline const Matrix & Matrix::RotateZ(float inAngle)
00337 {
00338     float c=gCos(inAngle), s=gSin(inAngle);
00339 
00340     // calculate the changed values
00341     float m00 = c*El(0,0) + s*El(0,1);
00342     float m10 = c*El(1,0) + s*El(1,1);
00343     float m20 = c*El(2,0) + s*El(2,1);
00344     float m30 = c*El(3,0) + s*El(3,1);
00345     float m01 =-s*El(0,0) + c*El(0,1);
00346     float m11 =-s*El(1,0) + c*El(1,1);
00347     float m21 =-s*El(2,0) + c*El(2,1);
00348     float m31 =-s*El(3,0) + c*El(3,1);
00349 
00350     // transfer them to the matrix
00351     El(0,0) = m00;
00352     El(1,0) = m10;
00353     El(2,0) = m20;
00354     El(3,0) = m30;
00355     El(0,1) = m01;
00356     El(1,1) = m11;
00357     El(2,1) = m21;
00358     El(3,1) = m31;
00359 
00360     return (*this);
00361 }
00362 
00363 // 'multiplies' the current matrix by a translation matrix (last row is interpreted as 0 0 0 1)
00364 f_inline const Matrix & Matrix::Translate(const Vector3f & inVector)
00365 {
00366     float x = inVector.x(), y = inVector.y(), z = inVector.z();
00367 
00368     // transfer them to the matrix
00369     El(0,3) = x*m[0] + y*m[4] + z*m[8] + m[12];
00370     El(1,3) = x*m[1] + y*m[5] + z*m[9] + m[13];
00371     El(2,3) = x*m[2] + y*m[6] + z*m[10]+ m[14];
00372 
00373     return (*this);
00374 }
00375 
00376 f_inline void Matrix::InvertRotationMatrix()
00377 {
00378     // transpose the rotation part
00379     gSwap(El(0, 1), El(1, 0));
00380     gSwap(El(0, 2), El(2, 0));
00381     gSwap(El(1, 2), El(2, 1));
00382 
00383     // Set new position
00384     Pos() = -Rotate(Pos());
00385 }
00386 
00387 // full matrix application (last row is interpreted as 0 0 0 1)
00388 f_inline Vector3f Matrix::Transform(const Vector3f & inVector) const
00389 {
00390     float x = inVector.x(), y = inVector.y(), z = inVector.z();
00391 
00392     return Vector3f(    x*m[0] + y*m[4] + z*m[8] + m[12],
00393                         x*m[1] + y*m[5] + z*m[9] + m[13],
00394                         x*m[2] + y*m[6] + z*m[10]+ m[14]);
00395 }
00396 
00397 // this only applies the rotation part of the matrix
00398 f_inline Vector3f Matrix::Rotate(const Vector3f & inVector) const
00399 {
00400     float x = inVector.x(), y = inVector.y(), z = inVector.z();
00401     return Vector3f(    x*m[0] + y*m[4] + z*m[8],
00402                         x*m[1] + y*m[5] + z*m[9],
00403                         x*m[2] + y*m[6] + z*m[10]);
00404 }
00405 
00406 // this applies the transpose of the rotation part of the matrix (inverse rotation)
00407 f_inline Vector3f Matrix::InverseRotate(const Vector3f & inVector) const
00408 {
00409     float x = inVector.x(), y = inVector.y(), z = inVector.z();
00410     return Vector3f(x*m[0] + y*m[1] + z*m[2],
00411                     x*m[4] + y*m[5] + z*m[6],
00412                     x*m[8] + y*m[9] + z*m[10]);
00413 }
00414 
00415 // Multiply this Matrix with another Matrix
00416 f_inline const Matrix Matrix::operator*(const Matrix & inRHS) const
00417 {
00418     Matrix r;
00419 
00420     for (int i=0; i<4; i++)
00421         for (int j=0; j<4; j++)
00422             r(i,j) = El(i,0)*inRHS(0,j)+El(i,1)*inRHS(1,j)+El(i,2)*inRHS(2,j)+El(i,3)*inRHS(3,j);
00423 
00424     return r;
00425 }
00426 
00427 // Multiply a Vector3f with this Matrix
00428 f_inline const Vector3f Matrix::operator*(const Vector3f &inRHS) const
00429 {
00430     float x = inRHS.x(), y = inRHS.y(), z = inRHS.z();
00431 
00432     return Vector3f(x*m[0] + y*m[4] + z*m[8] + m[12],
00433                     x*m[1] + y*m[5] + z*m[9] + m[13],
00434                     x*m[2] + y*m[6] + z*m[10]+ m[14]);
00435 }
00436 
00437 // Multiply a Vector2f with this Matrix
00438 f_inline const Vector3f Matrix::operator*(const Vector2f &inRHS) const
00439 {
00440     float x = inRHS.x(), y = inRHS.y();
00441 
00442     return Vector3f(x*m[0] + y*m[4] + m[12],
00443                     x*m[1] + y*m[5] + m[13],
00444                     x*m[2] + y*m[6] + m[14]);
00445 }
00446 
00447 f_inline const Matrix & Matrix::operator*=(const Matrix &inRHS)
00448 {
00449     *this = *this * inRHS;
00450     return *this;
00451 }
00452 
00453 } //namespace salt
00454 
00455 #endif // SALT_MATRIX_H

Generated on Thu Apr 6 15:25:38 2006 for rcssserver3d by  doxygen 1.4.4