www.pudn.com > ZFXMath-latest.zip > SHDevice.h


/// \file 
/// 
/// \if DE 
/// @brief SphericalHarmonics::TDevice 
/// 
/// TDevice: Werkzeug für effiziente Implementation von SH Lighting 
/// \else 
/// @brief SphericalHarmonics::TDevice 
/// 
/// TDevice: Tool for efficient implementation of SH Lighting 
/// \endif 
 
 
#ifndef	_ZFXMATH_INCLUDE_SH_DEVICE_H_ 
#define	_ZFXMATH_INCLUDE_SH_DEVICE_H_ 
 
#include  
#include "SphericalHarmonics.h" 
#include "SHRotateMatrix.h" 
#include "SHRotate.h" 
#include "NRook.h" 
 
namespace ZFXMath 
{ 
 
namespace SphericalHarmonics 
{ 
 
/// \if DE 
/// @brief Spherical Harmonic Lighting Device 
/// 
/// Ziemlich nützliches Werkzeug 
/// \else 
/// @brief Spherical Harmonic Lighting Device 
/// 
/// Pretty handy Tool 
/// \endif 
template< class PrecisionType, class FuncValueType > 
struct TDevice 
{ 
	/// \if DE 
	/// @brief Device Konstruktor 
	/// 
	/// \param numBands SH Ordnung + 1 (Genauigkeit der Funktionsrekonstruktion) 
	/// \param numSamples Anzahl der Samples um die Originalfunktion zu komprimieren (Genauigkeit der Funktionskompression) 
	/// \else 
	/// @brief Device Constructor 
	/// 
	/// \param numBands SH Order + 1 (accuracy of function reconstruction) 
	/// \param numSamples Number of samples to compress the original function (accuracy of function compression) 
	/// \endif 
	TDevice( int numBands, int numSamples ) : 
		m_NumBands( numBands ), 
		m_NumSamples( numSamples ) 
	{ 
		assert( numBands > 0 ); 
		assert( numSamples > 0 ); 
 
		// Generate the sphere samples 
		m_Samples = GenerateSamples( m_NumSamples ); 
 
		// Create an allocator with enough space to store y(l,m) over each band for each sample 
		m_CoeffsAllocator = new TCoeffs::Allocator( m_NumSamples * m_NumBands * m_NumBands ); 
 
		// Allocate a set of empty coeff lists 
		m_SHValues = new TCoeffs[m_NumSamples]; 
 
		for (int i = 0; i < m_NumSamples; i++) 
		{ 
			// De-ref current sample 
			TSample& s = m_Samples[i]; 
 
			// Create an SH coefficients to store the required number of bands 
			TCoeffs& sh = m_SHValues[i] = TCoeffs( m_NumBands, m_CoeffsAllocator ); 
 
			// Record all y(l,m) for this sample 
			for (int l = 0; l < m_NumBands; l++) 
				for (int m = -l; m <= l; m++) 
					sh(l, m) = y(l, m, s.theta, s.phi); 
		} 
	} 
 
	~TDevice() 
	{ 
		delete m_CoeffsAllocator; 
		delete[] m_SHValues;	 
	} 
 
	/// \if DE 
	/// @brief Komprimiert eine sphärische Funktion in SH-Koeffizienten 
	/// 
	/// \param func sphärische Funktion die projiziert werden soll (in) 
	/// \param dest Zielprojektion (out) 
	/// \else 
	/// @brief Compress a Spherical Function into SH Coefficients 
	/// 
	/// \param func Spherical Function to project (in) 
	/// \param dest Destination projection (out) 
	/// \endif 
	void Project(const TSphericalFunction< PrecisionType, FuncValueType >& func, 
				 TCoeffs< FuncValueType >& dest ) 
	{ 
		SphericalHarmonics::Project( func, m_Samples, m_SHValues, m_NumSamples, dest ); 
	} 
 
	private: 
 
		// Number of samples on the sphere 
		int											m_NumSamples; 
 
		// Number of SH bands 
		int											m_NumBands; 
 
		// Uniformly distributed samples on the sphere 
		TSample*						m_Samples; 
 
		// Allocator for y(l,m) values for each sample 
		typename TCoeffs::Allocator*	m_CoeffsAllocator; 
 
		// y(l,m) stored for each sample over m_NumBands 
		TCoeffs*						m_SHValues; 
	 
}; 
 
}; // namespace SphericalHarmonics 
 
}; // namespace ZFXMath 
 
#endif //_ZFXMATH_INCLUDE_SH_DEVICE_H_