#include #include #include "Common.h" #include "HemisphereScratchPad.h" HemisphereScratchPad::HemisphereScratchPad(int rpos,int rdir) { int i; DebugAssert(rdir>0,"Recursion level is a strictly positive number"); maxr = rdir; maxnumsub = (1<configure(p,grdsz); } void HemisphereScratchPad::setKernelSize(const float hp,const float hd) { int i; // Precompute some values h = (hd>M_PI_2) ? M_PI_2 : hd; h2 = h*h; h2inv = 1.0f / h2; for (i=0;isetKernelSize(hp); } void HemisphereScratchPad::addImpact(const VEC2D &pos,const VEC2D &dir,const COLOR &weight) { float tmp; float dt,dp,deltat,deltap; int i,d,it,ip,isr; VECTOR posd,posr,delta; COLOR tw; // Find the vector of the impact to3d(dir.u,dir.v,posd); // Find the reflection, if any tmp = M_PI_2 - dir.v; if (tmp0.0) { tmp = acos(tmp); if (tmpaddImpact(pos,tw); } dp += deltap; } i += d; d += (it==0) ? 3 : 4; dt += deltat; } } HemisphereScratchPad* HemisphereScratchPad::evaluateOutgoing() { HemisphereScratchPad *tp; int ia,ib; int da,db; int ita,itb; int ipa,ipb; float dta,dtb; float dpa,dpb; float deltata,deltatb; float deltapa,deltapb; float scale,fscale; VECTOR dira,dirb,norm; COLOR col; // Initialise VECTORSET(norm,0.0,0.0,1.0); scale = M_2PI / ((float)curnumspps); // Ajouter accum for (ib=0;ibaddAccum(); // Alloc another HemisphereScratchPad for temporary calculations. tp = new HemisphereScratchPad(spps[0]->curr,curr); tp->configure(spps[0]->patch,chgsz,curr); // Visit all directions ia = 0; da = 1; dta = 0.0; deltata = M_PI_2 / ((float)(curnumsub)); for (ita=0;ita<=curnumsub;ita++) { fscale = cos(dta)*scale; dpa = 0.0; deltapa = M_2PI / ((float)da); for (ipa=0;ipapatch->surface->material->bsdf, (&spps[0]->patch->midpoint), NULL, NULL, &dira, &dirb, &norm, DIFFUSE_COMPONENT|GLOSSY_COMPONENT); COLORSCALE(fscale,col,col); tp->spps[ib+ipb]->add(spps[ia+ipa],col); dpb += deltapb; } ib += db; db += (itb==0) ? 3 : 4; dtb += deltatb; } dpa += deltapa; } ia += da; da += (ita==0) ? 3 : 4; dta += deltata; } return tp; } NonDiffuseSurface* HemisphereScratchPad::constructNonDiffuseCompressedSurface(const float t) { HemisphereScratchPad *tp; NonDiffuseSurface *nds; int i; // Reconstruct outgoing radiance tp = evaluateOutgoing(); // Construct the non diffuse compressed surface nds = new NonDiffuseSurface(spps[0]->patch,curr); for (i=0;isetDiffuseSurface(i,tp->spps[i]->constructDiffuseCompressedSurface(t)); // Free temporary storage delete tp; return nds; } NonDiffuseSurface *HemisphereScratchPad::constructNonDiffuseDecimatedSurface(const float t) { HemisphereScratchPad *tp; NonDiffuseSurface *ndsp; int i; // Reconstruct outgoing radiance tp = evaluateOutgoing(); // Construct the coefficient store array ndsp = new NonDiffuseSurface(spps[0]->patch,curr); for (i=0;isetDiffuseSurface(i,tp->spps[i]->constructDiffuseDecimatedSurface(t)); // Free temporary storage delete tp; return ndsp; } void HemisphereScratchPad::to3d(const float p,const float t,VECTOR& v) { v.x = cos(p)*sin(t); v.y = sin(p)*sin(t); v.z = cos(t); } int HemisphereScratchPad::numberOfPoints(int rdir) { int nsub; DebugAssert(rdir>=0,"The recursion level is a positive number"); nsub = (1<=0,"The recursion level is a positive number"); // Be tolerant with numerical errors... if (phi<0.0) phi = 0.0; if (phi>M_2PI) phi = M_2PI; if (theta<0.0) theta = 0.0; if (theta>M_PI_2) theta = M_PI_2; // Find sub-triangle edge length convtheta = ((double)(1<patch,pos.u,pos.v,&outdir); VECTORSUBTRACT(Camera.eyep,outdir,outdir); if (VECTORDOTPRODUCT(spp->patch->normal,outdir)<=0.0) return; VECTORNORMALIZE(outdir); // Find how far we discretise vnumsub = (1<0.0) { angle = acos(angle); if (anglepatch->surface->material->bsdf, &(spp->patch->midpoint), NULL, NULL, &indirtp, &outdir, &(spp->patch->normal), DIFFUSE_COMPONENT|GLOSSY_COMPONENT); COLORPROD(twtp,weight,twtp); tmp *= M_1_PI; COLORADDSCALED(tw,tmp,twtp,tw); } dp += deltap; } i += d; d += (it==0) ? 3 : 4; dt += deltat; } spp->addImpact(pos,tw); }