home *** CD-ROM | disk | FTP | other *** search
/ Cutting-Edge 3D Game Programming with C++ / CE3DC++.ISO / BOOK / CHAP12 / MATRIX3D.CPP < prev    next >
C/C++ Source or Header  |  1996-01-24  |  9KB  |  269 lines

  1. //
  2. // File name: Matrix3D.CPP
  3. //
  4. // Description: The CPP file for the Matrix3D.HPP header file
  5. //
  6. // Author: John De Goes
  7. //
  8. // Project: Cutting Edge 3D Game Programming
  9. //
  10.  
  11. #include "Matrix3D.HPP"
  12.  
  13. // Function designed to set matrix to identity matrix:
  14. void Matrix3D::Initialize ()
  15.    {
  16.    Matrix[0][0] = 1;  Matrix[0][1] = 0;  Matrix[0][2] = 0;  Matrix[0][3] = 0;
  17.    Matrix[1][0] = 0;  Matrix[1][1] = 1;  Matrix[1][2] = 0;  Matrix[1][3] = 0;
  18.    Matrix[2][0] = 0;  Matrix[2][1] = 0;  Matrix[2][2] = 1;  Matrix[2][3] = 0;
  19.    Matrix[3][0] = 0;  Matrix[3][1] = 0;  Matrix[3][2] = 0;  Matrix[3][3] = 1;
  20.    }
  21.  
  22. void Matrix3D::InitMat ( float Mat [ 4 ] [ 4 ] )
  23.    {
  24.    // Initializes a specific matrix to the identity matrix:
  25.    Mat [0][0] = 1;  Mat [0][1] = 0;  Mat [0][2] = 0;  Mat [0][3] = 0;
  26.    Mat [1][0] = 0;  Mat [1][1] = 1;  Mat [1][2] = 0;  Mat [1][3] = 0;
  27.    Mat [2][0] = 0;  Mat [2][1] = 0;  Mat [2][2] = 1;  Mat [2][3] = 0;
  28.    Mat [3][0] = 0;  Mat [3][1] = 0;  Mat [3][2] = 0;  Mat [3][3] = 1;
  29.    }
  30.    
  31. void Matrix3D::MergeMatrix ( float NewMatrix [ 4 ] [ 4 ] )
  32.    {
  33.    // Multiply NewMatirx by Matrix; store result in TempMatrix
  34.    float TempMatrix [ 4 ] [ 4 ];
  35.     for (short unsigned int i = 0; i < 4; i++)
  36.          for (short unsigned int j = 0; j < 4; j++) 
  37.               TempMatrix[i][j] = (Matrix[i][0] * NewMatrix[0][j])
  38.                             + (Matrix[i][1] * NewMatrix[1][j])
  39.                             + (Matrix[i][2] * NewMatrix[2][j])
  40.                             + (Matrix[i][3] * NewMatrix[3][j]);
  41.    // Copy TempMatrix to Matrix:
  42.    for (i = 0; i < 4; i++)
  43.        {
  44.        Matrix[i][0] = TempMatrix[i][0];
  45.        Matrix[i][1] = TempMatrix[i][1];
  46.        Matrix[i][2] = TempMatrix[i][2];
  47.        Matrix[i][3] = TempMatrix[i][3];
  48.        }
  49.    }
  50.  
  51. void Matrix3D::MergeMatrices ( float Dest [ 4 ] [ 4 ], float Source [ 4 ] [ 4 ] )
  52.    {
  53.    // Multiply Source by Dest; store result in Temp:
  54.    float Temp [ 4 ] [ 4 ];
  55.     for ( short unsigned int i = 0; i < 4; i++ )
  56.          for ( short unsigned int j = 0; j < 4; j++ )
  57.            {
  58.               Temp [ i ] [ j ] = ( Source [ i ] [ 0 ] * Dest [ 0 ] [ j ] )
  59.                             + ( Source [ i ] [ 1 ] * Dest [ 1 ] [ j ] )
  60.                             + ( Source [ i ] [ 2 ] * Dest [ 2 ] [ j ] )
  61.                             + ( Source [ i ] [ 3 ] * Dest [ 3 ] [ j ] );
  62.            }
  63.    // Copy Temp to Dest:
  64.    for (i = 0; i < 4; i++)
  65.        {
  66.        Dest [ i ] [ 0 ] = Temp [ i ] [ 0 ];
  67.        Dest [ i ] [ 1 ] = Temp [ i ] [ 1 ];
  68.        Dest [ i ] [ 2 ] = Temp [ i ] [ 2 ];
  69.        Dest [ i ] [ 3 ] = Temp [ i ] [ 3 ];
  70.        }
  71.    }
  72.    
  73. void  Matrix3D::Rotate ( int Xa, int Ya, int Za )
  74.    {
  75.    // Generate 3D rotation matrix:
  76.    Xr = Xa; Yr = Ya; Zr = Za;
  77.    float Rmat [ 4 ] [ 4 ];
  78.    InitMat ( RMatrix );
  79.  
  80.    // Initialize Z rotation matrix - Note: we perform Z
  81.    // rotation first to align the 3D Z axis with the 2D Z axis.
  82.    Rmat[0][0]=COS(Za);  Rmat[0][1]=SIN(Za);  Rmat[0][2]=0;    Rmat[0][3]=0;
  83.    Rmat[1][0]=-SIN(Za); Rmat[1][1]=COS(Za);  Rmat[1][2]=0;    Rmat[1][3]=0;
  84.    Rmat[2][0]=0;        Rmat[2][1]=0;        Rmat[2][2]=1;    Rmat[2][3]=0;
  85.    Rmat[3][0]=0;        Rmat[3][1]=0;        Rmat[3][2]=0;    Rmat[3][3]=1;
  86.  
  87.    // Merge matrix with master matrix:
  88.    MergeMatrices ( RMatrix, Rmat );
  89.  
  90.    // Initialize X rotation matrix:
  91.    Rmat[0][0]=1;  Rmat[0][1]=0;        Rmat[0][2]=0;       Rmat[0][3]=0;
  92.    Rmat[1][0]=0;  Rmat[1][1]=COS(Xa);  Rmat[1][2]=SIN(Xa); Rmat[1][3]=0;
  93.    Rmat[2][0]=0;  Rmat[2][1]=-SIN(Xa); Rmat[2][2]=COS(Xa); Rmat[2][3]=0;
  94.    Rmat[3][0]=0;  Rmat[3][1]=0;        Rmat[3][2]=0;       Rmat[3][3]=1;
  95.  
  96.    // Merge matrix with master matrix:
  97.    MergeMatrices ( RMatrix, Rmat );
  98.  
  99.    // Initialize Y rotation matrix:
  100.    Rmat[0][0]=COS(Ya); Rmat[0][1]=0;   Rmat[0][2]=-SIN(Ya); Rmat[0][3]=0;
  101.    Rmat[1][0]=0;       Rmat[1][1]=1;   Rmat[1][2]=0;        Rmat[1][3]=0;
  102.    Rmat[2][0]=SIN(Ya); Rmat[2][1]=0;   Rmat[2][2]=COS(Ya);  Rmat[2][3]=0;
  103.    Rmat[3][0]=0;       Rmat[3][1]=0;   Rmat[3][2]=0;        Rmat[3][3]=1;
  104.  
  105.    // Merge matrix with master matrix:
  106.    MergeMatrices ( RMatrix, Rmat );
  107.  
  108.    MergeMatrix ( RMatrix );
  109.    }
  110.    
  111. void Matrix3D::Translate ( float Xt, float Yt, float Zt )
  112.    {
  113.    // Create 3D translation matrix:
  114.  
  115.    // Declare translation matrix:
  116.    float Tmat [ 4 ] [ 4 ];
  117.    
  118.    // Save translation values:
  119.    XTrans = Xt; YTrans = Yt; ZTrans = Zt;
  120.    
  121.    // Initialize translation matrix:
  122.    Tmat[0][0]=1;  Tmat[0][1]=0;  Tmat[0][2]=0;  Tmat[0][3]=0;
  123.    Tmat[1][0]=0;  Tmat[1][1]=1;  Tmat[1][2]=0;  Tmat[1][3]=0;
  124.    Tmat[2][0]=0;  Tmat[2][1]=0;  Tmat[2][2]=1;  Tmat[2][3]=0;
  125.    Tmat[3][0]=Xt; Tmat[3][1]=Yt; Tmat[3][2]=Zt; Tmat[3][3]=1;
  126.  
  127.    // Merge matrix with master matrix:
  128.    MergeMatrix ( Tmat );
  129.    }
  130.    
  131. // Function designed to merge scaling matrix with master
  132. // matrix:
  133. void  Matrix3D::Scale ( float Xs, float Ys, float Zs )
  134.    {
  135.    // Create 3D scaling matrix:
  136.    float Smat [ 4 ] [ 4 ];
  137.  
  138.    // Initialize scaling matrix:
  139.    Smat[0][0] = Xs; Smat[0][1] = 0;  Smat[0][2] = 0;  Smat[0][3] = 0;
  140.    Smat[1][0] = 0;  Smat[1][1] = Ys; Smat[1][2] = 0;  Smat[1][3] = 0;
  141.    Smat[2][0] = 0;  Smat[2][1] = 0;  Smat[2][2] = Zs; Smat[2][3] = 0;
  142.    Smat[3][0] = 0;  Smat[3][1] = 0;  Smat[3][2] = 0;  Smat[3][3] = 1;
  143.  
  144.    // Merge matrix with master matrix:
  145.    MergeMatrix ( Smat );
  146.    }
  147.  
  148. void  Matrix3D::Shear ( float Xs, float Ys )
  149.    {
  150.    // Create 3D shearing matrix:
  151.  
  152.    float Smat [ 4 ] [ 4 ];
  153.  
  154.    // Initialize shearing matrix:
  155.    Smat[0][0] = 1;  Smat[0][1] = 0;  Smat[0][2] = Xs;  Smat[0][3] = 0;
  156.    Smat[1][0] = 0;  Smat[1][1] = 1;  Smat[1][2] = Ys;  Smat[1][3] = 0;
  157.    Smat[2][0] = 0;  Smat[2][1] = 0;  Smat[2][2] = 1;   Smat[2][3] = 0;
  158.    Smat[3][0] = 0;  Smat[3][1] = 0;  Smat[3][2] = 0;   Smat[3][3] = 1;
  159.  
  160.    // Merge matrix with master matrix:
  161.    MergeMatrix ( Smat );
  162.    }
  163.  
  164. // Function designed to transform a vertex using the master
  165. // matrix:   
  166. Point3D &Matrix3D::Transform ( Point3D &V )
  167.    {
  168.    // Initialize temporary variables:
  169.    float Lx = V.Lx;
  170.    float Ly = V.Ly;
  171.    float Lz = V.Lz;
  172.  
  173.    // Transform vertex by master matrix:
  174.    V.Wx = ( (   Lx * Matrix [ 0 ][ 0 ]) )
  175.           + ( ( Ly * Matrix [ 1 ][ 0 ]) )
  176.           + ( ( Lz * Matrix [ 2 ][ 0 ]) )
  177.           + Matrix [ 3 ][ 0 ];
  178.  
  179.    V.Wy = (   ( Lx * Matrix [ 0 ][ 1 ]) )
  180.           + ( ( Ly * Matrix [ 1 ][ 1 ]) )
  181.           + ( ( Lz * Matrix [ 2 ][ 1 ]) )
  182.           + Matrix [ 3 ][ 1 ];
  183.  
  184.    V.Wz = (   ( Lx * Matrix [ 0 ][ 2 ]) )
  185.           + ( ( Ly * Matrix [ 1 ][ 2 ]) )
  186.           + ( ( Lz * Matrix [ 2 ][ 2 ]) )
  187.           + Matrix [ 3 ][ 2 ];
  188.    return V;
  189.    }
  190.  
  191. Point3D &Matrix3D::Untransform ( Point3D &V )
  192.    {
  193.    // Initialize temporary variables:
  194.    float Wx = V.Wx;
  195.    float Wy = V.Wy;
  196.    float Wz = V.Wz;
  197.    float InvMatrix [ 4 ] [ 4 ];
  198.    double Pivot;
  199.     int i, j, k;
  200.  
  201.    for ( i = 0; i < 4; i++ )
  202.        {
  203.        InvMatrix [ i ] [ 0 ] = Matrix [ i ] [ 0 ];
  204.        InvMatrix [ i ] [ 1 ] = Matrix [ i ] [ 1 ];
  205.        InvMatrix [ i ] [ 2 ] = Matrix [ i ] [ 2 ];
  206.        InvMatrix [ i ] [ 3 ] = Matrix [ i ] [ 3 ];
  207.        }
  208.  
  209.     for ( i = 0; i < 4; i++ )
  210.        {
  211.        Pivot = InvMatrix [ i ] [ i ];
  212.          InvMatrix [ i ] [ i ] = 1.0F;
  213.          for ( j = 0; j < 4; j++)
  214.            InvMatrix [ i ] [ j ] /= Pivot;
  215.        for ( k = 0; k < 4; k++)
  216.            {
  217.            if ( k == i )
  218.               continue;
  219.            Pivot = InvMatrix [ k ] [ i ];
  220.            InvMatrix [ k ] [ i ] = 0.0F;
  221.            for ( j = 0; j < 4; j++ )
  222.                InvMatrix [ k ] [ j ] -= Pivot * InvMatrix [ i ] [ j ];
  223.             }
  224.         }
  225.  
  226.    // Transform vertex by inverse master matrix:
  227.    V.Lx = ( (   Wx * InvMatrix [ 0 ][ 0 ]) )
  228.           + ( ( Wy * InvMatrix [ 1 ][ 0 ]) )
  229.           + ( ( Wz * InvMatrix [ 2 ][ 0 ]) )
  230.           +          InvMatrix [ 3 ][ 0 ];
  231.  
  232.    V.Ly = (   ( Wx * InvMatrix [ 0 ][ 1 ]) )
  233.           + ( ( Wy * InvMatrix [ 1 ][ 1 ]) )
  234.           + ( ( Wz * InvMatrix [ 2 ][ 1 ]) )
  235.           +          InvMatrix [ 3 ][ 1 ];
  236.  
  237.    V.Lz = (   ( Wx * InvMatrix [ 0 ][ 2 ]) )
  238.           + ( ( Wy * InvMatrix [ 1 ][ 2 ]) )
  239.           + ( ( Wz * InvMatrix [ 2 ][ 2 ]) )
  240.           +          InvMatrix [ 3 ][ 2 ];
  241.    return V;
  242.    }
  243.  
  244. // Function designed to transform a vector using the master
  245. // matrix:
  246. Vector &Matrix3D::Transform ( Vector &V )
  247.    {
  248.    // Initialize temporary variables:
  249.    float OldX = V.X;
  250.    float OldY = V.Y;
  251.    float OldZ = V.Z;
  252.  
  253.    // Transform vertex by master matrix:
  254.    V.Tx = ( ( OldX * Matrix [ 0 ] [ 0 ] ) )
  255.         + ( ( OldY * Matrix [ 1 ] [ 0 ] ) )
  256.         + ( ( OldZ * Matrix [ 2 ] [ 0 ] ) )
  257.         +            Matrix [ 3 ] [ 0 ];
  258.  
  259.    V.Ty = ( ( OldX * Matrix [ 0 ] [ 1 ] ) )
  260.         + ( ( OldY * Matrix [ 1 ] [ 1 ] ) )
  261.         + ( ( OldZ * Matrix [ 2 ] [ 1 ] ) )
  262.         +            Matrix [ 3 ] [ 1 ];
  263.  
  264.    V.Tz = ( ( OldX * Matrix [ 0 ] [ 2 ] ) )
  265.         + ( ( OldY * Matrix [ 1 ] [ 2 ] ) )
  266.         + ( ( OldZ * Matrix [ 2 ] [ 2 ] ) )
  267.         +            Matrix [ 3 ] [ 2 ];
  268.    return V;
  269.    }