Main Page Class Hierarchy Compound List File List Compound Members File Members

Haar.cc

Go to the documentation of this file.
00001 /*
00002 File: Haar.cc
00003 
00004 Function: Implementation of the Haar basis
00005 
00006 Author: Andrew Willmott
00007 
00008 Notes: 
00009 */
00010 
00011 #include "Haar.h"
00012 #include "RadMethod.h"
00013 #include "gcl/Draw.h"
00014 
00015  #define DBG_COUT if (0) cerr
00016 
00017  #define RAD_SAMPLE_ERROR
00018 
00019 // --- HaarLink methods -------------------------------------------------------
00020 
00021 
00022  Bool HaarLink::CalcTransport()
00023 {
00024 if (gRadControl->quadLevel > 3)
00025 transport = From()->SampledFormFactor(8, To(), error);
00026 else
00027 {
00028 transport = From()->EstFormFactor(To());
00029 error = transport;
00030 }
00031 
00032 if (transport == 0.0 && error == 0.0)
00033 return(false);
00034 
00035 return(true);
00036 }
00037 
00038  Bool HaarLink::CalcVisibility(HRLink *parent, Bool reuse)
00039 {
00040 if (parent && (reuse || !NeedVisibility(parent)))
00041 visibility = parent->visibility;
00042 else
00043 visibility = From()->Visibility(To());
00044 
00045 transport *= visibility;
00046 
00047 return(true);
00048 }
00049 
00050  Void HaarLink::Gather()
00051 {
00052 To()->R += transport * From()->B;
00053 }
00054 
00055  GCLReal HaarLink::Error()
00056 {
00057 return(error);
00058 }
00059 
00060  GCLReal HaarLink::BFAError()
00061 {
00062 return(To()->area * error * 
00063 dot(kRadRGBToLum, To()->Reflectance() * From()->B));
00064 }
00065 
00066  Void HaarLink::Print(ostream &s)
00067 {
00068 HRLink::Print(s);
00069 s << transport << ' ' << visibility << ' ';
00070 }
00071 
00072  Void HaarLink::DrawLink(Renderer &r, GCLReal left, GCLReal top,
00073 GCLReal right, GCLReal bottom, GCLReal weight)
00074 {
00075 r.SetColour(To()->Reflectance() * transport * visibility * weight);
00076 
00077 PaintRect(r, Coord(left, top), Coord(right, bottom));
00078 }
00079 
00080 
00081 // --- HaarElem methods -------------------------------------------------------
00082 
00083 
00084 Colour HaarElem::lastB;
00085 
00086  Void HaarElem::Add()
00087 {
00088 B += R;
00089 }
00090 
00091  Void HaarElem::Push()
00092 {
00093 Int i;
00094 
00095 for (i = 0; i < 4; i++)
00096 Child(i)->B = B;
00097 }
00098 
00099  Void HaarElem::Pull()
00100 {
00101 Int i;
00102 
00103 B = vl_0;
00104 for (i = 0; i < 4; i++)
00105 B += Child(i)->B;
00106 B /= 4.0;
00107 }
00108 
00109  Void HaarElem::ClearB()
00110 {
00111 // Save B for comparison to post push/pull B
00112 lastB = B;
00113 // Initialise B to emittance of this patch.
00114 B = vl_0;
00115 }
00116 
00117  GCLReal HaarElem::Error()
00118 {
00119 return(dot(kRadRGBToLum, B - lastB));
00120 }
00121 
00122  Void HaarElem::ClearR()
00123 {
00124 R = vl_0;
00125 }
00126 
00127  Void HaarElem::CalcLeafRadiosity()
00128 {
00129 B = Emittance() + Reflectance() * B;
00130 }
00131 
00132  Void HaarElem::Print(ostream &s)
00133 {
00134 s << " + haar ";
00135 PrintRec(s);
00136 }
00137 
00138  Void HaarElem::PrintSelf(ostream &s)
00139 {
00140 HRMeshElem::PrintSelf(s);
00141 s << B << ' ';
00142 }
00143 
00144  Void HaarElem::ParseSelf(istream &s)
00145 {
00146 HRMeshElem::ParseSelf(s);
00147 s >> B;
00148 }
00149 
00150  Void HaarElem::SetParent(HierElem &itsParent)
00151 {
00152 HierElem::SetParent(itsParent);
00153 
00154 B = ((HaarElem &) itsParent).B; 
00155 }
00156 
00157  Colour HaarElem::SampleLeaf(Coord c)
00158 {
00159 
00160 if (gRadControl->gouraud)
00161 {
00162 Colour c1, c2;
00163 
00164 c1 = Mix(VtxClr(0), VtxClr(3), c[0]); 
00165 c2 = Mix(VtxClr(1), VtxClr(2), c[0]); 
00166 return(Mix(c2, c1, c[1]));
00167 }
00168 else
00169 return(B);
00170 }
00171 
00172  Void HaarElem::EltSampleTransport(
00173 Int numSamples,
00174 Point p[],
00175 Vector n[],
00176 Matd &coeffs
00177 )
00178 // find coeffs s.t. dot(from->B, coeffs) = irradiance
00179 // at p, n.
00180 {
00181 Int i;
00182 
00183 for (i = 0; i < numSamples; i++)
00184 coeffs[i][0] = ApproxPatchFactor(p[i], n[i]);
00185 DBG_COUT << "haar: sample coeffs = " << coeffs << endl;
00186 }
00187 
00188  GCLReal HaarElem::EltCalcTransport(HRElem *from, Matd &coeffs)
00189 {
00190 if (from == this)
00191 {
00192 // no self-reflection for haar...
00193 coeffs = vl_0;
00194 return(0.0);
00195 }
00196 
00197 #ifndef RAD_SAMPLE_ERROR
00198 from->EltSampleTransport(1, &centre, &normal, coeffs);
00199 DBG_COUT << "haar: transport coeffs = " << coeffs << endl;
00200 return(coeffs[0][0]);
00201 #else
00202 GCLReal error;
00203 Point p[16];
00204 Vector n[16];
00205 static Matd t;
00206 Int i, samples;
00207 
00208 #ifdef RAD_SC
00209 // sample at 3 or 4 corners and centre.
00210 
00211 for (i = 0; i < Sides(); i++)
00212 {
00213 p[i] = Vertex(i);
00214 n[i] = normal;
00215 }
00216 p[i] = centre;
00217 n[i] = normal;
00218 samples = i + 1;
00219 #else
00220 samples = 16;
00221 SetVisPoints(p);
00222 for (i = 0; i < 16; i++)
00223 n[i] = normal;
00224 #endif
00225 t.SetSize(samples, from->NumCoeffs());
00226 
00227 from->EltSampleTransport(samples, p, n, t);
00228 
00229 // find (Linf) error in samples
00230 error = VecError(col(t, 0));
00231 // average samples to get coeffs...
00232 coeffs[0] = t[0];
00233 for (i = 1; i < t.Rows(); i++)
00234 coeffs[0] += t[i];
00235 coeffs[0] /= t.Rows();
00236 
00237 return(error);
00238 #endif
00239 }
00240 
00241  Void HaarElem::AddIrradiance(const Colour &E, const Vector &m)
00242 {
00243 GCLReal temp;
00244 
00245 temp = dot(m, normal);
00246 if (temp > 0.0)
00247 R += temp * E;
00248 }
00249 
00250  Colour HaarElem::GetPower(const Vector &m)
00251 {
00252 return(B * EltProjArea(m));
00253 }
00254 
00255  Void HaarElem::DistributeColours()
00256 {
00257 SetColour(B);
00258 
00259 if (HasChildren())
00260 {
00261 Child(0)->DistributeColours();
00262 Child(1)->DistributeColours();
00263 Child(2)->DistributeColours();
00264 Child(3)->DistributeColours();
00265 }
00266 }
00267 
00268  Void HaarElem::DistributeColoursBest(ShadeInfo &shadeInfo)
00269 {
00270 if (gRadControl->bestLevels == 0)
00271 {
00272 // for now we return. eventually would like to resample at vertices
00273 // same as the clusters. (only perhaps avoiding duplicate samples.)
00274 DistributeColours();
00275 return;
00276 }
00277 
00278 // Here we apply the leaf element irradiances to the leaf face clusters
00279 
00280 if (!links.IsEmpty())
00281 shadeInfo.linkStack.Push(&links);
00282 
00283 if (IsLeaf() && shadeInfo.level >= gRadControl->bestLevels)
00284 {
00285 Int i, nlinks = 0;
00286 HRLinkIter l;
00287 
00288 Point centreOff, srcPt;
00289 Vector r;
00290 GCLReal dp, r2;
00291 Colour E;
00292 
00293 // find face's normal, pos & area in WCS
00294 
00295 centreOff = centre;
00296 centreOff += 1e-6 * normal;
00297 colour = cBlack;
00298 
00299 // traverse all links, do final gather
00300 for (i = 0; i < shadeInfo.linkStack.NumItems(); i++)
00301 for (l.Begin(*shadeInfo.linkStack[i]); !l.AtEnd(); l.Inc())
00302 {
00303 HRElem *src = l.Data().from;
00304 
00305 nlinks++; 
00306 srcPt = src->EltCentre();
00307 r = srcPt - centre;
00308 dp = dot(r, normal);
00309 r2 = sqrlen(r);
00310 
00311 if (dp > 0 && r2 > 0)
00312 {
00313 E = src->GetPower(-r);
00314 E *= dp / (sqr(r2) * vl_pi + src->EltArea());
00315 
00316 if (!gRadControl->bestVisPass)
00317 E *= l.Data().visibility;
00318 else
00319 {
00320 dp = l.Data().visibility;
00321 if (dp == 0.0)
00322 E = vl_0;
00323 else if (dp < 1.0) // dot(kRadRGBToLum, E) > 0.01
00324 {
00325 r /= sqrt(r2) * 1e6;
00326 srcPt -= r;
00327 if (gRadControl->radObject->
00328 IntersectsWithRay(srcPt, centreOff))
00329 E = vl_0;
00330 gRadControl->rays++;
00331 }
00332 else
00333 E *= dp;
00334 }
00335 colour += E * Reflectance();
00336 }
00337 }
00338 
00339 colour += Emittance();
00340 }
00341 else
00342 {
00343 Bool amSubdividing = IsLeaf();
00344 
00345 if (amSubdividing)
00346 {
00347 shadeInfo.level++;
00348 
00349 flags.Set(hrIntNode);
00350 if (!HasChildren())
00351 Subdivide();
00352 }
00353 
00354 Child(0)->DistributeColoursBest(shadeInfo);
00355 Child(1)->DistributeColoursBest(shadeInfo);
00356 Child(2)->DistributeColoursBest(shadeInfo);
00357 Child(3)->DistributeColoursBest(shadeInfo);
00358 
00359 if (amSubdividing)
00360 shadeInfo.level--;
00361 }
00362 
00363 if (!links.IsEmpty())
00364 shadeInfo.linkStack.Pop();
00365 }

Generated at Sat Aug 5 00:26:51 2000 for Radiator by doxygen 1.1.0 written by Dimitri van Heesch, © 1997-2000

AltStyle によって変換されたページ (->オリジナル) /