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

HRElem.cc

Go to the documentation of this file.
00001 /*
00002 File: HRElem.cc
00003 
00004 Function: Defines the element type used by the various hierarchical
00005 radiosity methods.
00006 
00007 Author: Andrew Willmott
00008 
00009 Notes: 
00010 */
00011 
00012 #include "HRElem.h"
00013 #include "RadMethod.h"
00014 #include "gcl/SceneLang.h"
00015 #include "gcl/GLRenderer.h"
00016 
00017 #ifdef RAD_VIS
00018 #include "gcl/ScenePane.h"
00019 #endif
00020 
00021 // --- HRElem methods ---------------------------------------------------------
00022 
00023 UInt32 HRElem::gID = 0;
00024 
00025  HRElem::HRElem() :
00026 #ifdef RAD_VIS
00027 eltParent(0),
00028 eltHighlight(0),
00029 #endif
00030 id(gID++),
00031 flags()
00032 {
00033 } 
00034 
00035  HRElem::~HRElem()
00036 {
00037 Reset();
00038 }
00039 
00040  Void HRElem::Reset()
00041 {
00042 links.Free();
00043 }
00044 
00045  Void HRElem::DrawElem(Renderer &r)
00046 {
00047 DrawNodeElem(r);
00048 }
00049 
00050 // XXX shift?
00051 
00052  Void DrawArrow(Renderer &r, Point start, Point end)
00053 {
00054 static scPrimitive *sCone = 0;
00055 static scPrimitive *sShaft = 0;
00056 const Double ac = 0.1;
00057 const Double as = ac / 5.0;
00058 
00059 GCLReal al = len(end - start);
00060 GLRenderer &glr = (GLRenderer &) r;
00061 Transform trans;
00062 
00063 if (al < 1e-15)
00064 return;
00065 
00066 if (!sCone)
00067 {
00068 sCone = slGetLibrary()->Member("cone");
00069 sShaft = slGetLibrary()->Member("cylinder");
00070 }
00071 
00072 glr.SetHeadlight(true);
00073 
00074 #ifdef OFF
00075 r.C(cYellow).Begin(renLines);
00076 r.P(start).P(end);
00077 r.End();
00078 #endif
00079 
00080 r.C(cWhite);
00081 r.Push();
00082 trans = Shift(end) * AlignToDir(end - start);
00083 r.SetTransform(trans);
00084 
00085 r.Push();
00086 trans = Shift(-ac * Vector(vl_y)) * Scale(Vector(as, al - ac, as)) * Shift(-0.5 * Vector(vl_y));
00087 r.SetTransform(trans);
00088 sShaft->Draw(r);
00089 r.Pop();
00090 
00091 r.Push();
00092 trans = Scalef(ac) * Shift(-Vector(vl_y));
00093 r.SetTransform(trans);
00094 sCone->Draw(r);
00095 r.Pop();
00096 
00097 r.Pop();
00098 glr.SetHeadlight(false);
00099 }
00100 
00101  Void HRElem::DrawContributors(Renderer &r)
00102 {
00103 HRLinkIter iter;
00104 
00105 for (iter.Begin(links); !iter.AtEnd(); iter.Inc())
00106 DrawArrow(r, iter.Data().from->EltCentre(), iter.Data().to->EltCentre());
00107 
00108 for (iter.Begin(links); !iter.AtEnd(); iter.Inc())
00109 {
00110 iter.Data().from->DrawLeafElem(r);
00111 iter.Data().from->flags.Set(hrMark);
00112 }
00113 }
00114 
00115  Void HRElem::DrawContributorsRec(Void *r)
00116 {
00117 Int i;
00118 
00119 DrawContributors(*(Renderer*) r);
00120 ApplyToChildren(&HRElem::DrawContributorsRec, r);
00121 }
00122 
00123  Void HRElem::DrawMatrix(Renderer &r, Int baseNum)
00124 {
00125 DMInfo info;
00126 
00127 info.r = &r;
00128 info.baseNum = baseNum;
00129 DrawMatrixRec(&info);
00130 }
00131 
00132  Void HRElem::DrawMatrixRec(Void *dmi)
00133 {
00134 }
00135 
00136  Void HRElem::DistributeColours()
00137 {
00138 }
00139 
00140  Void HRElem::DistributeColoursBest(ShadeInfo &shadeInfo)
00141 {
00142 }
00143 
00144 // --- Link Refinement --------------------------------------------------------
00145 
00146 //#define RAD_VIS_LINKS
00147 // doesn't seem to have turned out to be all that useful?
00148 
00149  Bool HRElem::RefineLink(HRLink *link, Int levels)
00152 {
00153 Int i, j, which;
00154 GCLReal factor, visibility;
00155 
00156 // CreateSubLink() returns null if the link carries no energy, so
00157 // return if that's the case.
00158 if (link == 0)
00159 return(false);
00160 
00161 if (levels-- == 0)
00162 {
00163 links.Prepend(link);
00164 return(false);
00165 }
00166 
00167 which = link->RefineOracle();
00168 
00169 #ifdef RAD_VIS_LINKS
00170 if (gRadControl->showLinks)
00171 {
00172 RM_DISPLAY_START;
00173 gRadControl->radObject->display->Begin(renLines);
00174 }
00175 #endif
00176 
00177 if (which == kSubNone) // Form link here.
00178 {
00179 links.Prepend(link);
00180 
00181 #ifdef RAD_VIS_LINKS
00182 if (gRadControl->showLinks)
00183 {
00184 gRadControl->radObject->display->
00185 C(cRed).P(EltCentre()).P(link->from->EltCentre()).End();
00186 RM_DISPLAY_END;
00187 RM_OUT1("Forming link here.");
00188 if (RM_PAUSE) return(false);
00189 }
00190 #endif
00191 return(false);
00192 }
00193 else if (which == kSubTo) // Subdivide 'to' patch (this one!)
00194 {
00195 #ifdef RAD_VIS_LINKS
00196 if (gRadControl->showLinks)
00197 {
00198 gRadControl->radObject->display->
00199 C(cGreen).P(EltCentre()).P(link->from->EltCentre());
00200 RM_DISPLAY_END;
00201 RM_OUT1("Pushing link down to children of receiver");
00202 if (RM_PAUSE) return(false);
00203 }
00204 #endif 
00205 MakeChildLinks(link->from, link, which, levels);
00206 }
00207 else if (which == kSubFrom) // Subdivide 'from' patch
00208 {
00209 #ifdef RAD_VIS_LINKS
00210 if (gRadControl->showLinks)
00211 {
00212 gRadControl->radObject->display->
00213 C(cBlue).P(EltCentre()).P(link->from->EltCentre()).End();
00214 RM_DISPLAY_END;
00215 RM_OUT1("Pushing link down to children of source");
00216 if (RM_PAUSE) return(false);
00217 }
00218 #endif
00219 link->from->MakeChildLinks(this, link, which, levels);
00220 } 
00221 else if (which == kSubBoth) // Subdivide both patches
00222 {
00223 #ifdef RAD_VIS_LINKS
00224 if (gRadControl->showLinks)
00225 {
00226 gRadControl->radObject->display->
00227 C(cYellow).P(EltCentre()).P(link->from->EltCentre()).End();
00228 RM_DISPLAY_END;
00229 RM_OUT1("Pushing link down to children of source & dest");
00230 if (RM_PAUSE) return(false);
00231 }
00232 #endif
00233 MakeChildLinks(link->from, link, which, levels);
00234 } 
00235 
00236 link->FreeLink(link);
00237 
00238 return(true);
00239 }
00240 
00241  Bool HRElem::Refine()
00244 {
00245 Bool result = false;
00246 RefineFurther(&result);
00247 return(result);
00248 }
00249 
00250  Void HRElem::RefineFurther(Void *result)
00251 {
00252 HRLinkIter i;
00253 Int j, which;
00254 Bool split;
00255 HRLinkList oldLinks;
00256 HRLink *tempLink, *rlink;
00257 
00258 // bottom-up traversal to avoid refining a link more than once.
00259 ApplyToChildren(&HRElem::RefineFurther, result);
00260 
00261 rlink = (HRLink*) links.first;
00262 links.first = 0;
00263 
00264 // Step through links, see whether any should be pushed down the hierarchy.
00265 while (rlink)
00266 {
00267 tempLink = rlink;
00268 rlink = (HRLink*) rlink->next;
00269 if (RefineLink(tempLink, gRadControl->refineLevels))
00270 *(Bool*) result = true;
00271 }
00272 }
00273 
00274  Void HRStats::Init()
00275 {
00276 numLinks = 0;
00277 numPatches = 0;
00278 numVolClusters = 0;
00279 numFaceClusters = 0;
00280 numAliens = 0;
00281 }
00282 
00283  Void HRElem::CalcStats(Void *statsIn)
00284 {
00285 HRLinkIter i;
00286 HRStats *stats = (HRStats*) statsIn;
00287 
00288 for (i.Begin(links); !i.AtEnd(); i.Inc())
00289 stats->numLinks++;
00290 
00291 if (IsPatch())
00292 stats->numPatches++; 
00293 else if (IsCluster())
00294 stats->numVolClusters++;
00295 else if (IsFaceClus())
00296 stats->numFaceClusters++;
00297 else
00298 stats->numAliens++;
00299 
00300 ApplyToChildren(&HRElem::CalcStats, statsIn);
00301 }
00302 
00303 ostream *HRElem::out = &cout;
00304 
00305  Void HRElem::DumpHierarchy(Void *v)
00306 // dump the element hierarchy 
00307 {
00308 if (v)
00309 {
00310 // just printing a list of child IDs
00311 *out << id << ' ';
00312 return;
00313 }
00314 
00315 // dump from leaves to root
00316 ApplyToChildren(&HRElem::DumpHierarchy); 
00317 
00318 HRLinkIter i;
00319 // elt. format: e ID [childID1 childID2...]
00320 *out << "e " << id << ' ';
00321 ApplyToChildren(&HRElem::DumpHierarchy, this);
00322 *out << endl;
00323 // link format: L toEltID fromEltID transferCoeff
00324 for (i.Begin(links); !i.AtEnd(); i.Inc())
00325 *out << "L " << id << " " << i.Data().from->id 
00326 << ' ' << i.Data().Strength() << endl;
00327 }
00328 
00329  Void HRElem::Gather()
00330 {
00331 HRLinkIter i;
00332 
00333 ClearR();
00334 
00335 for (i.Begin(links); !i.AtEnd(); i.Inc())
00336 {
00337 i.Data().Gather();
00338 
00339 #ifdef RAD_VIS_LINKS
00340 // YYY replace with arrow sometime?
00341 if (gRadControl->showLinks)
00342 gRadControl->radObject->display->Begin(renLines)
00343 .C(cRed).P(EltCentre()).P(i.Data().from->EltCentre())
00344 .End();
00345 #endif
00346 }
00347 }
00348 
00349  Void HRElem::GatherAll(Void *)
00350 {
00351 ApplyToChildren(&HRElem::GatherAll);
00352 Gather(); // Gather radiosity across all links to this patch into R
00353 }
00354 
00355 #ifdef RAD_VIS
00356 
00357 Void HRElem::PushPull(Void *)
00358 {
00359 Int i;
00360 
00361 if (gRadControl->animate)
00362 {
00363 SetHighlight(0);
00364 if (RM_PAUSE) return;
00365 }
00366 
00367 Add();
00368 
00369 if (gRadControl->animate)
00370 RM_DISPLAY_SCENE;
00371 
00372 if (!IsLeaf())
00373 {
00374 if (gRadControl->animate)
00375 {
00376 if (RM_PAUSE) return;
00377 }
00378 
00379 Push();
00380 
00381 ApplyToChildren(&HRElem::PushPull);
00382 
00383 if (gRadControl->animate)
00384 {
00385 SetHighlight(1);
00386 SetHighlight(0);
00387 
00388 if (RM_PAUSE) return;
00389 }
00390 
00391 Pull();
00392 
00393 if (gRadControl->animate)
00394 RM_DISPLAY_SCENE;
00395 }
00396 else
00397 CalcLeafRadiosity();
00398 }
00399 
00400 #else
00401 
00402  Void HRElem::PushPull(Void *)
00403 {
00404 Int i;
00405 
00406 // Add R in to B: accumulated radiosity from this and higher levels
00407 Add(); 
00408 
00409 if (!IsLeaf())
00410 { 
00411 // Push B down to children's B's
00412 Push(); 
00413 // recurse
00414 ApplyToChildren(&HRElem::PushPull);
00415 // Pull radiosity back up
00416 Pull();
00417 }
00418 else
00419 CalcLeafRadiosity();
00420 }
00421 #endif
00422 
00423  GCLReal HRElem::EltVisToPoint(Point &p)
00424 {
00425 Int i, misses;
00426 Point srcPoint[16];
00427 Bool hit;
00428 
00429 if (gRadControl->visibility == vis_none)
00430 return(1.0);
00431 
00432 misses = 0;
00433 EltSetVisPoints(0, srcPoint);
00434 
00435 #ifdef RAD_VIS
00436 if (gRadControl->showRays)
00437 RM_DISPLAY_START;
00438 #endif
00439 
00440 gRadControl->rays += 16;
00441 
00442 for (i = 0; i < 16; i++)
00443 {
00444 hit = gRadControl->radObject->IntersectsWithRay(srcPoint[i], p);
00445 
00446 if (hit)
00447 misses++;
00448 
00449 #ifdef RAD_VIS
00450 if (gRadControl->showRays)
00451 {
00452 if (hit)
00453 gRadControl->radObject->display->Begin(renLines).C(cRed).P(srcPoint[i]).
00454 P(p).End();
00455 else
00456 gRadControl->radObject->display->Begin(renLines).C(cGreen).P(srcPoint[i]).
00457 P(p).End();
00458 }
00459 #endif
00460 }
00461 
00462 #ifdef RAD_VIS
00463 if (gRadControl->showRays)
00464 {
00465 RM_DISPLAY_END;
00466 RM_OUT1("Visibility: " << GCLReal(16 - misses) * 1.0 / 16.0);
00467 if (RM_PAUSE) return(0);
00468 }
00469 #endif
00470 
00471 return((16 - misses) * (1.0 / 16.0));
00472 }
00473 
00474  GCLReal HRElem::EltVis(HRElem *to)
00475 {
00476 Int i, misses;
00477 Point srcPoint[16], dstPoint[16];
00478 Bool hit;
00479 
00480 if (gRadControl->visibility == vis_none || to == this)
00481 return(1.0);
00482 
00483 misses = 0;
00484 EltSetVisPoints(to, srcPoint);
00485 to->EltSetVisPoints(this, dstPoint);
00486 
00487 #ifdef RAD_VIS
00488 if (gRadControl->showRays)
00489 RM_DISPLAY_START;
00490 #endif
00491 
00492 gRadControl->rays += 16;
00493 
00494 for (i = 0; i < 16; i++)
00495 {
00496 hit = gRadControl->radObject->IntersectsWithRay(srcPoint[i], dstPoint[i]);
00497 
00498 if (hit)
00499 misses++;
00500 
00501 #ifdef RAD_VIS
00502 if (gRadControl->showRays)
00503 {
00504 if (hit)
00505 gRadControl->radObject->display->Begin(renLines).C(cRed).P(srcPoint[i]).
00506 P(dstPoint[i]).End();
00507 else
00508 gRadControl->radObject->display->Begin(renLines).C(cGreen).P(srcPoint[i]).
00509 P(dstPoint[i]).End();
00510 }
00511 #endif
00512 }
00513 
00514 #ifdef RAD_VIS
00515 if (gRadControl->showRays)
00516 {
00517 RM_DISPLAY_END;
00518 RM_OUT1("Visibility: " << GCLReal(16 - misses) * 1.0 / 16.0);
00519 if (RM_PAUSE) return(0);
00520 }
00521 #endif
00522 
00523 return((16 - misses) * (1.0 / 16.0));
00524 }
00525 
00526  Colour HRElem::EltBA()
00528 {
00529 return(B_Coeffs()[0] * EltArea());
00530 }
00531 
00532  Void HRElem::InitRad()
00533 {
00534 ClearB();
00535 CalcLeafRadiosity();
00536 }
00537 
00538  Void HRElem::AddChanIrradiance(const Colour &E, Int chan)
00539 {
00540 Colour c(vl_0);
00541 Vector m;
00542 
00543 c[chan] = 1.0;
00544 ConvertVec(E, m);
00545 
00546 AddIrradiance(c, m);
00547 }
00548 
00549  GCLReal HRElem::EltMaxProjArea(const Vector &v)
00550 {
00551 return(EltProjArea(v));
00552 }
00553 
00554  Void HRElem::DebugInfo()
00555 {
00556 HRLinkIter i;
00557 
00558 cout << "radiosity = " << B_Coeffs()[0] << endl;
00559 cout << "rho = " << EltRho() << endl;
00560 cout << "flags = " << flags << endl;
00561 for (i.Begin(links); !i.AtEnd(); i.Inc())
00562 i.Data().DebugInfo();
00563 }
00564 
00565 
00566  GCLReal VecError(const SubVecd &v)
00567 {
00568 GCLReal min, max;
00569 Int i;
00570 
00571 if (v[0] < v[1])
00572 {
00573 min = v[0];
00574 max = v[1];
00575 }
00576 else
00577 {
00578 min = v[1];
00579 max = v[0];
00580 }
00581 
00582 for (i = 2; i < v.Elts(); i++)
00583 if (v[i] < min)
00584 min = v[i];
00585 else if (v[i] > max)
00586 max = v[i];
00587 
00588 return(max - min);
00589 }
00590 
00591 
00592  ShadeInfo::ShadeInfo() : linkStack(), level(0), data(0)
00593 {
00594 }
00595 

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

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