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.

238 lines
6.6 KiB

  1. #include "fow.h"
  2. #include "fow_lineoccluder.h"
  3. #include "fow_viewer.h"
  4. // memdbgon must be the last include file in a .cpp file!!!
  5. #include <tier0/memdbgon.h>
  6. //-----------------------------------------------------------------------------
  7. // Purpose: construct a line accluder from the given points. the normal is supplied, though if it doesn't match up with the points, then the points are swapped.
  8. // Input : bx - starting x coord
  9. // by - starting y coord
  10. // ex - ending x coord
  11. // ey - ending y coord
  12. // vNormal - the normal coming from a pre-existing plane from which the line was formed
  13. // nSlinceNum - the slice this occluder belongs to
  14. //-----------------------------------------------------------------------------
  15. CFoW_LineOccluder::CFoW_LineOccluder( float bx, float by, float ex, float ey, Vector2D &vNormal, int nSliceNum )
  16. {
  17. m_vStart.Init( bx, by );
  18. m_vEnd.Init( ex, ey );
  19. m_Plane.Init( bx, by, ex, ey );
  20. if ( fabs( m_Plane.GetNormal().x - vNormal.x ) < 0.1f && fabs( m_Plane.GetNormal().y - vNormal.y ) < 0.1f )
  21. {
  22. m_vStart.Init( ex, ey );
  23. m_vEnd.Init( bx, by );
  24. m_Plane.Init( ex, ey, bx, by );
  25. }
  26. m_nSliceNum = nSliceNum;
  27. }
  28. CFoW_LineOccluder::CFoW_LineOccluder( Vector2D &vStart, Vector2D &vEnd, CFOW_2DPlane &Plane, int nSliceNum )
  29. {
  30. m_vStart = vStart;
  31. m_vEnd = vEnd;
  32. m_Plane = Plane;
  33. m_nSliceNum = nSliceNum;
  34. }
  35. // #define SLOW_PATH 1
  36. //-----------------------------------------------------------------------------
  37. // Purpose: determine the occlusion of this line for the viewer
  38. // Input : pFoW - the main FoW object
  39. // pViewer - the viewer to obstruct
  40. //-----------------------------------------------------------------------------
  41. void CFoW_LineOccluder::ObstructViewer( CFoW *pFoW, CFoW_Viewer *pViewer )
  42. {
  43. int nUnits = pViewer->GetRadiusUnits();
  44. int *pVisibility = pViewer->GetVisibilityRadius();
  45. Vector vCenterLocation = pViewer->GetRealLocation(); // we don't want to use the grid centered location, as the z is not centered
  46. float distance = m_Plane.DistanceFrom( vCenterLocation.x, vCenterLocation.y );
  47. if ( distance < 0.0f )
  48. {
  49. return;
  50. }
  51. #ifdef SLOW_PATH
  52. float flDegreeAmount = 360.0 / pViewer->GetRadiusUnits();
  53. CFOW_2DPlane Edge1, Edge2;
  54. Edge1.Init( vCenterLocation.x, vCenterLocation.y, m_vStart.x, m_vStart.y );
  55. Edge2.Init( m_vEnd.x, m_vEnd.y, vCenterLocation.x, vCenterLocation.y );
  56. float flCurrentDegree = 0.0f;
  57. for ( int i = 0; i < nUnits; i++, flCurrentDegree += flDegreeAmount )
  58. {
  59. Vector Location = pViewer->GetLocation();
  60. Location.x += cos( DEG2RAD( flCurrentDegree ) ) * pViewer->GetSize();
  61. Location.y += sin( DEG2RAD( flCurrentDegree ) ) * pViewer->GetSize();
  62. float flDistance = m_Plane.DistanceFromLineStart( vCenterLocation.x, vCenterLocation.y, Location.x, Location.y );
  63. // flDistance *= pViewer->GetSize();
  64. if ( flDistance >= 0.0f )
  65. {
  66. // distance += Viewer->GetSize();
  67. flDistance *= flDistance;
  68. if ( flDistance >= 0.0f && flDistance < pVisibility[ i ] )
  69. {
  70. if ( Edge1.PointInFront( Location.x, Location.y ) && Edge2.PointInFront( Location.x, Location.y ) )
  71. {
  72. pVisibility[ i ] = flDistance;
  73. }
  74. }
  75. }
  76. }
  77. #else
  78. const Vector2D vStraight( 0.0f, 1.0f );
  79. Vector2D P1( m_vStart.x - vCenterLocation.x, m_vStart.y - vCenterLocation.y );
  80. P1.NormalizeInPlace();
  81. Vector2D P2( m_vEnd.x - vCenterLocation.x, m_vEnd.y - vCenterLocation.y );
  82. P2.NormalizeInPlace();
  83. #if 0
  84. float flCurrentDegree = 0.0f;
  85. for ( int i = 0; i < nUnits; i++, flCurrentDegree += flDegreeAmount )
  86. {
  87. Vector Location = pViewer->GetLocation();
  88. Location.x += cos( DEG2RAD( flCurrentDegree ) ) * pViewer->GetSize();
  89. Location.y += sin( DEG2RAD( flCurrentDegree ) ) * pViewer->GetSize();
  90. float flDistance = m_Plane.DistanceFromLineStart( vCenterLocation.x, vCenterLocation.y, Location.x, Location.y );
  91. // flDistance *= pViewer->GetSize();
  92. if ( flDistance >= 0.0f )
  93. {
  94. // distance += Viewer->GetSize();
  95. flDistance *= flDistance;
  96. if ( flDistance >= 0.0f && flDistance < pVisibility[ i ] )
  97. {
  98. if ( Edge1.PointInFront( Location.x, Location.y ) && Edge2.PointInFront( Location.x, Location.y ) )
  99. {
  100. pVisibility[ i ] = flDistance;
  101. }
  102. }
  103. }
  104. }
  105. #endif
  106. if ( fabs( P1.Dot( P2 ) ) > 0.99995f )
  107. {
  108. return;
  109. }
  110. float flDot1 = vStraight.Dot( P1 );
  111. float flPos = acos( flDot1 );
  112. if ( P1.x < 0.0f )
  113. {
  114. flPos = 2.0f * M_PI_F - flPos;
  115. }
  116. float flDot2 = vStraight.Dot( P2 );
  117. float flNeg = acos( flDot2 );
  118. if ( P2.x < 0.0f )
  119. {
  120. flNeg = 2.0f * M_PI_F - flNeg;
  121. }
  122. if ( fabs( flPos - flNeg ) > M_PI_F )
  123. {
  124. if ( flPos < flNeg )
  125. {
  126. flPos += M_PI_F * 2.0f;
  127. }
  128. else
  129. {
  130. flNeg += M_PI_F * 2.0f;
  131. }
  132. }
  133. // float flAng1 = RAD2DEG( flPos );
  134. // float flAng2 = RAD2DEG( flNeg );
  135. float flCurrentDegree, flFinishDegree;
  136. int nStartIndex;
  137. if ( flPos < flNeg )
  138. {
  139. flCurrentDegree = flPos;
  140. flFinishDegree = flNeg;
  141. }
  142. else
  143. {
  144. flCurrentDegree = flNeg;
  145. flFinishDegree = flPos;
  146. }
  147. /* if ( ( flFinishDegree - flCurrentDegree ) > M_PI_F )
  148. {
  149. float flTemp = flCurrentDegree;
  150. flCurrentDegree = flFinishDegree;
  151. flFinishDegree = flTemp + ( 2.0f * M_PI_F );
  152. }
  153. */
  154. nUnits = pViewer->GetRadiusUnits();
  155. float flDegreeAmount = 2.0f * M_PI_F / nUnits;
  156. nStartIndex = ( int )( flCurrentDegree / flDegreeAmount ) % nUnits;
  157. if ( nStartIndex < 0 )
  158. {
  159. nStartIndex += nUnits;
  160. }
  161. // Vector vViewerLoc = pViewer->GetLocation();
  162. // float flViewerRadius = pViewer->GetSize();
  163. // float flMaxDistance = ( m_vStart - m_vEnd ).LengthSqr() + ( 60.0f * 60.0f );
  164. #if 1
  165. for ( int i = nStartIndex; flCurrentDegree < flFinishDegree; i++, flCurrentDegree += flDegreeAmount )
  166. {
  167. Vector2D vDelta;
  168. if ( i >= nUnits )
  169. {
  170. i = 0;
  171. }
  172. vDelta.x = TableSin( flCurrentDegree );
  173. vDelta.y = TableCos( flCurrentDegree );
  174. #if 0
  175. float flDistance = m_Plane.DistanceFromRay( vCenterLocation.x, vCenterLocation.y, vDelta.x, vDelta.y );
  176. Vector2D vFinal = vCenterLocation.AsVector2D() + ( vDelta * flDistance );
  177. float flDist1 = ( vFinal - m_vStart ).LengthSqr();
  178. float flDist2 = ( vFinal - m_vEnd ).LengthSqr();
  179. if ( flDistance >= 0.0f && ( flDist1 + flDist2 ) < flMaxDistance )
  180. #else
  181. // vDelta = ( vDelta * pViewer->GetSize() ) + vCenterLocation.AsVector2D();
  182. // float flDistance = m_Plane.DistanceFromLineStart( vCenterLocation.x, vCenterLocation.y, vDelta.x, vDelta.y );
  183. float flDistance = m_Plane.DistanceFromRay( vCenterLocation.x, vCenterLocation.y, vDelta.x, vDelta.y );
  184. if ( flDistance >= 0.0f )
  185. #endif
  186. {
  187. flDistance *= flDistance;
  188. if ( flDistance < pVisibility[ i ] )
  189. {
  190. pVisibility[ i ] = flDistance;
  191. }
  192. }
  193. }
  194. #else
  195. int nStart = ( 0.0f / 4.0f ) * nUnits;
  196. int nEnd = ( 1.0f / 4.0f ) * nUnits;
  197. for( ; nStart < nEnd; nStart++ )
  198. {
  199. pVisibility[ nStart ] /= 5.0f;
  200. }
  201. #endif
  202. #endif
  203. }
  204. #include <tier0/memdbgoff.h>