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

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