Team Fortress 2 Source Code as on 22/4/2020
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.

73 lines
2.7 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Functions for spherical geometry.
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. #ifndef SPHERICAL_GEOMETRY_H
  9. #define SPHERICAL_GEOMETRY_H
  10. #ifdef _WIN32
  11. #pragma once
  12. #endif
  13. #include <math.h>
  14. #include <float.h>
  15. // see http://mathworld.wolfram.com/SphericalTrigonometry.html
  16. // return the spherical distance, in radians, between 2 points on the unit sphere.
  17. FORCEINLINE float UnitSphereLineSegmentLength( Vector const &a, Vector const &b )
  18. {
  19. // check unit length
  20. Assert( fabs( VectorLength( a ) - 1.0 ) < 1.0e-3 );
  21. Assert( fabs( VectorLength( b ) - 1.0 ) < 1.0e-3 );
  22. return acos( DotProduct( a, b ) );
  23. }
  24. // given 3 points on the unit sphere, return the spherical area (in radians) of the triangle they form.
  25. // valid for "small" triangles.
  26. FORCEINLINE float UnitSphereTriangleArea( Vector const &a, Vector const &b , Vector const &c )
  27. {
  28. float flLengthA = UnitSphereLineSegmentLength( b, c );
  29. float flLengthB = UnitSphereLineSegmentLength( c, a );
  30. float flLengthC = UnitSphereLineSegmentLength( a, b );
  31. if ( ( flLengthA == 0. ) || ( flLengthB == 0. ) || ( flLengthC == 0. ) )
  32. return 0.; // zero area triangle
  33. // now, find the 3 incribed angles for the triangle
  34. float flHalfSumLens = 0.5 * ( flLengthA + flLengthB + flLengthC );
  35. float flSinSums = sin( flHalfSumLens );
  36. float flSinSMinusA= sin( flHalfSumLens - flLengthA );
  37. float flSinSMinusB= sin( flHalfSumLens - flLengthB );
  38. float flSinSMinusC= sin( flHalfSumLens - flLengthC );
  39. float flTanAOver2 = sqrt ( ( flSinSMinusB * flSinSMinusC ) / ( flSinSums * flSinSMinusA ) );
  40. float flTanBOver2 = sqrt ( ( flSinSMinusA * flSinSMinusC ) / ( flSinSums * flSinSMinusB ) );
  41. float flTanCOver2 = sqrt ( ( flSinSMinusA * flSinSMinusB ) / ( flSinSums * flSinSMinusC ) );
  42. // Girards formula : area = sum of angles - pi.
  43. return 2.0 * ( atan( flTanAOver2 ) + atan( flTanBOver2 ) + atan( flTanCOver2 ) ) - M_PI;
  44. }
  45. // spherical harmonics-related functions. Best explanation at http://www.research.scea.com/gdc2003/spherical-harmonic-lighting.pdf
  46. // Evaluate associated legendre polynomial P( l, m ) at flX, using recurrence relation
  47. float AssociatedLegendrePolynomial( int nL, int nM, float flX );
  48. // Evaluate order N spherical harmonic with spherical coordinates
  49. // nL = band, 0..N
  50. // nM = -nL .. nL
  51. // theta = 0..M_PI
  52. // phi = 0.. 2 * M_PHI
  53. float SphericalHarmonic( int nL, int nM, float flTheta, float flPhi );
  54. // evaluate spherical harmonic with normalized vector direction
  55. float SphericalHarmonic( int nL, int nM, Vector const &vecDirection );
  56. #endif // SPHERICAL_GEOMETRY_H