diff options
| author | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
|---|---|---|
| committer | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
| commit | 39ed87570bdb2f86969d4be821c94b722dc71179 (patch) | |
| tree | abc53757f75f40c80278e87650ea92808274aa59 /mp/src/mathlib/spherical.cpp | |
| download | source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip | |
First version of the SOurce SDK 2013
Diffstat (limited to 'mp/src/mathlib/spherical.cpp')
| -rw-r--r-- | mp/src/mathlib/spherical.cpp | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/mp/src/mathlib/spherical.cpp b/mp/src/mathlib/spherical.cpp new file mode 100644 index 00000000..d3aa9679 --- /dev/null +++ b/mp/src/mathlib/spherical.cpp @@ -0,0 +1,124 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: spherical math routines
+//
+//=====================================================================================//
+
+#include <math.h>
+#include <float.h> // Needed for FLT_EPSILON
+#include "basetypes.h"
+#include <memory.h>
+#include "tier0/dbg.h"
+#include "mathlib/mathlib.h"
+#include "mathlib/vector.h"
+#include "mathlib/spherical_geometry.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+float s_flFactorials[]={
+ 1.,
+ 1.,
+ 2.,
+ 6.,
+ 24.,
+ 120.,
+ 720.,
+ 5040.,
+ 40320.,
+ 362880.,
+ 3628800.,
+ 39916800.,
+ 479001600.,
+ 6227020800.,
+ 87178291200.,
+ 1307674368000.,
+ 20922789888000.,
+ 355687428096000.,
+ 6402373705728000.,
+ 121645100408832000.,
+ 2432902008176640000.,
+ 51090942171709440000.,
+ 1124000727777607680000.,
+ 25852016738884976640000.,
+ 620448401733239439360000.,
+ 15511210043330985984000000.,
+ 403291461126605635584000000.,
+ 10888869450418352160768000000.,
+ 304888344611713860501504000000.,
+ 8841761993739701954543616000000.,
+ 265252859812191058636308480000000.,
+ 8222838654177922817725562880000000.,
+ 263130836933693530167218012160000000.,
+ 8683317618811886495518194401280000000.
+};
+
+float AssociatedLegendrePolynomial( int nL, int nM, float flX )
+{
+ // evaluate associated legendre polynomial at flX, using recurrence relation
+ float flPmm = 1.;
+ if ( nM > 0 )
+ {
+ float flSomX2 = sqrt( ( 1 - flX ) * ( 1 + flX ) );
+ float flFact = 1.;
+ for( int i = 0 ; i < nM; i++ )
+ {
+ flPmm *= -flFact * flSomX2;
+ flFact += 2.0;
+ }
+ }
+ if ( nL == nM )
+ return flPmm;
+ float flPmmp1 = flX * ( 2.0 * nM + 1.0 ) * flPmm;
+ if ( nL == nM + 1 )
+ return flPmmp1;
+ float flPll = 0.;
+ for( int nLL = nM + 2 ; nLL <= nL; nLL++ )
+ {
+ flPll = ( ( 2.0 * nLL - 1.0 ) * flX * flPmmp1 - ( nLL + nM - 1.0 ) * flPmm ) * ( 1.0 / ( nLL - nM ) );
+ flPmm = flPmmp1;
+ flPmmp1 = flPll;
+ }
+ return flPll;
+}
+
+static float SHNormalizationFactor( int nL, int nM )
+{
+ double flTemp = ( ( 2. * nL + 1.0 ) * s_flFactorials[ nL - nM ] )/ ( 4. * M_PI * s_flFactorials[ nL + nM ] );
+ return sqrt( flTemp );
+}
+
+#define SQRT_2 1.414213562373095
+
+FORCEINLINE float SphericalHarmonic( int nL, int nM, float flTheta, float flPhi, float flCosTheta )
+{
+ if ( nM == 0 )
+ return SHNormalizationFactor( nL, 0 ) * AssociatedLegendrePolynomial( nL, nM, flCosTheta );
+
+ if ( nM > 0 )
+ return SQRT_2 * SHNormalizationFactor( nL, nM ) * cos ( nM * flPhi ) *
+ AssociatedLegendrePolynomial( nL, nM, flCosTheta );
+
+ return
+ SQRT_2 * SHNormalizationFactor( nL, -nM ) * sin( -nM * flPhi ) * AssociatedLegendrePolynomial( nL, -nM, flCosTheta );
+
+}
+
+float SphericalHarmonic( int nL, int nM, float flTheta, float flPhi )
+{
+ return SphericalHarmonic( nL, nM, flTheta, flPhi, cos( flTheta ) );
+}
+
+float SphericalHarmonic( int nL, int nM, Vector const &vecDirection )
+{
+ Assert( fabs( VectorLength( vecDirection ) - 1.0 ) < 0.0001 );
+ float flPhi = acos( vecDirection.z );
+ float flTheta = 0;
+ float S = Square( vecDirection.x ) + Square( vecDirection.y );
+ if ( S > 0 )
+ {
+ flTheta = atan2( vecDirection.y, vecDirection.x );
+ }
+ return SphericalHarmonic( nL, nM, flTheta, flPhi, cos( flTheta ) );
+}
+
|