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.

152 lines
4.3 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. #include "cbase.h"
  9. #include "particledraw.h"
  10. #include "materialsystem/imesh.h"
  11. // memdbgon must be the last include file in a .cpp file!!!
  12. #include "tier0/memdbgon.h"
  13. //-----------------------------------------------------------------------------
  14. // Sees if the tracer is behind the camera or should be culled
  15. //-----------------------------------------------------------------------------
  16. static bool ClipTracer( const Vector &start, const Vector &delta, Vector &clippedStart, Vector &clippedDelta )
  17. {
  18. // dist1 = start dot forward - origin dot forward
  19. // dist2 = (start + delta ) dot forward - origin dot forward
  20. // in camera space this is -start[2] since origin = 0 and vecForward = (0, 0, -1)
  21. float dist1 = -start[2];
  22. float dist2 = dist1 - delta[2];
  23. // Clipped, skip this tracer
  24. if ( dist1 <= 0 && dist2 <= 0 )
  25. return true;
  26. clippedStart = start;
  27. clippedDelta = delta;
  28. // Needs to be clipped
  29. if ( dist1 <= 0 || dist2 <= 0 )
  30. {
  31. float fraction = dist2 - dist1;
  32. // Too close to clipping plane
  33. if ( fraction < 1e-3 && fraction > -1e-3 )
  34. return true;
  35. fraction = -dist1 / fraction;
  36. if ( dist1 <= 0 )
  37. {
  38. VectorMA( start, fraction, delta, clippedStart );
  39. }
  40. else
  41. {
  42. VectorMultiply( delta, fraction, clippedDelta );
  43. }
  44. }
  45. return false;
  46. }
  47. //-----------------------------------------------------------------------------
  48. // Computes the four verts to draw the tracer with
  49. //-----------------------------------------------------------------------------
  50. bool Tracer_ComputeVerts( const Vector &start, const Vector &delta, float width, Vector *pVerts )
  51. {
  52. Vector clippedStart, clippedDelta;
  53. // Clip the tracer
  54. if ( ClipTracer( start, delta, clippedStart, clippedDelta ) )
  55. return false;
  56. // Figure out direction in camera space of the normal
  57. Vector normal;
  58. CrossProduct( clippedDelta, clippedStart, normal );
  59. // don't draw if they are parallel
  60. float sqLength = DotProduct( normal, normal );
  61. if (sqLength < 1e-3)
  62. return false;
  63. // Resize the normal to be appropriate based on the width
  64. VectorScale( normal, 0.5f * width / sqrt(sqLength), normal );
  65. VectorSubtract( clippedStart, normal, pVerts[0] );
  66. VectorAdd( clippedStart, normal, pVerts[1] );
  67. VectorAdd( pVerts[0], clippedDelta, pVerts[2] );
  68. VectorAdd( pVerts[1], clippedDelta, pVerts[3] );
  69. return true;
  70. }
  71. void Tracer_Draw( CMeshBuilder *pMeshBuilder, Vector const& start, Vector const& delta, float width, float* color, float startV, float endV )
  72. {
  73. // Clip the tracer
  74. Vector verts[4];
  75. if (!Tracer_ComputeVerts( start, delta, width, verts ))
  76. return;
  77. // NOTE: Gotta get the winding right so it's not backface culled
  78. // (we need to turn of backface culling for these bad boys)
  79. pMeshBuilder->Position3f( verts[0].x, verts[0].y, verts[0].z );
  80. pMeshBuilder->TexCoord2f( 0, 0.0f, startV );
  81. if (color)
  82. {
  83. pMeshBuilder->Color4fv( color );
  84. }
  85. else
  86. {
  87. pMeshBuilder->Color4ub( 255, 255, 255, 255 );
  88. }
  89. pMeshBuilder->AdvanceVertex();
  90. pMeshBuilder->Position3f( verts[1].x, verts[1].y, verts[1].z );
  91. pMeshBuilder->TexCoord2f( 0, 1.0f, startV );
  92. if (color)
  93. {
  94. pMeshBuilder->Color4fv( color );
  95. }
  96. else
  97. {
  98. pMeshBuilder->Color4ub( 255, 255, 255, 255 );
  99. }
  100. pMeshBuilder->AdvanceVertex();
  101. pMeshBuilder->Position3f( verts[3].x, verts[3].y, verts[3].z );
  102. pMeshBuilder->TexCoord2f( 0, 1.0f, endV );
  103. if (color)
  104. pMeshBuilder->Color4fv( color );
  105. else
  106. pMeshBuilder->Color4ub( 255, 255, 255, 255 );
  107. pMeshBuilder->AdvanceVertex();
  108. pMeshBuilder->Position3f( verts[2].x, verts[2].y, verts[2].z );
  109. pMeshBuilder->TexCoord2f( 0, 0.0f, endV );
  110. if (color)
  111. pMeshBuilder->Color4fv( color );
  112. else
  113. pMeshBuilder->Color4ub( 255, 255, 255, 255 );
  114. pMeshBuilder->AdvanceVertex();
  115. }
  116. //-----------------------------------------------------------------------------
  117. // draw a tracer.
  118. //-----------------------------------------------------------------------------
  119. void Tracer_Draw( ParticleDraw* pDraw, Vector const& start, Vector const& delta, float width, float* color, float startV, float endV )
  120. {
  121. if( !pDraw->GetMeshBuilder() )
  122. return;
  123. Tracer_Draw( pDraw->GetMeshBuilder(), start, delta, width, color, startV, endV );
  124. }