Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

206 lines
5.8 KiB

  1. #include "fow.h"
  2. #include "fow_trisoup.h"
  3. #include "fow_lineoccluder.h"
  4. // memdbgon must be the last include file in a .cpp file!!!
  5. #include <tier0/memdbgon.h>
  6. //-----------------------------------------------------------------------------
  7. // Purpose: constructor to init this collection with the id
  8. // Input : nID - unused
  9. //-----------------------------------------------------------------------------
  10. CFoW_TriSoupCollection::CFoW_TriSoupCollection( unsigned nID )
  11. {
  12. }
  13. //-----------------------------------------------------------------------------
  14. // Purpose: destructor to dealloc the occluders
  15. //-----------------------------------------------------------------------------
  16. CFoW_TriSoupCollection::~CFoW_TriSoupCollection( void )
  17. {
  18. Clear();
  19. }
  20. //-----------------------------------------------------------------------------
  21. // Purpose: clears all entries from the collection ( useful for hammer editing only )
  22. //-----------------------------------------------------------------------------
  23. void CFoW_TriSoupCollection::Clear( void )
  24. {
  25. m_Occluders.PurgeAndDeleteElements();
  26. }
  27. //-----------------------------------------------------------------------------
  28. // Purpose: adds a tri to the collection. this is immediately split up into the horizontal slices. very slow!
  29. // Input : pFoW - the main FoW object
  30. // vPointA - a point on the tri
  31. // vPointB - a point on the tri
  32. // vPointC - a point on the tri
  33. //-----------------------------------------------------------------------------
  34. void CFoW_TriSoupCollection::AddTri( CFoW *pFoW, Vector &vPointA, Vector &vPointB, Vector &vPointC )
  35. {
  36. Vector vVerts[ 3 ], vOutVerts[ 8 ];
  37. int nBottomZ;
  38. int nGridSize;
  39. int nGridUnits;
  40. Vector vNormal, vTestNormal;
  41. float flIntercept;
  42. float *pflVerticalLevels;
  43. vVerts[ 0 ] = vPointA;
  44. vVerts[ 1 ] = vPointB;
  45. vVerts[ 2 ] = vPointC;
  46. pFoW->GetVerticalGridInfo( nBottomZ, nGridSize, nGridUnits, &pflVerticalLevels );
  47. ComputeTrianglePlane( vPointA, vPointB, vPointC, vNormal, flIntercept );
  48. vTestNormal = vNormal;
  49. vTestNormal.z = 0.0f;
  50. vTestNormal.NormalizeInPlace();
  51. Vector2D vTestNormal2( vTestNormal.x, vTestNormal.y );
  52. for ( int i = 0; i < nGridUnits; i++ )
  53. {
  54. nBottomZ = pflVerticalLevels[ i ] + 16.0f;
  55. int nCount = HorizontalSplitTri( vVerts, 3, vOutVerts, nBottomZ, 0.0f );
  56. if ( nCount == 2 )
  57. {
  58. CFoW_LineOccluder *pOccluder = new CFoW_LineOccluder( vOutVerts[ 0 ].x, vOutVerts[ 0 ].y, vOutVerts[ 1 ].x, vOutVerts[ 1 ].y, vTestNormal2, i );
  59. m_Occluders.AddToTail( pOccluder );
  60. pFoW->AddTriSoupOccluder( pOccluder, i );
  61. }
  62. }
  63. }
  64. //-----------------------------------------------------------------------------
  65. // Purpose: adds all occluders back into the visibility tree
  66. // Input : pFoW - the main FoW object
  67. //-----------------------------------------------------------------------------
  68. void CFoW_TriSoupCollection::RepopulateOccluders( CFoW *pFoW )
  69. {
  70. for ( int i = 0; i < m_Occluders.Count(); i++ )
  71. {
  72. pFoW->AddTriSoupOccluder( m_Occluders[ i ], m_Occluders[ i ]->GetSliceNum() );
  73. }
  74. }
  75. #if 0
  76. void CFoW_TriSoupCollection::ObstructViewer( CFoW *FoW, CFoW_Viewer *Viewer )
  77. {
  78. for ( int i = 0; i < m_Occluders.Count(); i++ )
  79. {
  80. m_Occluders[ i ].ObstructViewer( FoW, Viewer );
  81. }
  82. }
  83. #endif
  84. //-----------------------------------------------------------------------------
  85. // Purpose: clip a poly to the horizontal plane and return the poly on the front side of the plane
  86. // Input : *pInVerts - input polygon
  87. // nVertCount - # verts in input poly
  88. // *pOutVerts - destination poly
  89. // flDist - plane constant
  90. // flOnPlaneEpsilon - the fudge factor for determining if a point is within the plane edge
  91. // Output : int - # verts in output poly
  92. //-----------------------------------------------------------------------------
  93. int CFoW_TriSoupCollection::HorizontalSplitTri( Vector *pInVerts, int nVertCount, Vector *pOutVerts, float flDist, float flOnPlaneEpsilon )
  94. {
  95. vec_t *pDists = ( vec_t * )stackalloc( sizeof( vec_t ) * nVertCount * 4 ); //4x vertcount should cover all cases
  96. int *pSides = ( int * )stackalloc( sizeof( vec_t ) * nVertCount * 4 );
  97. int nCounts[ 3 ];
  98. vec_t flDot;
  99. int i, j;
  100. Vector vMid = vec3_origin;
  101. int nOutCount;
  102. Vector vNormal( 0.0f, 0.0f, 1.0f );
  103. nCounts[ 0 ] = nCounts[ 1 ] = nCounts[ 2 ] = 0;
  104. // determine sides for each point
  105. for ( i = 0; i < nVertCount; i++ )
  106. {
  107. flDot = DotProduct( pInVerts[ i ], vNormal ) - flDist;
  108. pDists[ i ] = flDot;
  109. if ( flDot > flOnPlaneEpsilon )
  110. {
  111. pSides[ i ] = SIDE_FRONT;
  112. }
  113. else if ( flDot < -flOnPlaneEpsilon )
  114. {
  115. pSides[ i ] = SIDE_BACK;
  116. }
  117. else
  118. {
  119. pSides[ i ] = SIDE_ON;
  120. }
  121. nCounts[ pSides[ i ] ]++;
  122. }
  123. pSides[ i ] = pSides[ 0 ];
  124. pDists[ i ] = pDists[ 0 ];
  125. if ( !nCounts[ SIDE_FRONT ] )
  126. { // if this has 2 sides that are side_on, then this should be a tri coming soon with the same two sides that are on, but with one on side_back
  127. return 0;
  128. }
  129. nOutCount = 0;
  130. for ( i = 0; i < nVertCount; i++ )
  131. {
  132. int nCurrent = ( i + 0 ) % nVertCount;
  133. int nNext = ( i + 1 ) % nVertCount;
  134. Vector &p1 = pInVerts[ nCurrent ];
  135. if ( pSides[ nCurrent ] == SIDE_ON )
  136. {
  137. VectorCopy( p1, pOutVerts[ nOutCount ] );
  138. nOutCount++;
  139. continue;
  140. }
  141. if ( pSides[ nCurrent ] == SIDE_FRONT )
  142. {
  143. // VectorCopy( p1, outVerts[outCount]);
  144. // outCount++;
  145. }
  146. if ( pSides[ nNext ] == SIDE_ON || pSides[ nNext ] == pSides[ nCurrent ] )
  147. {
  148. continue;
  149. }
  150. // generate a split point
  151. Vector &p2 = pInVerts[ nNext ];
  152. flDot = pDists[ nCurrent ] / ( pDists[ nCurrent ] - pDists[ nNext ] );
  153. for ( j = 0; j < 3; j++ )
  154. { // avoid round off error when possible
  155. if ( vNormal[ j ] == 1 )
  156. {
  157. vMid[ j ] = flDist;
  158. }
  159. else if ( vNormal[ j ] == -1 )
  160. {
  161. vMid[ j ] = -flDist;
  162. }
  163. else
  164. {
  165. vMid[ j ] = p1[ j ] + flDot * ( p2[ j ] - p1[ j ] );
  166. }
  167. }
  168. VectorCopy ( vMid, pOutVerts[ nOutCount ] );
  169. nOutCount++;
  170. }
  171. return nOutCount;
  172. }
  173. #include <tier0/memdbgoff.h>