home *** CD-ROM | disk | FTP | other *** search
/ Programming a Multiplayer FPS in DirectX / Programming a Multiplayer FPS in DirectX (Companion CD).iso / Source / Chapter 5 / Engine / Geometry.h < prev    next >
Encoding:
C/C++ Source or Header  |  2004-10-01  |  12.6 KB  |  335 lines

  1. //-----------------------------------------------------------------------------
  2. // Various geometry structures and processing functions.
  3. //
  4. // Programming a Multiplayer First Person Shooter in DirectX
  5. // Copyright (c) 2004 Vaughan Young
  6. //-----------------------------------------------------------------------------
  7. #ifndef GEOMETRY_H
  8. #define GEOMETRY_H
  9.  
  10. //-----------------------------------------------------------------------------
  11. // Vertex Structure
  12. //-----------------------------------------------------------------------------
  13. struct Vertex
  14. {
  15.     D3DXVECTOR3 translation; // Translation of the vertex (in world space).
  16.     D3DXVECTOR3 normal; // Vertex's normal vector.
  17.     float tu, tv; // Texture UV coordinates.
  18.  
  19.     //-------------------------------------------------------------------------
  20.     // The vertex structure constructor.
  21.     //-------------------------------------------------------------------------
  22.     Vertex()
  23.     {
  24.         translation = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
  25.         normal = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
  26.         tu = 0.0f;
  27.         tv = 0.0f;
  28.     }
  29.  
  30.     //-------------------------------------------------------------------------
  31.     // The vertex structure constructor.
  32.     //-------------------------------------------------------------------------
  33.     Vertex( D3DXVECTOR3 t, D3DXVECTOR3 n, float u, float v )
  34.     {
  35.         translation = t;
  36.         normal = n;
  37.         tu = u;
  38.         tv = v;
  39.     }
  40. };
  41. #define VERTEX_FVF ( D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1 )
  42. #define VERTEX_FVF_SIZE D3DXGetFVFVertexSize( VERTEX_FVF )
  43.  
  44. //-----------------------------------------------------------------------------
  45. // Lit Vertex Structure
  46. //-----------------------------------------------------------------------------
  47. struct LVertex
  48. {
  49.     D3DXVECTOR3 translation; // Translation of the vertex (in world space).
  50.     D3DCOLOR diffuse; // Colour of the vertex.
  51.     float tu, tv; // Texture UV coordinates.
  52.  
  53.     //-------------------------------------------------------------------------
  54.     // The lit vertex structure constructor.
  55.     //-------------------------------------------------------------------------
  56.     LVertex()
  57.     {
  58.         translation = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
  59.         diffuse = 0xFFFFFFFF;
  60.         tu = 0.0f;
  61.         tv = 0.0f;
  62.     }
  63.  
  64.     //-------------------------------------------------------------------------
  65.     // The lit vertex structure constructor.
  66.     //-------------------------------------------------------------------------
  67.     LVertex( D3DXVECTOR3 t, D3DCOLOR d, float u, float v )
  68.     {
  69.         translation = t;
  70.         diffuse = d;
  71.         tu = u;
  72.         tv = v;
  73.     }
  74. };
  75. #define L_VERTEX_FVF ( D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1 )
  76. #define L_VERTEX_FVF_SIZE D3DXGetFVFVertexSize( L_VERTEX_FVF )
  77.  
  78. //-----------------------------------------------------------------------------
  79. // Transformed & Lit Vertex Structure
  80. //-----------------------------------------------------------------------------
  81. struct TLVertex
  82. {
  83.     D3DXVECTOR4 translation; // Translation of the vertex (in screen space).
  84.     D3DCOLOR diffuse; // Colour of the vertex.
  85.     float tu, tv; // Texture UV coordinates.
  86.  
  87.     //-------------------------------------------------------------------------
  88.     // The transformed & lit vertex structure constructor.
  89.     //-------------------------------------------------------------------------
  90.     TLVertex()
  91.     {
  92.         translation = D3DXVECTOR4( 0.0f, 0.0f, 0.0f, 1.0f );
  93.         diffuse = 0xFFFFFFFF;
  94.         tu = 0.0f;
  95.         tv = 0.0f;
  96.     }
  97.  
  98.     //-------------------------------------------------------------------------
  99.     // The transformed & lit vertex structure constructor.
  100.     //-------------------------------------------------------------------------
  101.     TLVertex( D3DXVECTOR4 t, D3DCOLOR d, float u, float v )
  102.     {
  103.         translation = t;
  104.         diffuse = d;
  105.         tu = u;
  106.         tv = v;
  107.     }
  108. };
  109. #define TL_VERTEX_FVF ( D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1 )
  110. #define TL_VERTEX_FVF_SIZE D3DXGetFVFVertexSize( TL_VERTEX_FVF )
  111.  
  112. //-----------------------------------------------------------------------------
  113. // Edge Structure
  114. //-----------------------------------------------------------------------------
  115. struct Edge
  116. {
  117.     Vertex *vertex0; // First vertex of the edge.
  118.     Vertex *vertex1; // Second vertex of the edge.
  119.  
  120.     //-------------------------------------------------------------------------
  121.     // The edge structure constructor.
  122.     //-------------------------------------------------------------------------
  123.     Edge( Vertex *v0, Vertex *v1 )
  124.     {
  125.         vertex0 = v0;
  126.         vertex1 = v1;
  127.     }
  128. };
  129.  
  130. //-----------------------------------------------------------------------------
  131. // Indexed Edge Structure
  132. //-----------------------------------------------------------------------------
  133. struct IndexedEdge
  134. {
  135.     unsigned short vertex0; // Index of the edge's first vertex.
  136.     unsigned short vertex1; // Index of the edge's second vertex.
  137. };
  138.  
  139. //-----------------------------------------------------------------------------
  140. // Face Structure
  141. //-----------------------------------------------------------------------------
  142. struct Face
  143. {
  144.     Vertex *vertex0; // First vertex of the face.
  145.     Vertex *vertex1; // Second vertex of the face.
  146.     Vertex *vertex2; // Third vertex of the face.
  147.  
  148.     //-------------------------------------------------------------------------
  149.     // The face structure constructor.
  150.     //-------------------------------------------------------------------------
  151.     Face( Vertex *v0, Vertex *v1, Vertex *v2 )
  152.     {
  153.         vertex0 = v0;
  154.         vertex1 = v1;
  155.         vertex2 = v2;
  156.     }
  157. };
  158.  
  159. //-----------------------------------------------------------------------------
  160. // Indexed Face Structure
  161. //-----------------------------------------------------------------------------
  162. struct IndexedFace
  163. {
  164.     unsigned short vertex0; // Index of the face's first vertex.
  165.     unsigned short vertex1; // Index of the face's second vertex.
  166.     unsigned short vertex2; // Index of the face's third vertex.
  167. };
  168.  
  169. //-----------------------------------------------------------------------------
  170. // Returns true if the first given box is inside the second given box.
  171. //-----------------------------------------------------------------------------
  172. inline bool IsBoxInBox( D3DXVECTOR3 box1Min, D3DXVECTOR3 box1Max, D3DXVECTOR3 box2Min, D3DXVECTOR3 box2Max )
  173. {
  174.     if( box1Min.x > box2Max.x )
  175.         return false;
  176.     if( box1Min.y > box2Max.y )
  177.         return false;
  178.     if( box1Min.z > box2Max.z )
  179.         return false;
  180.     if( box1Max.x < box2Min.x )
  181.         return false;
  182.     if( box1Max.y < box2Min.y )
  183.         return false;
  184.     if( box1Max.z < box2Min.z )
  185.         return false;
  186.  
  187.     return true;
  188. }
  189.  
  190. //-----------------------------------------------------------------------------
  191. // Returns true if the given face is inside the given box.
  192. //-----------------------------------------------------------------------------
  193. inline bool IsFaceInBox( Vertex *vertex0, Vertex *vertex1, Vertex *vertex2, D3DXVECTOR3 boxMin, D3DXVECTOR3 boxMax )
  194. {
  195.     // Find the minimum and maximum points of the face along the x axis. Then
  196.     // check if these two points are within the box's x axis extents.
  197.     float minX = min( vertex0->translation.x, min( vertex1->translation.x, vertex2->translation.x ) );
  198.     float maxX = max( vertex0->translation.x, max( vertex1->translation.x, vertex2->translation.x ) );
  199.     if( maxX < boxMin.x )
  200.         return false;
  201.     if( minX > boxMax.x )
  202.         return false;
  203.  
  204.     // Find the minimum and maximum points of the face along the y axis. Then
  205.     // check if these two points are within the box's y axis extents.
  206.     float minY = min( vertex0->translation.y, min( vertex1->translation.y, vertex2->translation.y ) );
  207.     float maxY = max( vertex0->translation.y, max( vertex1->translation.y, vertex2->translation.y ) );
  208.     if( maxY < boxMin.y )
  209.         return false;
  210.     if( minY > boxMax.y )
  211.         return false;
  212.  
  213.     // Find the minimum and maximum points of the face along the z axis. Then
  214.     // check if these two points are within the box's z axis extents.
  215.     float minZ = min( vertex0->translation.z, min( vertex1->translation.z, vertex2->translation.z ) );
  216.     float maxZ = max( vertex0->translation.z, max( vertex1->translation.z, vertex2->translation.z ) );
  217.     if( maxZ < boxMin.z )
  218.         return false;
  219.     if( minZ > boxMax.z )
  220.         return false;
  221.  
  222.     return true;
  223. }
  224.  
  225. //-----------------------------------------------------------------------------
  226. // Returns true if the given box is completely enclosed by the given volume.
  227. //-----------------------------------------------------------------------------
  228. inline bool IsBoxEnclosedByVolume( LinkedList< D3DXPLANE > *planes, D3DXVECTOR3 min, D3DXVECTOR3 max )
  229. {
  230.     planes->Iterate( true );
  231.     while( planes->Iterate() )
  232.     {
  233.         if( D3DXPlaneDotCoord( planes->GetCurrent(), &D3DXVECTOR3( min.x, min.y, min.z ) ) < 0.0f )
  234.             return false;
  235.         if( D3DXPlaneDotCoord( planes->GetCurrent(), &D3DXVECTOR3( max.x, min.y, min.z ) ) < 0.0f )
  236.             return false;
  237.         if( D3DXPlaneDotCoord( planes->GetCurrent(), &D3DXVECTOR3( min.x, max.y, min.z ) ) < 0.0f )
  238.             return false;
  239.         if( D3DXPlaneDotCoord( planes->GetCurrent(), &D3DXVECTOR3( max.x, max.y, min.z ) ) < 0.0f )
  240.             return false;
  241.         if( D3DXPlaneDotCoord( planes->GetCurrent(), &D3DXVECTOR3( min.x, min.y, max.z ) ) < 0.0f )
  242.             return false;
  243.         if( D3DXPlaneDotCoord( planes->GetCurrent(), &D3DXVECTOR3( max.x, min.y, max.z ) ) < 0.0f )
  244.             return false;
  245.         if( D3DXPlaneDotCoord( planes->GetCurrent(), &D3DXVECTOR3( min.x, max.y, max.z ) ) < 0.0f )
  246.             return false;
  247.         if( D3DXPlaneDotCoord( planes->GetCurrent(), &D3DXVECTOR3( max.x, max.y, max.z ) ) < 0.0f )
  248.             return false;
  249.     }
  250.  
  251.     return true;
  252. }
  253.  
  254. //-----------------------------------------------------------------------------
  255. // Returns true if the given sphere is overlapping the given volume.
  256. //-----------------------------------------------------------------------------
  257. inline bool IsSphereOverlappingVolume( LinkedList< D3DXPLANE > *planes, D3DXVECTOR3 translation, float radius )
  258. {
  259.     planes->Iterate( true );
  260.     while( planes->Iterate() )
  261.         if( D3DXPlaneDotCoord( planes->GetCurrent(), &translation ) < -radius )
  262.             return false;
  263.  
  264.     return true;
  265. }
  266.  
  267. //-----------------------------------------------------------------------------
  268. // Returns true if the two given spheres collide.
  269. //-----------------------------------------------------------------------------
  270. inline bool IsSphereCollidingWithSphere( float *collisionDistance, D3DXVECTOR3 translation1, D3DXVECTOR3 translation2, D3DXVECTOR3 velocitySum, float radiiSum )
  271. {
  272.     // Get the distance between the two spheres.
  273.     float distanceBetween = D3DXVec3Length( &( translation1 - translation2 ) ) - radiiSum;
  274.  
  275.     // Get the length of the sum of the velocity vectors of the two spheres.
  276.     float velocityLength = D3DXVec3Length( &velocitySum );
  277.  
  278.     // If the spheres are not touching each other and the velocity length is
  279.     // less than the distance between them, then they cannot collide.
  280.     if( distanceBetween > 0.0f && velocityLength < distanceBetween )
  281.         return false;
  282.  
  283.     // Get the normalized sum of the velocity vectors.
  284.     D3DXVECTOR3 normalizedVelocity;
  285.     D3DXVec3Normalize( &normalizedVelocity, &velocitySum );
  286.  
  287.     // Get the direction vector from the second sphere to the first sphere.
  288.     D3DXVECTOR3 direction = translation1 - translation2;
  289.  
  290.     // Get the angle between the normalized velocity and direction vectors.
  291.     float angleBetween = D3DXVec3Dot( &normalizedVelocity, &direction );
  292.  
  293.     // Check if the spheres are moving away from one another.
  294.     if( angleBetween <= 0.0f )
  295.     {
  296.         // Check if they are touching (or inside) each other. If not then they
  297.         // cannot collide since they are moving away from one another.
  298.         if( distanceBetween < 0.0f )
  299.         {
  300.             // If the velocity length is greater than the distance between the
  301.             // spheres then they are moving away from each other fast enough
  302.             // that they will not be touching when they complete their move.
  303.             if( velocityLength > -distanceBetween )
  304.                 return false;
  305.         }
  306.         else
  307.             return false;
  308.     }
  309.  
  310.     // Get the length of the direction vector.
  311.     float directionLength = D3DXVec3Length( &direction );
  312.  
  313.     // The vector between the two spheres and the velocity vector produce two
  314.     // sides of a triangle. Now use Pythagorean Theorem to find the length of
  315.     // the third side of the triangle (i.e. the hypotenuse).
  316.     float hypotenuse = ( directionLength * directionLength ) - ( angleBetween * angleBetween );
  317.  
  318.     // Ensure that the spheres come closer than the sum of their radii.
  319.     float radiiSumSquared = radiiSum * radiiSum;
  320.     if( hypotenuse >= radiiSumSquared )
  321.         return false;
  322.  
  323.     // Get the distance along the velocity vector that the spheres collide.
  324.     // Then use this distance to calculate the distance to the collision.
  325.     float distance = radiiSumSquared - hypotenuse;
  326.     *collisionDistance = angleBetween - (float)sqrt( distance );
  327.  
  328.     // Ensure that the sphere will not travel more than the velocity allows.
  329.     if( velocityLength < *collisionDistance )
  330.         return false;
  331.  
  332.     return true;
  333. }
  334.  
  335. #endif