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.

126 lines
3.2 KiB

  1. //========= Copyright � 1996-2007, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: spherical math routines
  4. //
  5. //=====================================================================================//
  6. #include <math.h>
  7. #include <float.h> // needed for flt_epsilon
  8. #include "basetypes.h"
  9. #ifndef _PS3
  10. #include <memory.h>
  11. #endif
  12. #include "tier0/dbg.h"
  13. #include "mathlib/mathlib.h"
  14. #include "mathlib/vector.h"
  15. #include "mathlib/spherical_geometry.h"
  16. // memdbgon must be the last include file in a .cpp file!!!
  17. #include "tier0/memdbgon.h"
  18. float s_flFactorials[]={
  19. 1.,
  20. 1.,
  21. 2.,
  22. 6.,
  23. 24.,
  24. 120.,
  25. 720.,
  26. 5040.,
  27. 40320.,
  28. 362880.,
  29. 3628800.,
  30. 39916800.,
  31. 479001600.,
  32. 6227020800.,
  33. 87178291200.,
  34. 1307674368000.,
  35. 20922789888000.,
  36. 355687428096000.,
  37. 6402373705728000.,
  38. 121645100408832000.,
  39. 2432902008176640000.,
  40. 51090942171709440000.,
  41. 1124000727777607680000.,
  42. 25852016738884976640000.,
  43. 620448401733239439360000.,
  44. 15511210043330985984000000.,
  45. 403291461126605635584000000.,
  46. 10888869450418352160768000000.,
  47. 304888344611713860501504000000.,
  48. 8841761993739701954543616000000.,
  49. 265252859812191058636308480000000.,
  50. 8222838654177922817725562880000000.,
  51. 263130836933693530167218012160000000.,
  52. 8683317618811886495518194401280000000.
  53. };
  54. float AssociatedLegendrePolynomial( int nL, int nM, float flX )
  55. {
  56. // evaluate associated legendre polynomial at flX, using recurrence relation
  57. float flPmm = 1.;
  58. if ( nM > 0 )
  59. {
  60. float flSomX2 = sqrt( ( 1 - flX ) * ( 1 + flX ) );
  61. float flFact = 1.;
  62. for( int i = 0 ; i < nM; i++ )
  63. {
  64. flPmm *= -flFact * flSomX2;
  65. flFact += 2.0;
  66. }
  67. }
  68. if ( nL == nM )
  69. return flPmm;
  70. float flPmmp1 = flX * ( 2.0 * nM + 1.0 ) * flPmm;
  71. if ( nL == nM + 1 )
  72. return flPmmp1;
  73. float flPll = 0.;
  74. for( int nLL = nM + 2 ; nLL <= nL; nLL++ )
  75. {
  76. flPll = ( ( 2.0 * nLL - 1.0 ) * flX * flPmmp1 - ( nLL + nM - 1.0 ) * flPmm ) * ( 1.0 / ( nLL - nM ) );
  77. flPmm = flPmmp1;
  78. flPmmp1 = flPll;
  79. }
  80. return flPll;
  81. }
  82. static float SHNormalizationFactor( int nL, int nM )
  83. {
  84. double flTemp = ( ( 2. * nL + 1.0 ) * s_flFactorials[ nL - nM ] )/ ( 4. * M_PI * s_flFactorials[ nL + nM ] );
  85. return sqrt( flTemp );
  86. }
  87. #define SQRT_2 1.414213562373095
  88. FORCEINLINE float SphericalHarmonic( int nL, int nM, float flTheta, float flPhi, float flCosTheta )
  89. {
  90. if ( nM == 0 )
  91. return SHNormalizationFactor( nL, 0 ) * AssociatedLegendrePolynomial( nL, nM, flCosTheta );
  92. if ( nM > 0 )
  93. return SQRT_2 * SHNormalizationFactor( nL, nM ) * cos ( nM * flPhi ) *
  94. AssociatedLegendrePolynomial( nL, nM, flCosTheta );
  95. return
  96. SQRT_2 * SHNormalizationFactor( nL, -nM ) * sin( -nM * flPhi ) * AssociatedLegendrePolynomial( nL, -nM, flCosTheta );
  97. }
  98. float SphericalHarmonic( int nL, int nM, float flTheta, float flPhi )
  99. {
  100. return SphericalHarmonic( nL, nM, flTheta, flPhi, cos( flTheta ) );
  101. }
  102. float SphericalHarmonic( int nL, int nM, Vector const &vecDirection )
  103. {
  104. Assert( fabs( VectorLength( vecDirection ) - 1.0 ) < 0.0001 );
  105. float flPhi = acos( vecDirection.z );
  106. float flTheta = 0;
  107. float S = Square( vecDirection.x ) + Square( vecDirection.y );
  108. if ( S > 0 )
  109. {
  110. flTheta = atan2( vecDirection.y, vecDirection.x );
  111. }
  112. return SphericalHarmonic( nL, nM, flTheta, flPhi, cos( flTheta ) );
  113. }