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

Revision 1251, 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]81void
82RssPreprocessor::CastRays(
83                                                  SimpleRayContainer &rays,
84                                                  VssRayContainer &vssRays
85                                                  )
86{
[752]87  for (int i=0; i < rays.size(); i++) {
[1251]88        CastRay(rays[i].mOrigin, rays[i].mDirection, rays[i].mPdf, vssRays, mViewCellsManager->GetViewSpaceBox());
[752]89        if (i % 10000 == 0)
90          cout<<".";
91  }
92  cout<<endl;
[563]93}
94
95
[447]96RssPreprocessor::~RssPreprocessor()
97{
[492]98  // mVssRays get deleted in the tree
99  //  CLEAR_CONTAINER(mVssRays);
[447]100}
101
102
[1251]103#if 0 //matt: this moved up to preprocessor
[447]104int
105RssPreprocessor::CastRay(
106                                                 Vector3 &viewPoint,
107                                                 Vector3 &direction,
[537]108                                                 const float probability,
[447]109                                                 VssRayContainer &vssRays
110                                                 )
111{
112  int hits = 0;
113  static Ray ray;
[1199]114  Intersectable *objectA, *objectB;
115  Vector3 pointA, pointB;
[447]116
[1199]117  //  AxisAlignedBox3 box = Union(mKdTree->GetBox(), mViewCellsManager->GetViewSpaceBox());
118 
[1112]119  AxisAlignedBox3 box = mViewCellsManager->GetViewSpaceBox();
120
[447]121  AxisAlignedBox3 sbox = box;
122  sbox.Enlarge(Vector3(-Limits::Small));
123  if (!sbox.IsInside(viewPoint))
124        return 0;
125       
126  SetupRay(ray, viewPoint, direction);
[1199]127  ray.mFlags &= ~Ray::CULL_BACKFACES;
[549]128
[447]129  // cast ray to KD tree to find intersection with other objects
130  float bsize = Magnitude(box.Size());
131 
[1199]132 
[447]133  if (mKdTree->CastRay(ray)) {
134        objectA = ray.intersections[0].mObject;
135        pointA = ray.Extrap(ray.intersections[0].mT);
[1199]136        if (mDetectEmptyViewSpace)
137          if (DotProd(ray.intersections[0].mNormal, direction) >= 0) {
138                // discard the sample
139                return 0;
140          }
141       
[447]142  } else {
143        objectA = NULL;
144        // compute intersection with the scene bounding box
145        float tmin, tmax;
[492]146        if (box.ComputeMinMaxT(ray, &tmin, &tmax) && tmin < tmax)
147          pointA = ray.Extrap(tmax);
148        else
149          return 0;
[447]150  }
151
[1199]152 
153  SetupRay(ray, viewPoint, -direction);
154  ray.mFlags &= ~Ray::CULL_BACKFACES;
155 
[447]156  if (mKdTree->CastRay(ray)) {
157        objectB = ray.intersections[0].mObject;
158        pointB = ray.Extrap(ray.intersections[0].mT);
[1199]159        if (mDetectEmptyViewSpace)
160          if (DotProd(ray.intersections[0].mNormal, direction) <= 0) {
161                // discard the sample
162                return 0;
163          }
[447]164  } else {
165        objectB = NULL;
166        float tmin, tmax;
[492]167        if (box.ComputeMinMaxT(ray, &tmin, &tmax) && tmin < tmax)
168          pointB = ray.Extrap(tmax);
169        else
170          return 0;
171  }
172 
173 
[447]174  VssRay *vssRay  = NULL;
[492]175  bool validSample = (objectA != objectB);
[447]176  if (validSample) {
177        if (objectA) {
178          vssRay = new VssRay(pointB,
179                                                  pointA,
180                                                  objectB,
[464]181                                                  objectA,
[537]182                                                  mPass,
183                                                  probability
[464]184                                                  );
[447]185          vssRays.push_back(vssRay);
186          hits ++;
187        }
188       
189        if (objectB) {
190          vssRay = new VssRay(pointA,
191                                                  pointB,
192                                                  objectA,
[464]193                                                  objectB,
[537]194                                                  mPass,
195                                                  probability
[464]196                                                  );
[447]197          vssRays.push_back(vssRay);
198          hits ++;
199        }
200  }
[576]201 
[447]202  return hits;
203}
[1251]204#endif
[447]205
[576]206void
207RssPreprocessor::ExportObjectRays(VssRayContainer &rays,
208                                                                  const int objectId)
209{
210  ObjectContainer::const_iterator oi;
[447]211
[576]212  Intersectable *object = NULL;
213  for (oi = mObjects.begin(); oi != mObjects.end(); ++oi)
214        if (objectId == (*oi)->GetId()) {
215          object = *oi;
216          break;
217        }
[447]218
[576]219  if (object == NULL)
220        return;
221 
222  VssRayContainer selectedRays;
223  VssRayContainer::const_iterator it= rays.begin(), it_end = rays.end();
224
225 
226  for (; it != it_end; ++it) {
227        if ((*it)->mTerminationObject == object)
228          selectedRays.push_back(*it);
229  }
230 
231
232  Exporter *exporter = Exporter::GetExporter("object-rays.x3d");
233  //    exporter->SetWireframe();
234  //    exporter->ExportKdTree(*mKdTree);
235  exporter->SetFilled();
236  exporter->ExportIntersectable(object);
237  exporter->ExportRays(selectedRays, RgbColor(1, 0, 0));
238 
239  delete exporter;
240 
241}
242
243
[447]244int
245RssPreprocessor::GenerateImportanceRays(RssTree *rssTree,
246                                                                                const int desiredSamples,
247                                                                                SimpleRayContainer &rays
248                                                                                )
249{
250  int num;
[463]251
[492]252  rssTree->UpdateTreeStatistics();
[463]253
[447]254  cout<<
[492]255        "#RSS_AVG_PVS_SIZE\n"<<rssTree->stat.avgPvsSize<<endl<<
256        "#RSS_AVG_RAYS\n"<<rssTree->stat.avgRays<<endl<<
257        "#RSS_AVG_RAY_CONTRIB\n"<<rssTree->stat.avgRayContribution<<endl<<
258        "#RSS_AVG_PVS_ENTROPY\n"<<rssTree->stat.avgPvsEntropy<<endl<<
259        "#RSS_AVG_RAY_LENGTH_ENTROPY\n"<<rssTree->stat.avgRayLengthEntropy<<endl<<
260        "#RSS_AVG_IMPORTANCE\n"<<rssTree->stat.avgImportance<<endl;
[447]261 
262  if (0) {
[492]263        float p = desiredSamples/(float)(rssTree->stat.avgRayContribution*rssTree->stat.Leaves());
[447]264        num = rssTree->GenerateRays(p, rays);
265  } else {
[459]266        int leaves = rssTree->stat.Leaves()/1;
[1112]267       
[447]268        num = rssTree->GenerateRays(desiredSamples, leaves, rays);
269  }
270       
271       
272  return num;
273}
274
275
276bool
277RssPreprocessor::ExportRays(const char *filename,
278                                                        const VssRayContainer &vssRays,
279                                                        const int number
280                                                        )
281{
282  cout<<"Exporting vss rays..."<<endl<<flush;
283       
284  Exporter *exporter = NULL;
285  exporter = Exporter::GetExporter(filename);
[1112]286  if (0) {
287        exporter->SetWireframe();
288        exporter->ExportKdTree(*mKdTree);
289  }
[447]290  exporter->SetFilled();
[556]291  // $$JB temporarily do not export the scene
[752]292  if (0)
[549]293        exporter->ExportScene(mSceneGraph->mRoot);
[447]294  exporter->SetWireframe();
295
[1112]296  if (1 || mViewSpaceBox) {
[447]297        exporter->SetForcedMaterial(RgbColor(1,0,1));
[1112]298        exporter->ExportBox(mViewCellsManager->GetViewSpaceBox());
[447]299        exporter->ResetForcedMaterial();
300  }
[1112]301 
[492]302  VssRayContainer rays;
303 
[1112]304  vssRays.SelectRays(number, rays);
[447]305
306  exporter->ExportRays(rays, RgbColor(1, 0, 0));
307       
308  delete exporter;
309
310  cout<<"done."<<endl<<flush;
311
312  return true;
313}
314
[1112]315bool
316RssPreprocessor::ExportRayAnimation(const char *filename,
317                                                                        const vector<VssRayContainer> &vssRays
318                                                                        )
319{
320  cout<<"Exporting vss rays..."<<endl<<flush;
321       
322  Exporter *exporter = NULL;
323  exporter = Exporter::GetExporter(filename);
324  if (0) {
325        exporter->SetWireframe();
326        exporter->ExportKdTree(*mKdTree);
327  }
328  exporter->SetFilled();
329  // $$JB temporarily do not export the scene
330  if (1)
331        exporter->ExportScene(mSceneGraph->mRoot);
332  exporter->SetWireframe();
[447]333
[1112]334  if (1 || mViewSpaceBox) {
335        exporter->SetForcedMaterial(RgbColor(1,0,1));
336        exporter->ExportBox(mViewCellsManager->GetViewSpaceBox());
337        exporter->ResetForcedMaterial();
338  }
339 
340  exporter->ExportRaySets(vssRays, RgbColor(1, 0, 0));
341       
342  delete exporter;
343
344  cout<<"done."<<endl<<flush;
345
346  return true;
347}
348
349
[447]350bool
351RssPreprocessor::ExportRssTree(char *filename,
352                                                           RssTree *tree,
353                                                           const Vector3 &dir
354                                                           )
355{
356  Exporter *exporter = Exporter::GetExporter(filename);
357  exporter->SetFilled();
358  exporter->ExportScene(mSceneGraph->mRoot);
359  //  exporter->SetWireframe();
360  bool result = exporter->ExportRssTree2( *tree, dir );
361  delete exporter;
362  return result;
363}
364
365bool
366RssPreprocessor::ExportRssTreeLeaf(char *filename,
367                                                                   RssTree *tree,
368                                                                   RssTreeLeaf *leaf)
369{
370  Exporter *exporter = NULL;
371  exporter = Exporter::GetExporter(filename);
372  exporter->SetWireframe();
373  exporter->ExportKdTree(*mKdTree);
374       
375  if (mViewSpaceBox) {
376        exporter->SetForcedMaterial(RgbColor(1,0,0));
377        exporter->ExportBox(*mViewSpaceBox);
378        exporter->ResetForcedMaterial();
379  }
380       
381  exporter->SetForcedMaterial(RgbColor(0,0,1));
382  exporter->ExportBox(tree->GetBBox(leaf));
383  exporter->ResetForcedMaterial();
384       
385  VssRayContainer rays[4];
386  for (int i=0; i < leaf->rays.size(); i++) {
387        int k = leaf->rays[i].GetRayClass();
388        rays[k].push_back(leaf->rays[i].mRay);
389  }
390       
391  // SOURCE RAY
392  exporter->ExportRays(rays[0], RgbColor(1, 0, 0));
393  // TERMINATION RAY
394  exporter->ExportRays(rays[1], RgbColor(1, 1, 1));
395  // PASSING_RAY
396  exporter->ExportRays(rays[2], RgbColor(1, 1, 0));
397  // CONTAINED_RAY
398  exporter->ExportRays(rays[3], RgbColor(0, 0, 1));
399
400  delete exporter;
401  return true;
402}
403
404void
405RssPreprocessor::ExportRssTreeLeaves(RssTree *tree, const int number)
406{
407  vector<RssTreeLeaf *> leaves;
408  tree->CollectLeaves(leaves);
409
410  int num = 0;
411  int i;
412  float p = number / (float)leaves.size();
413  for (i=0; i < leaves.size(); i++) {
414        if (RandomValue(0,1) < p) {
415          char filename[64];
416          sprintf(filename, "rss-leaf-%04d.x3d", num);
417          ExportRssTreeLeaf(filename, tree, leaves[i]);
418          num++;
419        }
420        if (num >= number)
421          break;
422  }
423}
424
425
426float
427RssPreprocessor::GetAvgPvsSize(RssTree *tree,
428                                                           const vector<AxisAlignedBox3> &viewcells
429                                                           )
430{
431  vector<AxisAlignedBox3>::const_iterator it, it_end = viewcells.end();
432
433  int sum = 0;
434  for (it = viewcells.begin(); it != it_end; ++ it)
435        sum += tree->GetPvsSize(*it);
436       
437  return sum/(float)viewcells.size();
438}
439
440
441void
442RssPreprocessor::ExportPvs(char *filename,
443                                                   RssTree *rssTree
444                                                   )
445{
446  ObjectContainer pvs;
447  if (rssTree->CollectRootPvs(pvs)) {
448        Exporter *exporter = Exporter::GetExporter(filename);
449        exporter->SetFilled();
450        exporter->ExportGeometry(pvs);
[459]451        exporter->SetWireframe();
452        exporter->ExportBox(rssTree->bbox);
453        exporter->ExportViewpoint(rssTree->bbox.Center(), Vector3(1,0,0));
[447]454        delete exporter;
455  }
456}
457
[492]458
459void
460RssPreprocessor::ComputeRenderError()
461{
462  // compute rendering error
[1145]463       
[752]464  if (renderer && renderer->mPvsStatFrames) {
[496]465        //      emit EvalPvsStat();
466        //      QMutex mutex;
467        //      mutex.lock();
468        //      renderer->mRenderingFinished.wait(&mutex);
469        //      mutex.unlock();
[556]470
[496]471        renderer->EvalPvsStat();
[492]472        mStats <<
473          "#AvgPvsRenderError\n" <<renderer->mPvsStat.GetAvgError()<<endl<<
474          "#MaxPvsRenderError\n" <<renderer->mPvsStat.GetMaxError()<<endl<<
[713]475          "#ErrorFreeFrames\n" <<renderer->mPvsStat.GetErrorFreeFrames()<<endl<<
476          "#AvgRenderPvs\n" <<renderer->mPvsStat.GetAvgPvs()<<endl;
[492]477  }
478}
479
[1112]480void
481NormalizeRatios(float ratios[3])
482{
483  int i;
484  float sumRatios;
485  sumRatios = ratios[0] + ratios[1] + ratios[2];
486  if (sumRatios == 0.0f) {
487        ratios[0] = ratios[1] = ratios[2] = 1.0f;
488        sumRatios = 3.0f;
489  }
490 
491  for (i=0 ; i < 3; i++)
492        ratios[i]/=sumRatios;
493#define MIN_RATIO 0.03f
494  for (i=0 ; i < 3; i++)
495        if (ratios[i] < MIN_RATIO)
496          ratios[i] = MIN_RATIO;
[563]497
[1112]498  sumRatios = ratios[0] + ratios[1] + ratios[2];
499  for (i=0 ; i < 3; i++)
500        ratios[i]/=sumRatios;
501 
502}
[563]503
[447]504bool
505RssPreprocessor::ComputeVisibility()
506{
[556]507
[811]508  Debug << "type: rss" << endl;
[579]509
[464]510  cout<<"Rss Preprocessor started\n"<<flush;
[567]511  //  cout<<"Memory/ray "<<sizeof(VssRay)+sizeof(RssTreeNode::RayInfo)<<endl;
[492]512
513  Randomize(0);
514 
[1112]515  vector<VssRayContainer> rayBuffer(50);
516 
[447]517  long startTime = GetTime();
518 
519  int totalSamples = 0;
520
[563]521  mViewSpaceBox = NULL;
[572]522
[577]523  // if not already loaded, construct view cells from file
[1112]524  if (!mLoadViewCells)
525  {
526        if (1)
[577]527          mViewCellsManager->SetViewSpaceBox(mKdTree->GetBox());
[677]528        else {
529          AxisAlignedBox3 box = mKdTree->GetBox();
[1112]530         
531          if (1) {
532                // use a small box outside of the scene
533                box.Scale(Vector3(0.1f,0.5f,0.5f));
534                box.Translate(Vector3(Magnitude(mKdTree->GetBox().Size())*0.5, 0, 0));
535          } else {
536                float s = box.Size(0);
537                box.Scale(0.1f);
538                box.SetMin(0, box.Min(0) + s);
539                box.SetMax(0, box.Max(0) + s);
540          }
[1027]541         
[677]542          mViewCellsManager->SetViewSpaceBox(box);
543        }
[1112]544       
545        // construct view cells using it's own set of samples
546        mViewCellsManager->Construct(this);
547       
548        //-- several visualizations and statistics
549        Debug << "view cells construction finished: " << endl;
550        mViewCellsManager->PrintStatistics(Debug);
[574]551  }
[1112]552 
553 
[492]554  int rssPass = 0;
555  int rssSamples = 0;
[563]556 
[492]557  if (mLoadInitialSamples) {
558        cout << "Loading samples from file ... ";
559        LoadSamples(mVssRays, mObjects);
560        cout << "finished\n" << endl;
561  } else {
[563]562        SimpleRayContainer rays;
[537]563
[871]564        cout<<"Generating initial rays..."<<endl<<flush;
565
[1199]566        if (mUseImportanceSampling) {
567          GenerateRays(mInitialSamples/3, SPATIAL_BOX_BASED_DISTRIBUTION, rays);
568          GenerateRays(mInitialSamples/3, OBJECT_BASED_DISTRIBUTION, rays);
569          GenerateRays(mInitialSamples/3, DIRECTION_BASED_DISTRIBUTION, rays);
570          //    GenerateRays(mInitialSamples/4, OBJECT_DIRECTION_BASED_DISTRIBUTION, rays);
571        } else {
572          int rayType = SPATIAL_BOX_BASED_DISTRIBUTION;
573          if (mObjectBasedSampling)
574                rayType = OBJECT_BASED_DISTRIBUTION;
575          else
576                if (mDirectionalSampling)
577                  rayType = DIRECTION_BASED_DISTRIBUTION;
578          cout<<"Generating rays..."<<endl;
579          GenerateRays(mRssSamplesPerPass, rayType, rays);
580        }
581       
582       
[871]583        cout<<"Casting initial rays..."<<endl<<flush;
[563]584        CastRays(rays, mVssRays);
[576]585
586        ExportObjectRays(mVssRays, 1546);
[563]587  }
588 
589  cout << "#totalRayStackSize=" << (int)mVssRays.size() << endl <<flush;
590 
591  rssSamples += (int)mVssRays.size();
592  totalSamples += mInitialSamples;
593  mPass++;
594 
595  if (mExportRays) {
[577]596       
[563]597        char filename[64];
598        sprintf(filename, "rss-rays-initial.x3d");
599        ExportRays(filename, mVssRays, mExportNumRays);
[1112]600
601        mVssRays.SelectRays(mExportNumRays, rayBuffer[0], true);
[577]602       
[563]603  }
604 
605  if (mStoreInitialSamples) {
606        cout << "Writing samples to file ... ";
607        ExportSamples(mVssRays);
608        cout << "finished\n" << endl;
609  }
[492]610       
[563]611  if (mUseViewcells) {
612
[871]613        cout<<"Computing sample contributions..."<<endl<<flush;
[563]614        // evaluate contributions of the intitial rays
[574]615        mViewCellsManager->ComputeSampleContributions(mVssRays, true, false);
[871]616        cout<<"done.\n"<<flush;
[492]617       
[563]618        mStats <<
619          "#Pass\n" <<mPass<<endl<<
620          "#RssPass\n" <<rssPass<<endl<<
621          "#Time\n" << TimeDiff(startTime, GetTime())*1e-3<<endl<<
622          "#TotalSamples\n" <<totalSamples<<endl<<
623          "#RssSamples\n" <<rssSamples<<endl;
[569]624
625        {
626          VssRayContainer contributingRays;
[1112]627          mVssRays.GetContributingRays(contributingRays, 0);
[569]628          mStats<<"#NUM_CONTRIBUTING_RAYS\n"<<(int)contributingRays.size()<<endl;
[1112]629          if (mExportRays) {
630                char filename[64];
631                sprintf(filename, "rss-crays-%04d.x3d", 0);
632                ExportRays(filename, contributingRays, mExportNumRays);
633          }
[569]634        }
[563]635       
636        mVssRays.PrintStatistics(mStats);
637        mViewCellsManager->PrintPvsStatistics(mStats);
[502]638         
[572]639        // viewcells->UpdatePVS(newVssRays);
640        Debug<<"Valid viewcells before set validity: "<<mViewCellsManager->CountValidViewcells()<<endl;
641        // cull viewcells with PVS > median (0.5f)
[752]642        //mViewCellsManager->SetValidityPercentage(0, 0.5f);
643        mViewCellsManager->SetValidityPercentage(0, 1.0f);
[572]644        Debug<<"Valid viewcells after set validity: "<<mViewCellsManager->CountValidViewcells()<<endl;
[563]645       
646        ComputeRenderError();
647  }
[492]648 
649  rssPass++;
650 
[563]651  mRssTree = new RssTree;
652  mRssTree->SetPass(mPass);
[492]653 
[527]654  /// compute view cell contribution of rays if view cells manager already constructed
[752]655  //  mViewCellsManager->ComputeSampleContributions(mVssRays, true, false);
[527]656
[467]657  if (mUseImportanceSampling) {
658       
[563]659        mRssTree->Construct(mObjects, mVssRays);
[467]660       
[563]661        mRssTree->stat.Print(mStats);
662        cout<<"RssTree root PVS size = "<<mRssTree->GetRootPvsSize()<<endl;
663       
[467]664        if (mExportRssTree) {
[563]665          ExportRssTree("rss-tree-100.x3d", mRssTree, Vector3(1,0,0));
666          ExportRssTree("rss-tree-001.x3d", mRssTree, Vector3(0,0,1));
667          ExportRssTree("rss-tree-101.x3d", mRssTree, Vector3(1,0,1));
668          ExportRssTree("rss-tree-101m.x3d", mRssTree, Vector3(-1,0,-1));
669          ExportRssTreeLeaves(mRssTree, 10);
[467]670        }
671       
672        if (mExportPvs) {
[563]673          ExportPvs("rss-pvs-initial.x3d", mRssTree);
[467]674        }
[459]675  }
[467]676 
[466]677 
[447]678  while (1) {
679        SimpleRayContainer rays;
680        VssRayContainer vssRays;
[563]681        int castRays = 0;
682        if (mUseImportanceSampling) {
683          VssRayContainer tmpVssRays;
[567]684
[1112]685          static float ratios[] = {0.9f,0.05f,0.05f};
686          //float ratios[] = {1.0f,0.0f,0.0f};
687         
688          int nrays[3];
689          float contributions[3];
690          float times[3];
691         
[1150]692          long t1;
[567]693
[1112]694          t1 = GetTime();
695         
[567]696          GenerateRays(mRssSamplesPerPass*ratios[0], RSS_BASED_DISTRIBUTION, rays);
[1112]697
[1146]698          rays.NormalizePdf((int)rays.size());
[1112]699         
[563]700          CastRays(rays, tmpVssRays);
701          castRays += rays.size();
[1112]702#if ADD_RAYS_IN_PLACE
703          contributions[0] = mViewCellsManager->ComputeSampleContributions(tmpVssRays, true, false);
704#else
705          contributions[0] = mViewCellsManager->ComputeSampleContributions(tmpVssRays, false, true);
706#endif
707          times[0] = TimeDiff(t1, GetTime());
708          nrays[0] = rays.size();
709         
710          mStats<<"#RssRelContrib"<<endl<<contributions[0]/nrays[0]<<endl;
711         
[563]712          vssRays.insert(vssRays.end(), tmpVssRays.begin(), tmpVssRays.end() );
713          rays.clear();
714          tmpVssRays.clear();
[567]715          if (ratios[1]!=0.0f) {
[1112]716                t1 = GetTime();
[567]717                GenerateRays(mRssSamplesPerPass*ratios[1], SPATIAL_BOX_BASED_DISTRIBUTION, rays);
718                CastRays(rays, tmpVssRays);
719                castRays += rays.size();
[1112]720#if ADD_RAYS_IN_PLACE
721                contributions[1] = mViewCellsManager->ComputeSampleContributions(tmpVssRays, true, false);
722#else
723                contributions[1] = mViewCellsManager->ComputeSampleContributions(tmpVssRays, false, true);
724#endif
725          times[1] = TimeDiff(t1, GetTime());
726          nrays[1] = rays.size();
727
728          mStats<<"#SpatialRelContrib"<<endl<<contributions[1]/nrays[1]<<endl;
[567]729               
730                vssRays.insert(vssRays.end(), tmpVssRays.begin(), tmpVssRays.end() );
731               
732                rays.clear();
733                tmpVssRays.clear();
734          }
[563]735         
736         
[567]737          if (ratios[2]!=0.0f) {
[1112]738                t1 = GetTime();
[567]739                GenerateRays(mRssSamplesPerPass*ratios[2], DIRECTION_BASED_DISTRIBUTION, rays);
740                CastRays(rays, tmpVssRays);
741                castRays += rays.size();
[1112]742#if ADD_RAYS_IN_PLACE
743                contributions[2] = mViewCellsManager->ComputeSampleContributions(tmpVssRays, true, false);
744#else
745                contributions[2] = mViewCellsManager->ComputeSampleContributions(tmpVssRays, false, true);
746#endif
747                times[2] = TimeDiff(t1, GetTime());
748                nrays[2] = rays.size();
[567]749               
[1112]750                mStats<<"#DirectionalRelContrib"<<endl<<contributions[2]/nrays[2]<<endl;
751               
[567]752                vssRays.insert(vssRays.end(), tmpVssRays.begin(), tmpVssRays.end() );
753               
754                rays.clear();
755                tmpVssRays.clear();
756          }
[563]757         
[1112]758         
759          // now evaluate the ratios for the next pass
760#define TIMES 0
761
762#if TIMES
763          ratios[0] = sqr(contributions[0]/times[0]);
764          ratios[1] = sqr(contributions[1]/times[1]);
765          ratios[2] = sqr(contributions[2]/times[2]);
766#else
767          ratios[0] = sqr(contributions[0]/nrays[0]);
768          ratios[1] = sqr(contributions[1]/nrays[1]);
769          ratios[2] = sqr(contributions[2]/nrays[2]);
770#endif
771          NormalizeRatios(ratios);
772
773          cout<<"New ratios: "<<ratios[0]<<" "<<ratios[1]<<" "<<ratios[2]<<endl;
774         
[563]775          // add contributions of all rays at once...
[1112]776#if !ADD_RAYS_IN_PLACE
[563]777          mViewCellsManager->AddSampleContributions(vssRays);
[1112]778#endif   
[563]779        }
780        else {
781          int rayType = SPATIAL_BOX_BASED_DISTRIBUTION;
782          if (mObjectBasedSampling)
783                rayType = OBJECT_BASED_DISTRIBUTION;
784          else
785                if (mDirectionalSampling)
786                  rayType = DIRECTION_BASED_DISTRIBUTION;
[752]787
788          cout<<"Generating rays..."<<endl;
789
[563]790          GenerateRays(mRssSamplesPerPass, rayType, rays);
[752]791          cout<<"done."<<endl;
792
793          cout<<"Casting rays..."<<endl;
[563]794          CastRays(rays, vssRays);
[752]795          cout<<"done."<<endl;
[563]796          castRays += rays.size();
797          if (mUseViewcells) {
798                /// compute view cell contribution of rays
[752]799                cout<<"Computing sample contributions..."<<endl;
[574]800                mViewCellsManager->ComputeSampleContributions(vssRays, true, false);
[752]801                cout<<"done."<<endl;
[447]802          }
[563]803               
804         
[447]805        }
[563]806        totalSamples += castRays;
[503]807        rssSamples += (int)vssRays.size();
[467]808
[884]809        cout<<"Generated "<<castRays<<" rays, progress "<<100.0f*totalSamples/((float) mRssSamples +
810                                                                                                                                                   mInitialSamples)<<"%\n";
[492]811       
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.