source: GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.cpp @ 1199

Revision 1199, 24.7 KB checked in by bittner, 18 years ago (diff)

code merge

RevLine 
[447]1#include "SceneGraph.h"
2#include "KdTree.h"
3#include "RssPreprocessor.h"
4#include "X3dExporter.h"
5#include "Environment.h"
6#include "MutualVisibility.h"
7#include "Polygon3.h"
8#include "ViewCell.h"
9#include "VssRay.h"
10#include "RssTree.h"
[451]11#include "ViewCellsManager.h"
[452]12#include "RenderSimulator.h"
[492]13#include "GlRenderer.h"
[447]14
[863]15namespace GtpVisibilityPreprocessor {
[860]16
17
[549]18static bool useViewSpaceBox = false;
[447]19static bool use2dSampling = false;
[516]20
21
22// not supported anymore!
[463]23static bool fromBoxVisibility = false;
[447]24
[1199]25#define ADD_RAYS_IN_PLACE 1
[1112]26 
[447]27RssPreprocessor::RssPreprocessor():
28  mPass(0),
29  mVssRays()
30{
31  // this should increase coherence of the samples
[1004]32  Environment::GetSingleton()->GetIntValue("RssPreprocessor.samplesPerPass", mSamplesPerPass);
33  Environment::GetSingleton()->GetIntValue("RssPreprocessor.initialSamples", mInitialSamples);
34  Environment::GetSingleton()->GetIntValue("RssPreprocessor.vssSamples", mRssSamples);
35  Environment::GetSingleton()->GetIntValue("RssPreprocessor.vssSamplesPerPass", mRssSamplesPerPass);
36  Environment::GetSingleton()->GetBoolValue("RssPreprocessor.useImportanceSampling", mUseImportanceSampling);
[464]37
[1004]38  Environment::GetSingleton()->GetBoolValue("RssPreprocessor.Export.pvs", mExportPvs);
39  Environment::GetSingleton()->GetBoolValue("RssPreprocessor.Export.rssTree", mExportRssTree);
40  Environment::GetSingleton()->GetBoolValue("RssPreprocessor.Export.rays", mExportRays);
41  Environment::GetSingleton()->GetIntValue("RssPreprocessor.Export.numRays", mExportNumRays);
42  Environment::GetSingleton()->GetBoolValue("RssPreprocessor.useViewcells", mUseViewcells);
43  Environment::GetSingleton()->GetBoolValue("RssPreprocessor.objectBasedSampling", mObjectBasedSampling);
44  Environment::GetSingleton()->GetBoolValue("RssPreprocessor.directionalSampling", mDirectionalSampling);
[464]45
[1004]46  Environment::GetSingleton()->GetBoolValue("RssPreprocessor.loadInitialSamples", mLoadInitialSamples);
47  Environment::GetSingleton()->GetBoolValue("RssPreprocessor.storeInitialSamples", mStoreInitialSamples);
48  Environment::GetSingleton()->GetBoolValue("RssPreprocessor.updateSubdivision", mUpdateSubdivision);
[464]49 
[447]50  mStats.open("stats.log");
[563]51  mRssTree = NULL;
52}
[492]53
[563]54
55bool
56RssPreprocessor::GenerateRays(
57                                                          const int number,
58                                                          const int sampleType,
59                                                          SimpleRayContainer &rays
60                                                          )
61{
62  bool result = false;
63
64  switch (sampleType) {
65  case RSS_BASED_DISTRIBUTION:
66  case RSS_SILHOUETTE_BASED_DISTRIBUTION:
67        if (mRssTree) {
68          GenerateImportanceRays(mRssTree, number, rays);
69          result = true;
70        }
71        break;
[752]72       
[563]73  default:
74        result = Preprocessor::GenerateRays(number, sampleType, rays);
75  }
76
[1112]77  //  rays.NormalizePdf();
78 
[563]79  return result;
[447]80}
81
[563]82void
83RssPreprocessor::CastRays(
84                                                  SimpleRayContainer &rays,
85                                                  VssRayContainer &vssRays
86                                                  )
87{
[752]88  for (int i=0; i < rays.size(); i++) {
[563]89        CastRay(rays[i].mOrigin, rays[i].mDirection, rays[i].mPdf, vssRays);
[752]90        if (i % 10000 == 0)
91          cout<<".";
92  }
93  cout<<endl;
[563]94}
95
96
[447]97RssPreprocessor::~RssPreprocessor()
98{
[492]99  // mVssRays get deleted in the tree
100  //  CLEAR_CONTAINER(mVssRays);
[447]101}
102
103void
104RssPreprocessor::SetupRay(Ray &ray,
105                                                  const Vector3 &point,
106                                                  const Vector3 &direction
107                                                  )
108{
109  ray.intersections.clear();
110  // do not store anything else then intersections at the ray
111  ray.Init(point, direction, Ray::LOCAL_RAY);
112}
113
114int
115RssPreprocessor::CastRay(
116                                                 Vector3 &viewPoint,
117                                                 Vector3 &direction,
[537]118                                                 const float probability,
[447]119                                                 VssRayContainer &vssRays
120                                                 )
121{
122  int hits = 0;
123  static Ray ray;
[1199]124  Intersectable *objectA, *objectB;
125  Vector3 pointA, pointB;
[447]126
[1199]127  //  AxisAlignedBox3 box = Union(mKdTree->GetBox(), mViewCellsManager->GetViewSpaceBox());
128 
[1112]129  AxisAlignedBox3 box = mViewCellsManager->GetViewSpaceBox();
130
[447]131  AxisAlignedBox3 sbox = box;
132  sbox.Enlarge(Vector3(-Limits::Small));
133  if (!sbox.IsInside(viewPoint))
134        return 0;
135       
136  SetupRay(ray, viewPoint, direction);
[1199]137  ray.mFlags &= ~Ray::CULL_BACKFACES;
[549]138
[447]139  // cast ray to KD tree to find intersection with other objects
140  float bsize = Magnitude(box.Size());
141 
[1199]142 
[447]143  if (mKdTree->CastRay(ray)) {
144        objectA = ray.intersections[0].mObject;
145        pointA = ray.Extrap(ray.intersections[0].mT);
[1199]146        if (mDetectEmptyViewSpace)
147          if (DotProd(ray.intersections[0].mNormal, direction) >= 0) {
148                // discard the sample
149                return 0;
150          }
151       
[447]152  } else {
153        objectA = NULL;
154        // compute intersection with the scene bounding box
155        float tmin, tmax;
[492]156        if (box.ComputeMinMaxT(ray, &tmin, &tmax) && tmin < tmax)
157          pointA = ray.Extrap(tmax);
158        else
159          return 0;
[447]160  }
161
[1199]162 
163  SetupRay(ray, viewPoint, -direction);
164  ray.mFlags &= ~Ray::CULL_BACKFACES;
165 
[447]166  if (mKdTree->CastRay(ray)) {
167        objectB = ray.intersections[0].mObject;
168        pointB = ray.Extrap(ray.intersections[0].mT);
[1199]169        if (mDetectEmptyViewSpace)
170          if (DotProd(ray.intersections[0].mNormal, direction) <= 0) {
171                // discard the sample
172                return 0;
173          }
[447]174  } else {
175        objectB = NULL;
176        float tmin, tmax;
[492]177        if (box.ComputeMinMaxT(ray, &tmin, &tmax) && tmin < tmax)
178          pointB = ray.Extrap(tmax);
179        else
180          return 0;
181  }
182 
183 
[447]184  VssRay *vssRay  = NULL;
[492]185  bool validSample = (objectA != objectB);
[447]186  if (validSample) {
187        if (objectA) {
188          vssRay = new VssRay(pointB,
189                                                  pointA,
190                                                  objectB,
[464]191                                                  objectA,
[537]192                                                  mPass,
193                                                  probability
[464]194                                                  );
[447]195          vssRays.push_back(vssRay);
196          hits ++;
197        }
198       
199        if (objectB) {
200          vssRay = new VssRay(pointA,
201                                                  pointB,
202                                                  objectA,
[464]203                                                  objectB,
[537]204                                                  mPass,
205                                                  probability
[464]206                                                  );
[447]207          vssRays.push_back(vssRay);
208          hits ++;
209        }
210  }
[576]211 
[447]212  return hits;
213}
214
215
[576]216void
217RssPreprocessor::ExportObjectRays(VssRayContainer &rays,
218                                                                  const int objectId)
219{
220  ObjectContainer::const_iterator oi;
[447]221
[576]222  Intersectable *object = NULL;
223  for (oi = mObjects.begin(); oi != mObjects.end(); ++oi)
224        if (objectId == (*oi)->GetId()) {
225          object = *oi;
226          break;
227        }
[447]228
[576]229  if (object == NULL)
230        return;
231 
232  VssRayContainer selectedRays;
233  VssRayContainer::const_iterator it= rays.begin(), it_end = rays.end();
234
235 
236  for (; it != it_end; ++it) {
237        if ((*it)->mTerminationObject == object)
238          selectedRays.push_back(*it);
239  }
240 
241
242  Exporter *exporter = Exporter::GetExporter("object-rays.x3d");
243  //    exporter->SetWireframe();
244  //    exporter->ExportKdTree(*mKdTree);
245  exporter->SetFilled();
246  exporter->ExportIntersectable(object);
247  exporter->ExportRays(selectedRays, RgbColor(1, 0, 0));
248 
249  delete exporter;
250 
251}
252
253
[447]254int
255RssPreprocessor::GenerateImportanceRays(RssTree *rssTree,
256                                                                                const int desiredSamples,
257                                                                                SimpleRayContainer &rays
258                                                                                )
259{
260  int num;
[463]261
[492]262  rssTree->UpdateTreeStatistics();
[463]263
[447]264  cout<<
[492]265        "#RSS_AVG_PVS_SIZE\n"<<rssTree->stat.avgPvsSize<<endl<<
266        "#RSS_AVG_RAYS\n"<<rssTree->stat.avgRays<<endl<<
267        "#RSS_AVG_RAY_CONTRIB\n"<<rssTree->stat.avgRayContribution<<endl<<
268        "#RSS_AVG_PVS_ENTROPY\n"<<rssTree->stat.avgPvsEntropy<<endl<<
269        "#RSS_AVG_RAY_LENGTH_ENTROPY\n"<<rssTree->stat.avgRayLengthEntropy<<endl<<
270        "#RSS_AVG_IMPORTANCE\n"<<rssTree->stat.avgImportance<<endl;
[447]271 
272  if (0) {
[492]273        float p = desiredSamples/(float)(rssTree->stat.avgRayContribution*rssTree->stat.Leaves());
[447]274        num = rssTree->GenerateRays(p, rays);
275  } else {
[459]276        int leaves = rssTree->stat.Leaves()/1;
[1112]277       
[447]278        num = rssTree->GenerateRays(desiredSamples, leaves, rays);
279  }
280       
281       
282  return num;
283}
284
285
286bool
287RssPreprocessor::ExportRays(const char *filename,
288                                                        const VssRayContainer &vssRays,
289                                                        const int number
290                                                        )
291{
292  cout<<"Exporting vss rays..."<<endl<<flush;
293       
294  Exporter *exporter = NULL;
295  exporter = Exporter::GetExporter(filename);
[1112]296  if (0) {
297        exporter->SetWireframe();
298        exporter->ExportKdTree(*mKdTree);
299  }
[447]300  exporter->SetFilled();
[556]301  // $$JB temporarily do not export the scene
[752]302  if (0)
[549]303        exporter->ExportScene(mSceneGraph->mRoot);
[447]304  exporter->SetWireframe();
305
[1112]306  if (1 || mViewSpaceBox) {
[447]307        exporter->SetForcedMaterial(RgbColor(1,0,1));
[1112]308        exporter->ExportBox(mViewCellsManager->GetViewSpaceBox());
[447]309        exporter->ResetForcedMaterial();
310  }
[1112]311 
[492]312  VssRayContainer rays;
313 
[1112]314  vssRays.SelectRays(number, rays);
[447]315
316  exporter->ExportRays(rays, RgbColor(1, 0, 0));
317       
318  delete exporter;
319
320  cout<<"done."<<endl<<flush;
321
322  return true;
323}
324
[1112]325bool
326RssPreprocessor::ExportRayAnimation(const char *filename,
327                                                                        const vector<VssRayContainer> &vssRays
328                                                                        )
329{
330  cout<<"Exporting vss rays..."<<endl<<flush;
331       
332  Exporter *exporter = NULL;
333  exporter = Exporter::GetExporter(filename);
334  if (0) {
335        exporter->SetWireframe();
336        exporter->ExportKdTree(*mKdTree);
337  }
338  exporter->SetFilled();
339  // $$JB temporarily do not export the scene
340  if (1)
341        exporter->ExportScene(mSceneGraph->mRoot);
342  exporter->SetWireframe();
[447]343
[1112]344  if (1 || mViewSpaceBox) {
345        exporter->SetForcedMaterial(RgbColor(1,0,1));
346        exporter->ExportBox(mViewCellsManager->GetViewSpaceBox());
347        exporter->ResetForcedMaterial();
348  }
349 
350  exporter->ExportRaySets(vssRays, RgbColor(1, 0, 0));
351       
352  delete exporter;
353
354  cout<<"done."<<endl<<flush;
355
356  return true;
357}
358
359
[447]360bool
361RssPreprocessor::ExportRssTree(char *filename,
362                                                           RssTree *tree,
363                                                           const Vector3 &dir
364                                                           )
365{
366  Exporter *exporter = Exporter::GetExporter(filename);
367  exporter->SetFilled();
368  exporter->ExportScene(mSceneGraph->mRoot);
369  //  exporter->SetWireframe();
370  bool result = exporter->ExportRssTree2( *tree, dir );
371  delete exporter;
372  return result;
373}
374
375bool
376RssPreprocessor::ExportRssTreeLeaf(char *filename,
377                                                                   RssTree *tree,
378                                                                   RssTreeLeaf *leaf)
379{
380  Exporter *exporter = NULL;
381  exporter = Exporter::GetExporter(filename);
382  exporter->SetWireframe();
383  exporter->ExportKdTree(*mKdTree);
384       
385  if (mViewSpaceBox) {
386        exporter->SetForcedMaterial(RgbColor(1,0,0));
387        exporter->ExportBox(*mViewSpaceBox);
388        exporter->ResetForcedMaterial();
389  }
390       
391  exporter->SetForcedMaterial(RgbColor(0,0,1));
392  exporter->ExportBox(tree->GetBBox(leaf));
393  exporter->ResetForcedMaterial();
394       
395  VssRayContainer rays[4];
396  for (int i=0; i < leaf->rays.size(); i++) {
397        int k = leaf->rays[i].GetRayClass();
398        rays[k].push_back(leaf->rays[i].mRay);
399  }
400       
401  // SOURCE RAY
402  exporter->ExportRays(rays[0], RgbColor(1, 0, 0));
403  // TERMINATION RAY
404  exporter->ExportRays(rays[1], RgbColor(1, 1, 1));
405  // PASSING_RAY
406  exporter->ExportRays(rays[2], RgbColor(1, 1, 0));
407  // CONTAINED_RAY
408  exporter->ExportRays(rays[3], RgbColor(0, 0, 1));
409
410  delete exporter;
411  return true;
412}
413
414void
415RssPreprocessor::ExportRssTreeLeaves(RssTree *tree, const int number)
416{
417  vector<RssTreeLeaf *> leaves;
418  tree->CollectLeaves(leaves);
419
420  int num = 0;
421  int i;
422  float p = number / (float)leaves.size();
423  for (i=0; i < leaves.size(); i++) {
424        if (RandomValue(0,1) < p) {
425          char filename[64];
426          sprintf(filename, "rss-leaf-%04d.x3d", num);
427          ExportRssTreeLeaf(filename, tree, leaves[i]);
428          num++;
429        }
430        if (num >= number)
431          break;
432  }
433}
434
435
436float
437RssPreprocessor::GetAvgPvsSize(RssTree *tree,
438                                                           const vector<AxisAlignedBox3> &viewcells
439                                                           )
440{
441  vector<AxisAlignedBox3>::const_iterator it, it_end = viewcells.end();
442
443  int sum = 0;
444  for (it = viewcells.begin(); it != it_end; ++ it)
445        sum += tree->GetPvsSize(*it);
446       
447  return sum/(float)viewcells.size();
448}
449
450
451void
452RssPreprocessor::ExportPvs(char *filename,
453                                                   RssTree *rssTree
454                                                   )
455{
456  ObjectContainer pvs;
457  if (rssTree->CollectRootPvs(pvs)) {
458        Exporter *exporter = Exporter::GetExporter(filename);
459        exporter->SetFilled();
460        exporter->ExportGeometry(pvs);
[459]461        exporter->SetWireframe();
462        exporter->ExportBox(rssTree->bbox);
463        exporter->ExportViewpoint(rssTree->bbox.Center(), Vector3(1,0,0));
[447]464        delete exporter;
465  }
466}
467
[492]468
469void
470RssPreprocessor::ComputeRenderError()
471{
472  // compute rendering error
[1145]473       
[752]474  if (renderer && renderer->mPvsStatFrames) {
[496]475        //      emit EvalPvsStat();
476        //      QMutex mutex;
477        //      mutex.lock();
478        //      renderer->mRenderingFinished.wait(&mutex);
479        //      mutex.unlock();
[556]480
[496]481        renderer->EvalPvsStat();
[492]482        mStats <<
483          "#AvgPvsRenderError\n" <<renderer->mPvsStat.GetAvgError()<<endl<<
484          "#MaxPvsRenderError\n" <<renderer->mPvsStat.GetMaxError()<<endl<<
[713]485          "#ErrorFreeFrames\n" <<renderer->mPvsStat.GetErrorFreeFrames()<<endl<<
486          "#AvgRenderPvs\n" <<renderer->mPvsStat.GetAvgPvs()<<endl;
[492]487  }
488}
489
[1112]490void
491NormalizeRatios(float ratios[3])
492{
493  int i;
494  float sumRatios;
495  sumRatios = ratios[0] + ratios[1] + ratios[2];
496  if (sumRatios == 0.0f) {
497        ratios[0] = ratios[1] = ratios[2] = 1.0f;
498        sumRatios = 3.0f;
499  }
500 
501  for (i=0 ; i < 3; i++)
502        ratios[i]/=sumRatios;
503#define MIN_RATIO 0.03f
504  for (i=0 ; i < 3; i++)
505        if (ratios[i] < MIN_RATIO)
506          ratios[i] = MIN_RATIO;
[563]507
[1112]508  sumRatios = ratios[0] + ratios[1] + ratios[2];
509  for (i=0 ; i < 3; i++)
510        ratios[i]/=sumRatios;
511 
512}
[563]513
[447]514bool
515RssPreprocessor::ComputeVisibility()
516{
[556]517
[811]518  Debug << "type: rss" << endl;
[579]519
[464]520  cout<<"Rss Preprocessor started\n"<<flush;
[567]521  //  cout<<"Memory/ray "<<sizeof(VssRay)+sizeof(RssTreeNode::RayInfo)<<endl;
[492]522
523  Randomize(0);
524 
[1112]525  vector<VssRayContainer> rayBuffer(50);
526 
[447]527  long startTime = GetTime();
528 
529  int totalSamples = 0;
530
[563]531  mViewSpaceBox = NULL;
[572]532
[577]533  // if not already loaded, construct view cells from file
[1112]534  if (!mLoadViewCells)
535  {
536        if (1)
[577]537          mViewCellsManager->SetViewSpaceBox(mKdTree->GetBox());
[677]538        else {
539          AxisAlignedBox3 box = mKdTree->GetBox();
[1112]540         
541          if (1) {
542                // use a small box outside of the scene
543                box.Scale(Vector3(0.1f,0.5f,0.5f));
544                box.Translate(Vector3(Magnitude(mKdTree->GetBox().Size())*0.5, 0, 0));
545          } else {
546                float s = box.Size(0);
547                box.Scale(0.1f);
548                box.SetMin(0, box.Min(0) + s);
549                box.SetMax(0, box.Max(0) + s);
550          }
[1027]551         
[677]552          mViewCellsManager->SetViewSpaceBox(box);
553        }
[1112]554       
555        // construct view cells using it's own set of samples
556        mViewCellsManager->Construct(this);
557       
558        //-- several visualizations and statistics
559        Debug << "view cells construction finished: " << endl;
560        mViewCellsManager->PrintStatistics(Debug);
[574]561  }
[1112]562 
563 
[492]564  int rssPass = 0;
565  int rssSamples = 0;
[563]566 
[492]567  if (mLoadInitialSamples) {
568        cout << "Loading samples from file ... ";
569        LoadSamples(mVssRays, mObjects);
570        cout << "finished\n" << endl;
571  } else {
[563]572        SimpleRayContainer rays;
[537]573
[871]574        cout<<"Generating initial rays..."<<endl<<flush;
575
[1199]576        if (mUseImportanceSampling) {
577          GenerateRays(mInitialSamples/3, SPATIAL_BOX_BASED_DISTRIBUTION, rays);
578          GenerateRays(mInitialSamples/3, OBJECT_BASED_DISTRIBUTION, rays);
579          GenerateRays(mInitialSamples/3, DIRECTION_BASED_DISTRIBUTION, rays);
580          //    GenerateRays(mInitialSamples/4, OBJECT_DIRECTION_BASED_DISTRIBUTION, rays);
581        } else {
582          int rayType = SPATIAL_BOX_BASED_DISTRIBUTION;
583          if (mObjectBasedSampling)
584                rayType = OBJECT_BASED_DISTRIBUTION;
585          else
586                if (mDirectionalSampling)
587                  rayType = DIRECTION_BASED_DISTRIBUTION;
588          cout<<"Generating rays..."<<endl;
589          GenerateRays(mRssSamplesPerPass, rayType, rays);
590        }
591       
592       
[871]593        cout<<"Casting initial rays..."<<endl<<flush;
[563]594        CastRays(rays, mVssRays);
[576]595
596        ExportObjectRays(mVssRays, 1546);
[563]597  }
598 
599  cout << "#totalRayStackSize=" << (int)mVssRays.size() << endl <<flush;
600 
601  rssSamples += (int)mVssRays.size();
602  totalSamples += mInitialSamples;
603  mPass++;
604 
605  if (mExportRays) {
[577]606       
[563]607        char filename[64];
608        sprintf(filename, "rss-rays-initial.x3d");
609        ExportRays(filename, mVssRays, mExportNumRays);
[1112]610
611        mVssRays.SelectRays(mExportNumRays, rayBuffer[0], true);
[577]612       
[563]613  }
614 
615  if (mStoreInitialSamples) {
616        cout << "Writing samples to file ... ";
617        ExportSamples(mVssRays);
618        cout << "finished\n" << endl;
619  }
[492]620       
[563]621  if (mUseViewcells) {
622
[871]623        cout<<"Computing sample contributions..."<<endl<<flush;
[563]624        // evaluate contributions of the intitial rays
[574]625        mViewCellsManager->ComputeSampleContributions(mVssRays, true, false);
[871]626        cout<<"done.\n"<<flush;
[492]627       
[563]628        mStats <<
629          "#Pass\n" <<mPass<<endl<<
630          "#RssPass\n" <<rssPass<<endl<<
631          "#Time\n" << TimeDiff(startTime, GetTime())*1e-3<<endl<<
632          "#TotalSamples\n" <<totalSamples<<endl<<
633          "#RssSamples\n" <<rssSamples<<endl;
[569]634
635        {
636          VssRayContainer contributingRays;
[1112]637          mVssRays.GetContributingRays(contributingRays, 0);
[569]638          mStats<<"#NUM_CONTRIBUTING_RAYS\n"<<(int)contributingRays.size()<<endl;
[1112]639          if (mExportRays) {
640                char filename[64];
641                sprintf(filename, "rss-crays-%04d.x3d", 0);
642                ExportRays(filename, contributingRays, mExportNumRays);
643          }
[569]644        }
[563]645       
646        mVssRays.PrintStatistics(mStats);
647        mViewCellsManager->PrintPvsStatistics(mStats);
[502]648         
[572]649        // viewcells->UpdatePVS(newVssRays);
650        Debug<<"Valid viewcells before set validity: "<<mViewCellsManager->CountValidViewcells()<<endl;
651        // cull viewcells with PVS > median (0.5f)
[752]652        //mViewCellsManager->SetValidityPercentage(0, 0.5f);
653        mViewCellsManager->SetValidityPercentage(0, 1.0f);
[572]654        Debug<<"Valid viewcells after set validity: "<<mViewCellsManager->CountValidViewcells()<<endl;
[563]655       
656        ComputeRenderError();
657  }
[492]658 
659  rssPass++;
660 
[563]661  mRssTree = new RssTree;
662  mRssTree->SetPass(mPass);
[492]663 
[527]664  /// compute view cell contribution of rays if view cells manager already constructed
[752]665  //  mViewCellsManager->ComputeSampleContributions(mVssRays, true, false);
[527]666
[467]667  if (mUseImportanceSampling) {
668       
[563]669        mRssTree->Construct(mObjects, mVssRays);
[467]670       
[563]671        mRssTree->stat.Print(mStats);
672        cout<<"RssTree root PVS size = "<<mRssTree->GetRootPvsSize()<<endl;
673       
[467]674        if (mExportRssTree) {
[563]675          ExportRssTree("rss-tree-100.x3d", mRssTree, Vector3(1,0,0));
676          ExportRssTree("rss-tree-001.x3d", mRssTree, Vector3(0,0,1));
677          ExportRssTree("rss-tree-101.x3d", mRssTree, Vector3(1,0,1));
678          ExportRssTree("rss-tree-101m.x3d", mRssTree, Vector3(-1,0,-1));
679          ExportRssTreeLeaves(mRssTree, 10);
[467]680        }
681       
682        if (mExportPvs) {
[563]683          ExportPvs("rss-pvs-initial.x3d", mRssTree);
[467]684        }
[459]685  }
[467]686 
[466]687 
[447]688  while (1) {
689        SimpleRayContainer rays;
690        VssRayContainer vssRays;
[563]691        int castRays = 0;
692        if (mUseImportanceSampling) {
693          VssRayContainer tmpVssRays;
[567]694
[1112]695          static float ratios[] = {0.9f,0.05f,0.05f};
696          //float ratios[] = {1.0f,0.0f,0.0f};
697         
698          int nrays[3];
699          float contributions[3];
700          float times[3];
701         
[1150]702          long t1;
[567]703
[1112]704          t1 = GetTime();
705         
[567]706          GenerateRays(mRssSamplesPerPass*ratios[0], RSS_BASED_DISTRIBUTION, rays);
[1112]707
[1146]708          rays.NormalizePdf((int)rays.size());
[1112]709         
[563]710          CastRays(rays, tmpVssRays);
711          castRays += rays.size();
[1112]712#if ADD_RAYS_IN_PLACE
713          contributions[0] = mViewCellsManager->ComputeSampleContributions(tmpVssRays, true, false);
714#else
715          contributions[0] = mViewCellsManager->ComputeSampleContributions(tmpVssRays, false, true);
716#endif
717          times[0] = TimeDiff(t1, GetTime());
718          nrays[0] = rays.size();
719         
720          mStats<<"#RssRelContrib"<<endl<<contributions[0]/nrays[0]<<endl;
721         
[563]722          vssRays.insert(vssRays.end(), tmpVssRays.begin(), tmpVssRays.end() );
723          rays.clear();
724          tmpVssRays.clear();
[567]725          if (ratios[1]!=0.0f) {
[1112]726                t1 = GetTime();
[567]727                GenerateRays(mRssSamplesPerPass*ratios[1], SPATIAL_BOX_BASED_DISTRIBUTION, rays);
728                CastRays(rays, tmpVssRays);
729                castRays += rays.size();
[1112]730#if ADD_RAYS_IN_PLACE
731                contributions[1] = mViewCellsManager->ComputeSampleContributions(tmpVssRays, true, false);
732#else
733                contributions[1] = mViewCellsManager->ComputeSampleContributions(tmpVssRays, false, true);
734#endif
735          times[1] = TimeDiff(t1, GetTime());
736          nrays[1] = rays.size();
737
738          mStats<<"#SpatialRelContrib"<<endl<<contributions[1]/nrays[1]<<endl;
[567]739               
740                vssRays.insert(vssRays.end(), tmpVssRays.begin(), tmpVssRays.end() );
741               
742                rays.clear();
743                tmpVssRays.clear();
744          }
[563]745         
746         
[567]747          if (ratios[2]!=0.0f) {
[1112]748                t1 = GetTime();
[567]749                GenerateRays(mRssSamplesPerPass*ratios[2], DIRECTION_BASED_DISTRIBUTION, rays);
750                CastRays(rays, tmpVssRays);
751                castRays += rays.size();
[1112]752#if ADD_RAYS_IN_PLACE
753                contributions[2] = mViewCellsManager->ComputeSampleContributions(tmpVssRays, true, false);
754#else
755                contributions[2] = mViewCellsManager->ComputeSampleContributions(tmpVssRays, false, true);
756#endif
757                times[2] = TimeDiff(t1, GetTime());
758                nrays[2] = rays.size();
[567]759               
[1112]760                mStats<<"#DirectionalRelContrib"<<endl<<contributions[2]/nrays[2]<<endl;
761               
[567]762                vssRays.insert(vssRays.end(), tmpVssRays.begin(), tmpVssRays.end() );
763               
764                rays.clear();
765                tmpVssRays.clear();
766          }
[563]767         
[1112]768         
769          // now evaluate the ratios for the next pass
770#define TIMES 0
771
772#if TIMES
773          ratios[0] = sqr(contributions[0]/times[0]);
774          ratios[1] = sqr(contributions[1]/times[1]);
775          ratios[2] = sqr(contributions[2]/times[2]);
776#else
777          ratios[0] = sqr(contributions[0]/nrays[0]);
778          ratios[1] = sqr(contributions[1]/nrays[1]);
779          ratios[2] = sqr(contributions[2]/nrays[2]);
780#endif
781          NormalizeRatios(ratios);
782
783          cout<<"New ratios: "<<ratios[0]<<" "<<ratios[1]<<" "<<ratios[2]<<endl;
784         
[563]785          // add contributions of all rays at once...
[1112]786#if !ADD_RAYS_IN_PLACE
[563]787          mViewCellsManager->AddSampleContributions(vssRays);
[1112]788#endif   
[563]789        }
790        else {
791          int rayType = SPATIAL_BOX_BASED_DISTRIBUTION;
792          if (mObjectBasedSampling)
793                rayType = OBJECT_BASED_DISTRIBUTION;
794          else
795                if (mDirectionalSampling)
796                  rayType = DIRECTION_BASED_DISTRIBUTION;
[752]797
798          cout<<"Generating rays..."<<endl;
799
[563]800          GenerateRays(mRssSamplesPerPass, rayType, rays);
[752]801          cout<<"done."<<endl;
802
803          cout<<"Casting rays..."<<endl;
[563]804          CastRays(rays, vssRays);
[752]805          cout<<"done."<<endl;
[563]806          castRays += rays.size();
807          if (mUseViewcells) {
808                /// compute view cell contribution of rays
[752]809                cout<<"Computing sample contributions..."<<endl;
[574]810                mViewCellsManager->ComputeSampleContributions(vssRays, true, false);
[752]811                cout<<"done."<<endl;
[447]812          }
[563]813               
814         
[447]815        }
[563]816        totalSamples += castRays;
[503]817        rssSamples += (int)vssRays.size();
[467]818
[884]819        cout<<"Generated "<<castRays<<" rays, progress "<<100.0f*totalSamples/((float) mRssSamples +
820                                                                                                                                                   mInitialSamples)<<"%\n";
[492]821       
822       
[467]823        mStats <<
824          "#Pass\n" <<mPass<<endl<<
825          "#RssPass\n" <<rssPass<<endl<<
826          "#Time\n" << TimeDiff(startTime, GetTime())*1e-3<<endl<<
827          "#TotalSamples\n" <<totalSamples<<endl<<
828          "#RssSamples\n" <<rssSamples<<endl;
829
[492]830
[466]831        if (mUseViewcells) {
[467]832          vssRays.PrintStatistics(mStats);
833          mViewCellsManager->PrintPvsStatistics(mStats);
[466]834        }
[576]835
836        if (0 && mPass > 0) {
[1145]837                char buf[100];
[576]838          if (mUseImportanceSampling)
[1145]839          {
840                sprintf(buf, "snap/i-%02d-", mPass);
841
[1151]842                renderer->SetSnapPrefix(buf);
[1145]843          }
[576]844          else
[1145]845          {
846                sprintf(buf, "snap/r-%02d-", mPass);
847
[1151]848                renderer->SetSnapPrefix(buf);
[1145]849          }
850
[1151]851          renderer->SetSnapErrorFrames(true);
[576]852        }
853
[492]854        ComputeRenderError();
855       
856        // epxort rays before adding them to the tree -> some of them can be deleted
857
858        if (mExportRays) {
859          char filename[64];
860          if (mUseImportanceSampling)
861                sprintf(filename, "rss-rays-i%04d.x3d", rssPass);
862          else
863                sprintf(filename, "rss-rays-%04d.x3d", rssPass);
864         
[1112]865         
866
867          vssRays.SelectRays(mExportNumRays, rayBuffer[mPass], true);
868         
[492]869          ExportRays(filename, vssRays, mExportNumRays);
[1112]870         
[492]871          // now export all contributing rays
872          VssRayContainer contributingRays;
873          vssRays.GetContributingRays(contributingRays, mPass);
[508]874          mStats<<"#NUM_CONTRIBUTING_RAYS\n"<<(int)contributingRays.size()<<endl;
[492]875          sprintf(filename, "rss-crays-%04d.x3d", rssPass);
876          ExportRays(filename, contributingRays, mExportNumRays);
[1112]877         
[492]878        }
879
880       
[467]881        // add rays to the tree after the viewcells have been cast to have their contributions
882        // already when adding into the tree
883        // do not add those rays which have too low or no contribution....
[466]884       
[467]885        if (mUseImportanceSampling) {
[563]886          mRssTree->AddRays(vssRays);
[467]887         
888          if (mUpdateSubdivision) {
[492]889                int updatePasses = 1;
890                if (mPass % updatePasses == 0) {
[563]891                  int subdivided = mRssTree->UpdateSubdivision();
[492]892                  cout<<"subdivided leafs = "<<subdivided<<endl;
[563]893                  cout<<"#total leaves = "<<mRssTree->stat.Leaves()<<endl;
[492]894                }
[467]895          }
[447]896        }
[467]897       
[464]898        if (mExportPvs) {
[447]899          char filename[64];
[467]900          sprintf(filename, "rss-pvs-%04d.x3d", rssPass);
[563]901          ExportPvs(filename, mRssTree);
[447]902        }
[492]903       
[563]904       
[1199]905        if (!mUseImportanceSampling)
[492]906          CLEAR_CONTAINER(vssRays);
[563]907        // otherwise the rays get deleted by the rss tree update according to RssTree.maxRays ....
[492]908
[467]909        if (totalSamples >= mRssSamples + mInitialSamples)
[447]910          break;
911
912       
[467]913        rssPass++;
914        mPass++;
[563]915        mRssTree->SetPass(mPass);
[447]916  }
917 
[464]918  if (mUseViewcells) {
[466]919
[1199]920        if(0)
[574]921          {
[1199]922                VssRayContainer selectedRays;
923                int desired = mViewCellsManager->GetVisualizationSamples();
924               
925                mVssRays.SelectRays(desired, selectedRays);
926               
927                mViewCellsManager->Visualize(mObjects, selectedRays);
[574]928          }
[556]929       
[1199]930        // view cells after sampling
931        mViewCellsManager->PrintStatistics(Debug);
932       
933        //-- render simulation after merge
934        cout << "\nevaluating bsp view cells render time after sampling ... ";
935       
936        mRenderSimulator->RenderScene();
937        SimulationStatistics ss;
938        mRenderSimulator->GetStatistics(ss);
939       
940        cout << " finished" << endl;
941        cout << ss << endl;
942        Debug << ss << endl;
943       
[466]944  }
[1112]945
946
947  if (mExportRays && mUseImportanceSampling) {
948        char filename[64];
949        sprintf(filename, "rss-rays-i.x3d");
950       
951        rayBuffer.resize(mPass);
952        ExportRayAnimation(filename, rayBuffer);
953  }
954         
[563]955  Debug<<"Deleting RSS tree...\n";
956  delete mRssTree;
957  Debug<<"Done.\n";
[466]958
[859]959
[1199]960  //mViewCellsManager->ExportViewCells("visibility.xml",
[871]961  //                                                                     true);
[447]962 
[871]963 
[447]964  return true;
965}
966
[871]967}
Note: See TracBrowser for help on using the repository browser.