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

Revision 1151, 24.7 KB checked in by mattausch, 18 years ago (diff)

worded on dll loading

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