#include #include "hitlist.h" #include "dest.h" #include "phong.h" #include "potential.h" #include "ray.h" #include "scene.h" #include "Common.h" #include "SamplingStrategy.h" PatchBRDFSamplingStrategy::PatchBRDFSamplingStrategy(PatchProbabilityAssigner *nppa) { // Save ppa = nppa; } PatchBRDFSamplingStrategy::~PatchBRDFSamplingStrategy() { delete ppa; } void PatchBRDFSamplingStrategy::Update() { ppa->assignProbabilities((PATCH *)NULL); } double PatchBRDFSamplingStrategy::BounceRay(RAY &rin,HITREC &hin,RAY &rout,HITREC &hout) { DENSITY_ESTIMATION_DATA *thisData; PATCH *thisPatch; double xi_1,xi_2; double cosTheta; double res; // Choose patch thisPatch = ppa->choosePatch(); // Set default result res = 0.0; // A patch is choosen if ( thisPatch != hin.patch ) { // First select the ray. // Select position rout.pos = hin.point; // Select direction thisData = (DENSITY_ESTIMATION_DATA_PTR) thisPatch->radiance_data; xi_1 = drand48(); xi_2 = drand48(); PatchUniformPoint(thisPatch,xi_1,xi_2,&rout.dir); VECTORSUBTRACT(rout.dir,rout.pos,rout.dir); VECTORNORMALIZE(rout.dir); // Calculate cosTheta cosTheta = VECTORDOTPRODUCT(hin.normal,rout.dir); // Send ray RayCastingFunction(hin.patch,&rout,hout); // !!! FRONT ONLY !!! // Evaluate probability res = EvalRay(rin,hin,rout,hout,cosTheta); } return res; } double PatchBRDFSamplingStrategy::EvalRay(RAY &,HITREC &hin,RAY &rout,HITREC &,const double cosTheta) { HITLIST *hitlist; double res,act; // We are only working with brdf if (cosTheta<0.0) return 0.0; // Initialise res. res = 0.0; // Accumulate probability PatchDontIntersect(1, hin.patch); hitlist = AllGridIntersections((HITLIST *)NULL, WorldGrid, &rout, 0.0, HUGE, HIT_FRONT|HIT_BACK|HIT_PATCH); ForAllHits(hit,hitlist) { act = fabs(VECTORDOTPRODUCT(rout.dir,hit->patch->normal)); if (act>EPSILON) res += (ppa->getProbability(hit->patch)*hit->t*hit->t)/(act*hit->patch->area); } EndForAll; DestroyHitlist(hitlist); return res; }