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

HProgRad.cc

Go to the documentation of this file.
00001 /*
00002 File: HProgRad.cc
00003 
00004 Function: See header file
00005 
00006 Author(s): Andrew Willmott
00007 
00008 Copyright: (c) 1999-2000, Andrew Willmott
00009 
00010 Notes: 
00011 
00012 Change History:
00013 */
00014 
00015 #include "HProgRad.h"
00016 #include "HierMesh.h"
00017 #include "gcl/Draw.h"
00018 
00019 
00020  Void HProgRad::ResetOptions()
00021 {
00022 Int i;
00023 
00024 CreatePatches();
00025 
00026 elements.Clear();
00027 eltParents.Clear();
00028 
00029 for (i = 0; i < patches.NumItems(); i++)
00030 ((HierElem *) patches[i])->CreateElements(elements, eltParents, i); 
00031 
00032 ColourMeshInitial();
00033 ColourVertices();
00034 
00035 #ifdef RAD_VIS
00036 Field(out1) << patches.NumItems() << " patches, " << 
00037 elements.NumItems() << " elements." << show;
00038 #endif
00039 }
00040 
00041  static Colour SingleFormFactor(RadElem *fromPatch, RadElem *toPatch)
00042 {
00043 GCLReal visibility;
00044 GCLReal factor;
00045 Colour result;
00046 
00047 if (len(toPatch->Reflectance()) < 0.0001)
00048 {
00049 result.MakeZero();
00050 return(result);
00051 }
00052 
00053 visibility = fromPatch->Visibility(toPatch);
00054 
00055 if (visibility > 0.0)
00056 {
00057 factor = fromPatch->EstFormFactor(toPatch);
00058 result = toPatch->Reflectance();
00059 result *= factor * visibility;
00060 }
00061 else
00062 result.MakeZero();
00063 
00064 return(result);
00065 }
00066 
00067 
00068  Bool HProgRad::Render()
00069 {
00070 Int i, j;
00071 Colour c;
00072 Colour deltaRad;
00073 Colour radToShoot;
00074 Bool subdivided;
00075 Int numElts = elements.NumItems();
00076 Int numPatches = patches.NumItems();
00077 GCLReal power, envArea;
00078 Colour envPower, envRefl;
00079 Bool finished = false; 
00080 RadElem *shootPatch;
00081 ColourList *theFFRow;
00082 
00083 RadMethod::Render();
00084 
00085 iterations = 0;
00086 error = 1.0;
00087 origShoot = 0;
00088 
00089 B.SetSize(numElts); // Radiosity vectors for R, G, B
00090 S.SetSize(numPatches); // Unshot radiosity vectors for R, G, B
00091 
00092 for (i = 0; i < patches.NumItems(); i++)
00093 S[i] = patches[i]->Emittance();
00094 
00095 for (i = 0; i < numElts; i++)
00096 B[i] = S[eltParents[i]];
00097 
00098 envRad = vl_1;
00099 
00100 if (Stage(1)) return(0);
00101 
00102 // Setup for the ambient term
00103 
00104 envRefl.MakeZero();
00105 envArea = 0;
00106 envPower.MakeZero();
00107 
00108 for (i = 0; i < numPatches; i++)
00109 {
00110 envRefl += patches[i]->area * patches[i]->Reflectance();
00111 envArea += patches[i]->area; 
00112 envPower += S[i] * patches[i]->area;
00113 }
00114 
00115 envPower /= envArea;
00116 
00117 // R = 1 / (1 - avgReflectance)
00118 
00119 for (i = 0; i < 3; i++)
00120 envRefl[i] = 1.0 / (1.0 - envRefl[i] / envArea);
00121 
00122 // Now, run the algorithm...
00123 
00124 while (!finished)
00125 { 
00126 if (Stage(2)) return(0);
00127 
00128 iterations++;
00129 
00130 // Find the patch with the max power to shoot...
00131 
00132 maxPower = 0;
00133 maxPowerIndex = 0;
00134 envPower.MakeZero();
00135 
00136 for (i = 0; i < numPatches; i++) 
00137 {
00138 c = S[i] * patches[i]->area; 
00139 power = dot(c, kRadRGBToLum);
00140 
00141 if (maxPower < power)
00142 {
00143 maxPower = power;
00144 maxPowerIndex = i;
00145 }
00146 }
00147 
00148 radToShoot = S[maxPowerIndex];
00149 radToShoot *= gRadControl->alpha;
00150 shootPatch = patches[maxPowerIndex];
00151 
00152 if (Stage(3)) return(0);
00153 
00154 // Find initial form factors
00155 #ifdef RAD_VIS
00156 if (gRadControl->drawMatrix)
00157 {
00158 if (maxPowerIndex >= FFElts.NumItems())
00159 FFElts.SetSize(maxPowerIndex + 1);
00160 FFElts[maxPowerIndex] = elements;
00161 
00162 theFFRow = &FFRows[maxPowerIndex];
00163 }
00164 else
00165 #endif
00166 theFFRow = &FFRow;
00167 MakeFormFactorFromVector(*shootPatch, elements, *theFFRow);
00168 
00169 if (Stage(4)) return(0); 
00170 
00171 // Shoot radiosity, updating S and B as necessary 
00172 error = 0;
00173 S[maxPowerIndex] -= radToShoot;
00174 
00175 for (i = 0; i < numElts; i++)
00176 {
00177 deltaRad = (*theFFRow)[i] * radToShoot;
00178 B[i] += deltaRad;
00179 
00180 // Push radiosity delta to the parent... 
00181 S[eltParents[i]] += deltaRad * (elements[i]->area 
00182 / patches[eltParents[i]]->area);
00183 error += sqrlen(deltaRad);
00184 }
00185 
00186 error = sqrt(error);
00187 
00188 // Calculate ambient light in scene...
00189 
00190 if (gRadControl->ambient)
00191 {
00192 envPower = vl_0;
00193 for (i = 0; i < numPatches; i++)
00194 envPower += S[i] * patches[i]->area;
00195 
00196 envPower /= envArea;
00197 envRad = envRefl * envPower;
00198 }
00199 else
00200 envRad.MakeZero();
00201 
00202 if (true) // was multigrid option???
00203 do 
00204 { 
00205 Colour oldFF, f0, f1, f2, f3, temp;
00206 
00207 // Subdivide receiving elements as necessary...
00208 
00209 subdivided = false;
00210 
00211 // Distribute radiosity to vertices so we can measure error
00212 for (i = 0; i < numElts; i++)
00213 ((HierElem *) elements[i])->SetColour(
00214 B[i] + envRad * elements[i]->Reflectance());
00215 ColourVertices();
00216 
00217 if (Stage(5)) return(0);
00218 
00219 for (i = 0; i < numElts; i++)
00220 {
00221 HierElem *old = (HierElem *) elements[i];
00222 
00223 if (old->area >= gRadControl->kAError &&
00224 old->RadError() > gRadControl->kFError)
00225 {
00226 // We need to subdivide
00227 
00228 if (!old->HasChildren())
00229 old->Subdivide();
00230 
00231 // Replace elt with its subdivisions...
00232 elements[i] = old->child[0]; 
00233 elements.Append(old->child[1]);
00234 elements.Append(old->child[2]);
00235 elements.Append(old->child[3]);
00236 
00237 j = eltParents[i];
00238 eltParents.Append(j);
00239 eltParents.Append(j);
00240 eltParents.Append(j);
00241 
00242 // Generate new form factors to the children...
00243 f0 = SingleFormFactor(shootPatch, old->child[0]);
00244 f1 = SingleFormFactor(shootPatch, old->child[1]);
00245 f2 = SingleFormFactor(shootPatch, old->child[2]);
00246 f3 = SingleFormFactor(shootPatch, old->child[3]);
00247 oldFF = (*theFFRow)[i];
00248 
00249 theFFRow->Item(i) = f0;
00250 theFFRow->Append(f1);
00251 theFFRow->Append(f2);
00252 theFFRow->Append(f3);
00253 
00254 // update contribution to parent... 
00255 temp = f0 * old->child[0]->area 
00256 + f1 * old->child[1]->area 
00257 + f2 * old->child[2]->area 
00258 + f3 * old->child[3]->area 
00259 - oldFF * old->area;
00260 S[j] += radToShoot * (temp / patches[j]->area);
00261 
00262 // update child radiosities... 
00263 B.Append(B[i] + radToShoot * (f1 - oldFF));
00264 B.Append(B[i] + radToShoot * (f2 - oldFF));
00265 B.Append(B[i] + radToShoot * (f3 - oldFF));
00266 B[i] += radToShoot * (f0 - oldFF);
00267 
00268 subdivided = true;
00269 } 
00270 }
00271 numElts = elements.NumItems();
00272 #ifdef RAD_VIS
00273 if (maxPowerIndex >= FFElts.NumItems())
00274 FFElts.SetSize(maxPowerIndex + 1);
00275 FFElts[maxPowerIndex] = elements;
00276 #endif 
00277 
00278 Stage(6);
00279 } 
00280 while (subdivided);
00281 
00282 // Stop us before we shoot again
00283 
00284 if (iterations == 1)
00285 origShoot = maxPower;
00286 else
00287 finished = 
00288 (gRadControl->maxShots > 0 && iterations > gRadControl->maxShots)
00289 || (maxPower < gRadControl->error * origShoot);
00290 
00291 if (Stage(7)) return(0);
00292 } 
00293 
00294 if (Stage(8)) return(0);
00295 
00296 return(1);
00297 }
00298 
00299 
00300 #ifdef RAD_VIS
00301 
00302 Void HProgRad::DumpStats(){}
00303 
00304 Int HProgRad::Stage(Int stage)
00305 {
00306 Int i, j;
00307 Bool animate = gRadControl->animate || gRadControl->pause;
00308 
00309 switch (stage)
00310 {
00311 case 1: // pre setup
00312 Field(out3) << patches.NumItems() << " patches, " 
00313 << elements.NumItems() << " elements." << show;
00314 Field(out1) << "Forming emission vector E..." << show;
00315 FFRow.Clear();
00316 FFElts.Clear();
00317 if (gRadControl->drawMatrix)
00318 {
00319 FFRows.SetSize(patches.NumItems());
00320 FFElts.SetSize(patches.NumItems());
00321 // FFRows.ClearTo(ColourList());
00322 // FFElts.ClearTo(PatchList());
00323 }
00324 StartUpdate();
00325 break;
00326 
00327 case 2: // post setup
00328 ColourVertices();
00329 display->Redraw();
00330 
00331 doUpdate = animate || Update();
00332 
00333 if (animate)
00334 Field(out1) << "Finding patch to shoot..." << show;
00335 else if (doUpdate)
00336 {
00337 Char *plural;
00338 if (iterations == 1)
00339 plural = "";
00340 else
00341 plural = "es";
00342 Field(out1) << iterations << " patch" << plural << " shot" << show;
00343 
00344 } 
00345 break;
00346 
00347 case 3: 
00348 if (doUpdate)
00349 {
00350 if (animate)
00351 {
00352 Field(out1) << "Finding factors for patch " << maxPowerIndex 
00353 << show;
00354 
00355 // flash shooting patch red
00356 patches[maxPowerIndex]->SetHighlight(1);
00357 }
00358 
00359 ColourVertices();
00360 display->Redraw(); 
00361 }
00362 break;
00363 
00364 case 4:
00365 if (doUpdate)
00366 {
00367 if (animate)
00368 Field(out1) << "Shooting patch " << maxPowerIndex << show;
00369 RenderMatrix();
00370 display->Redraw(); 
00371 }
00372 break;
00373 
00374 case 5: 
00375 if (animate)
00376 Field(out1) << "Looking for elements to subdivide..." << show;
00377 if (doUpdate)
00378 display->Redraw();
00379 break;
00380 
00381 case 6: 
00382 if (doUpdate)
00383 {
00384 display->Redraw();
00385 UpdateCont();
00386 }
00387 if (animate)
00388 Field(out1) << "Re-shooting Patch " << maxPowerIndex << show;
00389 Field(out2) << "error = " << maxPower / origShoot 
00390 << ", RMS Error = " << error << show;
00391 Field(out3) << patches.NumItems() << " patches, " 
00392 << elements.NumItems() << " elements." << show;
00393 break;
00394 
00395 case 7: // Middle of solve loop.
00396 if (doUpdate)
00397 {
00398 Colour c;
00399 
00400 patches[maxPowerIndex]->SetHighlight(0);
00401 
00402 if (gRadControl->shotDisplay)
00403 // Colour the elements according to S...
00404 for (i = 0; i < elements.NumItems(); i++)
00405 ((HierElem*) elements[i])->SetColour(S[eltParents[i]]);
00406 else
00407 // Colour the elements according to B...
00408 for (i = 0; i < elements.NumItems(); i++)
00409 ((HierElem*) elements[i])->
00410 SetColour(B[i] + envRad * elements[i]->Reflectance());
00411 
00412 ColourVertices();
00413 display->Redraw();
00414 
00415 if (animate)
00416 {
00417 Field(out1) << "Done with shooting " << show;
00418 Field(out3) << patches.NumItems() << " patches, " 
00419 << elements.NumItems() << " elements." << show;
00420 
00421 Field(out2) << "error = " << maxPower / origShoot 
00422 << ", RMS Error = " << error << show;
00423 }
00424 UpdateCont();
00425 }
00426 break;
00427 
00428 case 8:
00429 Field(out1) << "Finished: " << iterations << " patches shot" << show;
00430 
00431 // Colour the elements according to B...
00432 for (i = 0; i < elements.NumItems(); i++)
00433 ((HierElem*) elements[i])->SetColour(B[i] + envRad 
00434 * elements[i]->Reflectance());
00435 ColourVertices();
00436 break;
00437 }
00438 
00439 return(Pause());
00440 }
00441 
00442 #else
00443 
00444  Void HProgRad::DumpStats()
00445 {
00446 Int i, j;
00447 Colour c;
00448 GCLReal shotErr, mem;
00449 
00450 if (origShoot == 0.0)
00451 shotErr = 1.0;
00452 else
00453 shotErr = maxPower / origShoot;
00454 
00455 mem = sizeof(Colour) * (B.NumItems() + S.NumItems() + FFRow.NumItems()
00456 + elements.NumItems()) + sizeof(Int) * eltParents.NumItems();
00457 mem /= 1024.0;
00458 
00459 cout << dumpID
00460 << ' ' << totTime
00461 << ' ' << gRadControl->stage
00462 << ' ' << patches.NumItems()
00463 << ' ' << elements.NumItems()
00464 
00465 << ' ' << shotErr
00466 << ' ' << error
00467 << ' ' << gRadControl->rays
00468 << ' ' << iterations
00469 << ' ' << mem
00470 << ' ' << grid->MemoryUsage()
00471 << ' ' << TotalMemoryUse()
00472 << endl;
00473 
00474 for (i = 0; i < elements.NumItems(); i++) // Colour the elements...
00475 ((HierElem*) elements[i])->SetColour(B[i] + 
00476 envRad * elements[i]->Reflectance());
00477 
00478 DumpScene();
00479 #ifdef RAD_MEM_USE
00480 DumpMemoryUse();
00481 #endif
00482 }
00483 
00484  Int HProgRad::Stage(Int stage)
00485 {
00486 if (CheckTime()) return(1);
00487 
00488 gRadControl->stage = stage;
00489 
00490 switch (stage)
00491 {
00492 case 1: // pre setup
00493 cout << "method hprog " << endl;
00494 cout << "sub " << gRadControl->patchSubdivs << endl;
00495 cout << "esub " << gRadControl->eltSubdivs << endl;
00496 cout << "tErr " << gRadControl->error << endl;
00497 cout << "fErr " << gRadControl->kFError << endl;
00498 cout << "aErr " << gRadControl->kAError << endl;
00499 cout << "scene " << sceneName << endl;
00500 cout << "polys " << gRadControl->numPolys << endl;
00501 cout << "srcPatches " << patches.NumItems() << endl;
00502 cout << "format "
00503 << "ID "
00504 << "time "
00505 << "stage "
00506 << "srcPatches "
00507 << "patches "
00508 << "shootErr "
00509 << "resErr "
00510 << "rays "
00511 << "iterations "
00512 << "mem "
00513 << "rtMem "
00514 << "rss "
00515 << endl;
00516 
00517 cout << "----------------------------------------------"
00518 << "---------------------------------" << endl;
00519 
00520 DumpStats();
00521 break;
00522 
00523 case 8:
00524 DumpStats();
00525 break;
00526 }
00527 
00528 if (Idle()) return(1);
00529 timer.ContTimer();
00530 return(0);
00531 }
00532 
00533 #endif
00534 
00535  Void HProgRad::DrawMatrix(Renderer &r)
00536 {
00537 if (!gRadControl->drawMatrix || gRadControl->stop)
00538 return;
00539 
00540 #ifdef RAD_VIS
00541 Int i, j;
00542 GCLReal x1, x2, y1, y2, wx, wy, m;
00543 HierElem *hq;
00544 
00545 wx = 2.0 / FFRows.NumItems();
00546 
00547 x1 = -1;
00548 x2 = wx - 1;
00549 
00550 for (i = 0; i < FFRows.NumItems(); i++)
00551 {
00552 y2 = 1;
00553 
00554 // Draw a column
00555 
00556 for (j = 0; j < FFRows[i].NumItems(); j++)
00557 {
00558 hq = (HierElem*) FFElts[i][j];
00559 y2 = 1 - 2 * GCLReal(eltParents[j]) / GCLReal(patches.NumItems());
00560 
00561 wy = 2.0 / GCLReal(patches.NumItems());
00562 m = GCLReal(1 << (2 * hq->level));
00563 wy /= m;
00564 
00565 y2 -= GCLReal(hq->treeCode) * wy; 
00566 y1 = y2 - wy;
00567 
00568 if (hq->highlight == 2 && patches[i]->highlight == 3)
00569 r.C(cPurple);
00570 else if (hq->highlight == 2)
00571 r.C(cYellow);
00572 else if (patches[i]->highlight == 3)
00573 r.C(cGreen);
00574 else 
00575 r.C(FFRows.NumItems() * FFRows[i][j]);
00576 
00577 PaintRect(r, Coord(x1, y1), Coord(x2, y2)); 
00578 
00579 y2 = y1;
00580 }
00581 
00582 x1 += wx;
00583 x2 += wx;
00584 }
00585 #endif
00586 }
00587 
00588  RadElem *HProgRad::NewMesh()
00589 {
00590 if (gRadControl->noGridMesh)
00591 return(new HierElem());
00592 else
00593 return(new HierGrid());
00594 }
00595 
00596  Void HProgRad::ColourVertices()
00597 {
00598 Int i;
00599 
00600 for (i = 0; i < elements.NumItems(); i++)
00601 ((HierElem*) elements[i])->CorrectLeaves();
00602 
00603 RadMethod::ColourVertices();
00604 }
00605 
00606  PatchList *HProgRad::GetElements()
00607 {
00608 Int i, j, n, numElems, numSplitElems = 0;
00609 HierElemPtr subElems[5];
00610 
00611 // Make the mesh compliant, if it's been tesselated.
00612 
00613 ColourVertices();
00614 
00615 if (gRadControl->anchor)
00616 {
00617 n = elements.NumItems();
00618 for (i = 0; i < n; i++)
00619 {
00620 ((HierElemPtr) elements[i])->SplitElement(numElems, subElems);
00621 
00622 if (numElems > 0)
00623 {
00624 numSplitElems++;
00625 
00626 
00627 elements[i] = subElems[0];
00628 for (j = 1; j < numElems; j++)
00629 elements.Append(subElems[j]);
00630 }
00631 }
00632 
00633 }
00634 
00635 return(&elements);
00636 }
00637 
00638  Void HProgRad::DumpMemoryUse()
00639 {
00640 Float propmem, bmem, bpmem, pmem, emem, semem, epmem, total;
00641 Float ptmem, clrmem, rtmem;
00642 Int i;
00643 Char *fmt = "%+10s %10.1f\n";
00644 
00645 propmem = sizeof(RadProps) * numProps / 1024.0;
00646 ptmem = sizeof(Point) * points->NumItems() / 1024.0;
00647 clrmem = sizeof(Colour) * colours->NumItems() / 1024.0;
00648 
00649 bmem = sizeof(RadElem*) * baseElems.NumItems() / 1024.0;
00650 bpmem = 0;
00651 RadElem::sGridMem = 0;
00652 RadElem::sGridChildMem = 0;
00653 for (i = 0; i < baseElems.NumItems(); i++)
00654 bpmem += baseElems[i]->MemoryUse();
00655 bpmem /= 1024.0;
00656 
00657 pmem = sizeof(RadElem*) * patches.NumItems() / 1024.0;
00658 emem = sizeof(RadElem*) * elements.NumItems() / 1024.0;
00659 epmem = sizeof(Int) * eltParents.NumItems() / 1024.0;
00660 rtmem = grid->MemoryUsage();
00661 
00662 printf(fmt, "propmem", propmem);
00663 printf(fmt, "points", ptmem);
00664 printf(fmt, "colours", clrmem);
00665 printf(fmt, "bmem", bmem);
00666 printf(fmt, "bpmem", bpmem);
00667 printf(fmt, " grid", RadElem::sGridMem / 1024.0);
00668 printf(fmt, " gridCh", RadElem::sGridChildMem / 1024.0);
00669 printf(fmt, "pmem", pmem);
00670 printf(fmt, "emem", emem);
00671 printf(fmt, "semem", semem);
00672 printf(fmt, "epmem", epmem);
00673 printf(fmt, "rtmem", rtmem);
00674 
00675 total = propmem + bmem + bpmem + pmem + emem + semem + epmem
00676 + clrmem + ptmem + rtmem;
00677 
00678 printf(fmt, "total", total);
00679 grid->DumpMemoryUsage();
00680 }

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

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