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.

75 lines
2.1 KiB

  1. //========= Copyright � Valve Corporation, All rights reserved. ============//
  2. #include "sphere.h"
  3. //#include "body.h"
  4. //#include "gjk.h"
  5. //#include "toi.h"
  6. //--------------------------------------------------------------------------------------------------
  7. // Local utilities
  8. //--------------------------------------------------------------------------------------------------
  9. static void CastStationaryHit( CShapeCastResult& out, float c, const Vector &p, const Vector &m, float mm )
  10. {
  11. // return a sphere hit for zero-length ray at point p, with
  12. // m = p - m_vCenter
  13. // mm = DotProduct( m, m )
  14. // c = mm - Sqr( m_flRadius )
  15. if( c <= 0 )
  16. {
  17. out.m_flHitTime = 0;
  18. out.m_vHitPoint = p;
  19. if( mm > FLT_EPSILON )
  20. {
  21. out.m_vHitNormal = m / sqrtf( mm );
  22. }
  23. else
  24. {
  25. out.m_vHitNormal = Vector( 0,0,1 );
  26. }
  27. }
  28. else
  29. {
  30. // we didn't hit - we're outside and we don't move
  31. out.m_flHitTime = FLT_MAX;
  32. }
  33. }
  34. //--------------------------------------------------------------------------------------------------
  35. void CastSphereRay( CShapeCastResult& out, const Vector &m, const Vector& p, const Vector& d, float flRadius )
  36. {
  37. float a = DotProduct( d, d ), mm = DotProduct( m, m ), c = mm - Sqr( flRadius );
  38. if( a < FLT_EPSILON * FLT_EPSILON )
  39. {
  40. // we barely move; just detect if we're in the sphere or not
  41. CastStationaryHit( out, c, p, m, mm );
  42. return;
  43. }
  44. float b = DotProduct( m, d ); // solve: at^2+2bt+c=0; t = (-b�sqrt(b^2-ac))/a = -b/a � sqrt((b/a)^2-c/a))
  45. float D = Sqr( b ) - a * c;
  46. if( D < 0 )
  47. {
  48. // no intersection at all
  49. out.m_flHitTime = FLT_MAX;
  50. return;
  51. }
  52. float sqrtD = sqrtf( D );
  53. float t = ( -b - sqrtD ) / a;
  54. if( t < 0 )
  55. {
  56. // this was the first hit in the past - determine if we're still inside the sphere at time t=0
  57. // we could do that by checking if float t1 = ( b + sqrtD ) / a; is > 0 or not, but it's easier to:
  58. // we barely move; just detect if we're in the sphere or not
  59. CastStationaryHit( out, c, p, m, mm );
  60. }
  61. else
  62. {
  63. out.m_flHitTime = t;
  64. Vector dt = d * t;
  65. out.m_vHitPoint = p + dt;
  66. out.m_vHitNormal = ( m + dt ) / flRadius; // Should I normalize this here or is this sufficient precision?
  67. }
  68. }