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

Revision 1520, 24.8 KB checked in by mattausch, 18 years ago (diff)

moved raycasting out of preprocessor into specific ray casting interface

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