char sphericalHarmonics::isCloseTo(const XYZ& ray, const float threshold, unsigned int id) const
{
	SHSample& s = getSample(id);
	float c = ray.dot(s.vector);
	float t = sqrt(1-c*c)/c;
	if(t >threshold) return 0;
	return 1;
}
void sphericalHarmonics::bDiffuseTransfer(SHSample* samp, const int num_samp, const float unitarea, XYZ* inCoeff, XYZ* outCoeff, const XYZ& normal) const
{
	bReconstructSH rsh(inCoeff);
	for (int j = 0; j < SH_N_BASES; j++) outCoeff[j] = XYZ(0);
	
	for(int j=0; j<num_samp; j++)
	{
		SHSample& s = samp[j];
		float H = normal.dot(s.vector);
		if(H>0)
		{
			XYZ col = rsh.getColor(s) * H * unitarea;
			projectASample(outCoeff, s, col);
		}
	}
}
void sphericalHarmonics::diffuseTransfer(SHSample* samp, const int num_samp, const float unitarea, XYZ* inCoeff, XYZ* outCoeff, float* tmpCoeff, const XYZ& normal) const
{
	reconstructSH rsh(inCoeff);
	
	for (int j = 0; j < SH_N_BASES; j++)
		tmpCoeff[j] = 0;
	
	for(int j=0; j<num_samp; j++)
	{
		SHSample& s = samp[j];
		float H = normal.dot(s.vector);
		if(H>0)
		{
			float shd = rsh.getFloat(s) * H * unitarea;
			projectASample(tmpCoeff, s, shd);
		}
	}
	
	for (int j = 0; j < SH_N_BASES; j++)
		outCoeff[j].x = outCoeff[j].y = outCoeff[j].z = tmpCoeff[j];
}