home *** CD-ROM | disk | FTP | other *** search
/ AI Game Programming Wisdom / AIGameProgrammingWisdom.iso / SourceCode / 02 Useful Techniques / 07 Vykruta / TransformMat.h < prev   
Encoding:
C/C++ Source or Header  |  2001-11-13  |  6.7 KB  |  302 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // TransformMat.h : vector definitions, constant defines, etc.
  3. //
  4. /////////////////////////////////////////////////////////////////////////////
  5.  
  6. #ifndef _TRANSFORMMAT_H_
  7. #define _TRANSFORMMAT_H_
  8.  
  9. #include <math.h>
  10.  
  11. #define ELEMWID 20
  12. #define rELEMWID 20.0f
  13.  
  14. #define SIGN(n)        (((n) > 0) ? 1 : (((n) < 0) ? (-1) : 0))
  15. #define ABS(n)        (((n) < 0) ? (-(n)) : (n))
  16. #define MIN(a,b)    (((a) < (b)) ? (a):(b))
  17. #define MAX(a,b)    (((a) > (b)) ? (a):(b))
  18.  
  19.  
  20. // 2D Vector class
  21. class VECTOR2D
  22. {
  23. public:
  24.     union
  25.     {
  26.         float dx;
  27.         float x;
  28.     };
  29.     union
  30.     {
  31.         float dy;
  32.         float y;
  33.     };
  34.  
  35. public:
  36.     // constructor
  37.     VECTOR2D() {};
  38.  
  39.     //constructor
  40.     VECTOR2D( float x, float y )
  41.         { dx = x; dy = y; }
  42.  
  43.     void Set(float x, float y)
  44.         { dx = x; dy = y; }
  45.  
  46.     // Set this equal to another
  47.     VECTOR2D& operator=( const VECTOR2D& vRHS )
  48.     {
  49.         x = vRHS.x;
  50.         y = vRHS.y;
  51.  
  52.         return( *this );
  53.     }
  54.     
  55.     //negate a vector
  56.     inline friend VECTOR2D operator - ( const VECTOR2D& v)
  57.     {
  58.         return VECTOR2D(-v.dx,-v.dy);
  59.     }
  60.  
  61.     //increment by another vector
  62.     void operator += ( const VECTOR2D& v )
  63.         { dx += v.dx; dy += v.dy; }
  64.  
  65.     //decrement by another vector
  66.     void operator -= ( const VECTOR2D& v )
  67.         { dx -= v.dx; dy -= v.dy; }
  68.  
  69.     //multiply by a number
  70.     void operator *= ( float n )
  71.     {
  72.         dx *= n;
  73.         dy *= n;
  74.     }
  75.  
  76.     //add two vectors
  77.     VECTOR2D operator + ( const VECTOR2D& v ) const
  78.     { return VECTOR2D( dx + v.dx, dy + v.dy ); }
  79.  
  80.     //subtract two vectors
  81.     VECTOR2D operator - ( const VECTOR2D& v ) const
  82.     { return VECTOR2D( dx - v.dx, dy - v.dy ); }
  83.  
  84.     //post-multiply by a scalar
  85.     VECTOR2D operator * ( float n ) const
  86.     {
  87.         return VECTOR2D( dx * n, dy * n );
  88.     }
  89.  
  90.     //pre-multiply by a scalar
  91.     inline friend VECTOR2D operator * ( float n, const VECTOR2D& v )
  92.     {
  93.         return VECTOR2D( v.dx * n, v.dy * n );
  94.     }
  95. };
  96.  
  97. class VECTOR3D; // forward dec.
  98.  
  99. // 3D Vector class
  100. class VECTOR3D
  101. {
  102. public:
  103.     union
  104.     {
  105.         float dx;
  106.         float x;
  107.     };
  108.     union
  109.     {
  110.         float dy;
  111.         float y;
  112.     };
  113.     union
  114.     {
  115.         float dz;
  116.         float z;
  117.     };
  118. public:
  119.  
  120.     // constructor
  121.     VECTOR3D() {};
  122.  
  123.     // constructor
  124.     VECTOR3D(float x, float y, float z)
  125.         { dx = x; dy = y; dz = z; }
  126.  
  127.     VECTOR3D( const VECTOR3D& vPos )
  128.         { dx = vPos.x; dy = vPos.y; dz = vPos.z; }
  129.  
  130.     void Set(float x, float y, float z)
  131.         { dx = x; dy = y; dz = z; }
  132.  
  133.     // Set this equal to another
  134.     VECTOR3D& operator=( const VECTOR3D& vRHS )
  135.     {
  136.         x = vRHS.x;
  137.         y = vRHS.y;
  138.         z = vRHS.z;
  139.  
  140.         return( *this );
  141.     }
  142.  
  143.     // Equality test
  144.     BOOL operator == (const VECTOR3D &v) const
  145.         { return(dx == v.dx && dy == v.dy && dz == v.dz); }
  146.  
  147.     // Increment by another vector
  148.     void operator += (const VECTOR3D &v)
  149.         { dx += v.dx; dy += v.dy; dz += v.dz; }
  150.  
  151.     // Decrement by another vector
  152.     void operator -= (const VECTOR3D &v)
  153.         { dx -= v.dx; dy -= v.dy; dz -= v.dz; }
  154.  
  155.     // Increment by a float
  156.     void operator += (const float f)
  157.         { dx += f; dy += f; dz += f; }
  158.  
  159.     // Decrement by a float
  160.     void operator -= (const float f)
  161.         { dx -= f; dy -= f; dz -= f; }
  162.  
  163.     // Multiply by a number
  164.     void operator *= (const float n)
  165.     {
  166.         dx = dx * n;
  167.         dy = dy * n;
  168.         dz = dz * n;
  169.     }
  170.  
  171.     // boolean != operator
  172.     BOOL operator != (const VECTOR3D v) const
  173.         { return(dx != v.dx || dy != v.dy || dz != v.dz); }
  174.  
  175. };
  176.  
  177.  
  178. // The idea behind this class, is to take a arbitrary 2d line, and transform it such that it has a slope between 0 and 0.5
  179. class TransformMatrix
  180. {
  181. public:
  182.     enum eGridTransMatrix {tInvertXY,tNegateX,tNegateY,tNum};
  183.  
  184.     TransformMatrix(const VECTOR2D& vOrigin, const VECTOR2D& vDirVec)
  185.     {    
  186.         vMyOrigin = vDirVec;
  187.         InitMatrix(vDirVec);    
  188.     };
  189.     // Transforms to and from local/global grid space. order of operations is important here!
  190.     // Use templates, because we'll be passing in floats and ints, and ftoi is very expensive.
  191.     template <class tGM1>
  192.     inline void TransformToGridSpace(tGM1& x, tGM1& y)
  193.     {
  194.         if (matrix[tInvertXY] )
  195.         {
  196.             tGM1 iTmp = x;
  197.             x = y;
  198.             y = iTmp;
  199.         }
  200.         if (matrix[tNegateX] )
  201.             x = -x;
  202.         if (matrix[tNegateY] )
  203.             y = -y;
  204.     }
  205.     template <class tGM2>
  206.     inline void TransformToRealSpace(tGM2& x, tGM2& y)
  207.     {
  208.         if (matrix[tNegateX] )
  209.             x = -x;
  210.         if (matrix[tNegateY] )
  211.             y = -y;
  212.         if (matrix[tInvertXY] )
  213.         {
  214.             tGM2 iTmp = x;
  215.             x = y;
  216.             y = iTmp;
  217.         }
  218.     }
  219. // Documentation for TransformOffsetToRealSpace:
  220. // Given an offset to a point (can be 0,0  1,0  0,1  1,0  1,1) returned a transformed offset
  221. // there are 8 possible cases.. here is a chart.  The function, given input, gives output
  222. // INPUT ||      MATRIX          ||  OUTPUT
  223. // X | Y || NegX | NegY | FlipXY ||  X | Y
  224. // 1   0       0     0        0      1   0
  225. // 1   0       0     1        0      1   1
  226. // 1   0       1     0        1      0   0
  227. // 1   0       1     1        1      1   0
  228. // 1   0       1     1        0      0   1
  229. // 1   0       1     0        0      0   0
  230. // 1   0       0     1        1      1   1
  231. // 1   0       0     0        1      0   1
  232.     inline void TransformOffsetToRealSpace(int& x, int& y)
  233.     {
  234.         // if NegX is true, flip the state of X (can be 0 or 1)
  235.         // if NetY is true, flip the satte of Y (can be 0 or 1)
  236.         // if FlipXY is true, reverse thea nswer (easier than reversing both beforehand)
  237.         x ^= matrix[tNegateX];
  238.         y ^= matrix[tNegateY];
  239.         if (matrix[tInvertXY])
  240.         {
  241.             int temp = x;
  242.             x = y;
  243.             y = temp;
  244.         }
  245.     }
  246.  
  247.     void InitMatrix(const VECTOR2D& vDirVec) // given a world-vector, create a local transform
  248.     {
  249.         matrix[tInvertXY] = fabs(vDirVec.y) > fabs(vDirVec.x);
  250.         if (!matrix[tInvertXY])
  251.         {
  252.             matrix[tNegateX]  = vDirVec.x < 0;
  253.             matrix[tNegateY]  = vDirVec.y < 0;
  254.         }
  255.         else
  256.         {
  257.             matrix[tNegateX]  = vDirVec.y < 0;
  258.             matrix[tNegateY]  = vDirVec.x < 0;
  259.         }
  260.     }
  261.  
  262.     BOOL operator [] (const eGridTransMatrix e)
  263.         {    return(matrix[e]);    };
  264. private:
  265. public:
  266.     BOOL     matrix[tNum];
  267.     VECTOR2D vMyOrigin;
  268. };
  269.  
  270. // very simple landscape-chunk
  271. class Layer
  272. {
  273. public:
  274.     Layer(const int iXOrig, const int iZOrig, const int iWidth, const int iHeight, const float rYOrig) : 
  275.                                 m_iXOrig(iXOrig), m_iZOrig(iZOrig), m_iWidth(iWidth), m_iHeight(iHeight), m_rYOrig(rYOrig)
  276.     {
  277.     }
  278.     
  279.     const int    GetXOrigin() const 
  280.         {    return(m_iXOrig);    }
  281.     const int    GetZOrigin() const 
  282.         {    return(m_iZOrig);    }
  283.     const float    GetYOrigin() const 
  284.         {    return(m_rYOrig);    }
  285.     const VECTOR3D GetOrigin() const
  286.         {    return( VECTOR3D(0,0,0));    }
  287.     bool DoesElemCollideRay(const VECTOR3D &vFrom, const VECTOR3D &vTo, VECTOR3D* pvImpact) const;
  288.     
  289.     const float VertHeight(const int iX, const int iZ) const
  290.         { return(m_rYOrig);    } // assume a uniform height for all vertices for academic purposes
  291.  
  292. private:
  293.     int m_iXOrig;
  294.     int m_iZOrig;
  295.     int m_iWidth;
  296.     int m_iHeight;
  297.     
  298.     float m_rYOrig;
  299. };
  300.  
  301. #endif // _TRANSFORMMAT_H
  302.