source: trunk/VUT/GtpVisibilityPreprocessor/src/RssPreprocessor.cpp @ 463

Revision 463, 16.6 KB checked in by bittner, 19 years ago (diff)

removed mT from vss ray

Line 
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"
11#include "ViewCellsManager.h"
12#include "RenderSimulator.h"
13
14static bool useViewSpaceBox = true;
15static bool use2dSampling = false;
16static bool fromBoxVisibility = false;
17
18static bool exportPvs = false;
19static bool exportRssTree = false;
20
21static int numExportRays = 5000;
22// static int numExportRays = 0;
23
24static bool useViewcells = false;
25
26RssPreprocessor::RssPreprocessor():
27  mPass(0),
28  mVssRays()
29{
30  // this should increase coherence of the samples
31  environment->GetIntValue("RssPreprocessor.samplesPerPass", mSamplesPerPass);
32  environment->GetIntValue("RssPreprocessor.initialSamples", mInitialSamples);
33  environment->GetIntValue("RssPreprocessor.vssSamples", mRssSamples);
34  environment->GetIntValue("RssPreprocessor.vssSamplesPerPass", mRssSamplesPerPass);
35  environment->GetBoolValue("RssPreprocessor.useImportanceSampling", mUseImportanceSampling);
36  environment->GetIntValue("BspTree.Construction.samples", mBspConstructionSamples);
37       
38  mStats.open("stats.log");
39}
40
41RssPreprocessor::~RssPreprocessor()
42{
43  CLEAR_CONTAINER(mVssRays);
44}
45
46void
47RssPreprocessor::SetupRay(Ray &ray,
48                                                  const Vector3 &point,
49                                                  const Vector3 &direction
50                                                  )
51{
52  ray.intersections.clear();
53  // do not store anything else then intersections at the ray
54  ray.Init(point, direction, Ray::LOCAL_RAY);
55}
56
57int
58RssPreprocessor::CastRay(
59                                                 Vector3 &viewPoint,
60                                                 Vector3 &direction,
61                                                 VssRayContainer &vssRays
62                                                 )
63{
64  int hits = 0;
65  static Ray ray;
66  AxisAlignedBox3 box = mKdTree->GetBox();
67
68  AxisAlignedBox3 sbox = box;
69  sbox.Enlarge(Vector3(-Limits::Small));
70  if (!sbox.IsInside(viewPoint))
71        return 0;
72       
73  SetupRay(ray, viewPoint, direction);
74  // cast ray to KD tree to find intersection with other objects
75  Intersectable *objectA, *objectB;
76  Vector3 pointA, pointB;
77  float bsize = Magnitude(box.Size());
78 
79  if (mKdTree->CastRay(ray)) {
80        objectA = ray.intersections[0].mObject;
81        pointA = ray.Extrap(ray.intersections[0].mT);
82  } else {
83        objectA = NULL;
84        // compute intersection with the scene bounding box
85        float tmin, tmax;
86        box.ComputeMinMaxT(ray, &tmin, &tmax);
87        if (tmax > bsize) {
88          //cerr<<"Warning: tmax > box size tmax="<<tmax<<" tmin="<<tmin<<" size="<<bsize<<endl;
89          //cerr<<"ray"<<ray<<endl;
90        }
91        pointA = ray.Extrap(tmax);
92  }
93
94  bool detectEmptyViewSpace = true;
95       
96  if (detectEmptyViewSpace) {
97        SetupRay(ray, pointA, -direction);
98  } else
99        SetupRay(ray, viewPoint, -direction);
100       
101       
102  if (mKdTree->CastRay(ray)) {
103        objectB = ray.intersections[0].mObject;
104        pointB = ray.Extrap(ray.intersections[0].mT);
105  } else {
106        objectB = NULL;
107        float tmin, tmax;
108        box.ComputeMinMaxT(ray, &tmin, &tmax);
109        if (tmax > bsize) {
110          //cerr<<"Warning: tmax > box size tmax="<<tmax<<" tmin="<<tmin<<" size="<<bsize<<endl;
111          //cerr<<"ray"<<ray<<endl;
112        }
113        pointB = ray.Extrap(tmax);
114  }
115
116  VssRay *vssRay  = NULL;
117
118  bool validSample = true;
119  if (detectEmptyViewSpace) {
120        // check if the viewpoint lies on the line segment AB
121        if (Distance(pointA, pointB) <
122                Distance(viewPoint, pointA) + Distance(viewPoint, pointB) - Limits::Small) {
123          validSample = false;
124        }
125  }
126       
127  if (validSample) {
128        if (objectA) {
129          vssRay = new VssRay(pointB,
130                                                  pointA,
131                                                  objectB,
132                                                  objectA);
133          vssRays.push_back(vssRay);
134          hits ++;
135        }
136       
137        if (objectB) {
138          vssRay = new VssRay(pointA,
139                                                  pointB,
140                                                  objectA,
141                                                  objectB);
142          vssRays.push_back(vssRay);
143          hits ++;
144        }
145  }
146       
147  return hits;
148}
149
150
151Vector3
152RssPreprocessor::GetViewpoint(AxisAlignedBox3 *viewSpaceBox)
153{
154  AxisAlignedBox3 box;
155       
156  if (viewSpaceBox)
157        box =*viewSpaceBox;
158  else
159        box = mKdTree->GetBox();
160       
161  // shrink the box in the y direction
162  return box.GetRandomPoint();
163}
164
165Vector3
166RssPreprocessor::GetDirection(const Vector3 &viewpoint,
167                                                          AxisAlignedBox3 *viewSpaceBox
168                                                          )
169{
170  Vector3 point;
171  if (!use2dSampling) {
172        Vector3 normal;
173        int i = RandomValue(0, mObjects.size()-1);
174        Intersectable *object = mObjects[i];
175        object->GetRandomSurfacePoint(point, normal);
176  } else {
177        AxisAlignedBox3 box;
178               
179        if (viewSpaceBox)
180          box =*viewSpaceBox;
181        else
182          box = mKdTree->GetBox();
183               
184        point = box.GetRandomPoint();
185        point.y = viewpoint.y;
186  }
187       
188  return point - viewpoint;
189}
190
191int
192RssPreprocessor::GenerateImportanceRays(RssTree *rssTree,
193                                                                                const int desiredSamples,
194                                                                                SimpleRayContainer &rays
195                                                                                )
196{
197  int num;
198
199
200 
201  float avgPvsSize;
202  float avgRayContribution;
203  float avgPvsEntropy;
204  float avgRayLengthEntropy;
205  float avgImportance;
206  float avgRays;
207  rssTree->GetTreeStatistics(
208                                                         avgPvsSize,
209                                                         avgRays,
210                                                         avgRayContribution,
211                                                         avgPvsEntropy,
212                                                         avgRayLengthEntropy,
213                                                         avgImportance);
214 
215  cout<<
216        "#AVG_PVS_SIZE\n"<<avgPvsSize<<endl<<
217        "#AVG_RAYS\n"<<avgRays<<endl<<
218        "#AVG_RAY_CONTRIB\n"<<avgRayContribution<<endl<<
219        "#AVG_PVS_ENTROPY\n"<<avgPvsEntropy<<endl<<
220        "#AVG_RAY_LENGTH_ENTROPY\n"<<avgRayLengthEntropy<<endl<<
221        "#AVG_IMPORTANCE\n"<<avgImportance<<endl;
222 
223  if (0) {
224        float p = desiredSamples/(float)(avgRayContribution*rssTree->stat.Leaves());
225        num = rssTree->GenerateRays(p, rays);
226  } else {
227        int leaves = rssTree->stat.Leaves()/1;
228        num = rssTree->GenerateRays(desiredSamples, leaves, rays);
229  }
230       
231  cout<<"Generated "<<num<<" rays."<<endl;
232       
233  return num;
234}
235
236
237bool
238RssPreprocessor::ExportRays(const char *filename,
239                                                        const VssRayContainer &vssRays,
240                                                        const int number
241                                                        )
242{
243  cout<<"Exporting vss rays..."<<endl<<flush;
244       
245  float prob = number/(float)vssRays.size();
246
247
248  Exporter *exporter = NULL;
249  exporter = Exporter::GetExporter(filename);
250  //    exporter->SetWireframe();
251  //    exporter->ExportKdTree(*mKdTree);
252  exporter->SetFilled();
253  exporter->ExportScene(mSceneGraph->mRoot);
254  exporter->SetWireframe();
255
256  if (mViewSpaceBox) {
257        exporter->SetForcedMaterial(RgbColor(1,0,1));
258        exporter->ExportBox(*mViewSpaceBox);
259        exporter->ResetForcedMaterial();
260  }
261       
262  VssRayContainer rays; for (int i=0; i < vssRays.size(); i++)
263        if (RandomValue(0,1) < prob)
264          rays.push_back(vssRays[i]);
265
266  exporter->ExportRays(rays, RgbColor(1, 0, 0));
267       
268  delete exporter;
269
270  cout<<"done."<<endl<<flush;
271
272  return true;
273}
274
275
276bool
277RssPreprocessor::ExportRssTree(char *filename,
278                                                           RssTree *tree,
279                                                           const Vector3 &dir
280                                                           )
281{
282  Exporter *exporter = Exporter::GetExporter(filename);
283  exporter->SetFilled();
284  exporter->ExportScene(mSceneGraph->mRoot);
285  //  exporter->SetWireframe();
286  bool result = exporter->ExportRssTree2( *tree, dir );
287  delete exporter;
288  return result;
289}
290
291bool
292RssPreprocessor::ExportRssTreeLeaf(char *filename,
293                                                                   RssTree *tree,
294                                                                   RssTreeLeaf *leaf)
295{
296  Exporter *exporter = NULL;
297  exporter = Exporter::GetExporter(filename);
298  exporter->SetWireframe();
299  exporter->ExportKdTree(*mKdTree);
300       
301  if (mViewSpaceBox) {
302        exporter->SetForcedMaterial(RgbColor(1,0,0));
303        exporter->ExportBox(*mViewSpaceBox);
304        exporter->ResetForcedMaterial();
305  }
306       
307  exporter->SetForcedMaterial(RgbColor(0,0,1));
308  exporter->ExportBox(tree->GetBBox(leaf));
309  exporter->ResetForcedMaterial();
310       
311  VssRayContainer rays[4];
312  for (int i=0; i < leaf->rays.size(); i++) {
313        int k = leaf->rays[i].GetRayClass();
314        rays[k].push_back(leaf->rays[i].mRay);
315  }
316       
317  // SOURCE RAY
318  exporter->ExportRays(rays[0], RgbColor(1, 0, 0));
319  // TERMINATION RAY
320  exporter->ExportRays(rays[1], RgbColor(1, 1, 1));
321  // PASSING_RAY
322  exporter->ExportRays(rays[2], RgbColor(1, 1, 0));
323  // CONTAINED_RAY
324  exporter->ExportRays(rays[3], RgbColor(0, 0, 1));
325
326  delete exporter;
327  return true;
328}
329
330void
331RssPreprocessor::ExportRssTreeLeaves(RssTree *tree, const int number)
332{
333  vector<RssTreeLeaf *> leaves;
334  tree->CollectLeaves(leaves);
335
336  int num = 0;
337  int i;
338  float p = number / (float)leaves.size();
339  for (i=0; i < leaves.size(); i++) {
340        if (RandomValue(0,1) < p) {
341          char filename[64];
342          sprintf(filename, "rss-leaf-%04d.x3d", num);
343          ExportRssTreeLeaf(filename, tree, leaves[i]);
344          num++;
345        }
346        if (num >= number)
347          break;
348  }
349}
350
351
352float
353RssPreprocessor::GetAvgPvsSize(RssTree *tree,
354                                                           const vector<AxisAlignedBox3> &viewcells
355                                                           )
356{
357  vector<AxisAlignedBox3>::const_iterator it, it_end = viewcells.end();
358
359  int sum = 0;
360  for (it = viewcells.begin(); it != it_end; ++ it)
361        sum += tree->GetPvsSize(*it);
362       
363  return sum/(float)viewcells.size();
364}
365
366
367void
368RssPreprocessor::ExportPvs(char *filename,
369                                                   RssTree *rssTree
370                                                   )
371{
372  ObjectContainer pvs;
373  if (rssTree->CollectRootPvs(pvs)) {
374        Exporter *exporter = Exporter::GetExporter(filename);
375        exporter->SetFilled();
376        exporter->ExportGeometry(pvs);
377        exporter->SetWireframe();
378        exporter->ExportBox(rssTree->bbox);
379        exporter->ExportViewpoint(rssTree->bbox.Center(), Vector3(1,0,0));
380        delete exporter;
381  }
382}
383
384bool
385RssPreprocessor::ComputeVisibility()
386{
387 
388  mSceneGraph->CollectObjects(&mObjects);
389       
390  long startTime = GetTime();
391 
392  int totalSamples = 0;
393
394  /// Rays used for post processing and visualizations.
395  RayContainer storedRays;
396
397  AxisAlignedBox3 *box = new AxisAlignedBox3(mKdTree->GetBox());
398
399  if (fromBoxVisibility) {
400        float m = box->Min(1);
401        float bsize = box->Size(1);
402
403        float size = 0.02f;
404        float s = 0.5f - size;
405        float olds = Magnitude(box->Size());
406        box->Enlarge(box->Size()*Vector3(-s));
407        //      Vector3 translation = Vector3(-olds*0.2f, 0, 0);
408        Vector3 translation = Vector3(-0.05*olds, 0, 0);
409        box->SetMin(box->Min() + translation);
410        box->SetMax(box->Max() + translation);
411
412        box->SetMin(1,  m + bsize*0.1);
413        box->SetMax(1,  m + bsize*0.6);
414
415       
416  } else {
417               
418        // sample city like heights
419        float m = box->Min(1);
420        float bsize = box->Size(1);
421        box->SetMin(1,  m + bsize*0.2);
422        box->SetMax(1,  m + bsize*0.3);
423  }
424
425  if (use2dSampling)
426        box->SetMax(1, box->Min(1));
427       
428  if (useViewSpaceBox)
429        mViewSpaceBox = box;
430  else
431        mViewSpaceBox = NULL;
432               
433
434  RssTree *rssTree = NULL;
435
436  while (totalSamples < mInitialSamples) {
437        int passContributingSamples = 0;
438        int passSampleContributions = 0;
439        int passSamples = 0;
440        int index = 0;
441               
442        int sampleContributions;
443               
444        int s = Min(mSamplesPerPass, mInitialSamples);
445        for (int k=0; k < s; k++) {
446                       
447          Vector3 viewpoint = GetViewpoint(mViewSpaceBox);
448          Vector3 direction = GetDirection(viewpoint, mViewSpaceBox);
449                       
450          sampleContributions = CastRay(viewpoint, direction, mVssRays);
451                       
452                       
453          //-- CORR matt: put block inside loop
454          if (sampleContributions) {
455                passContributingSamples ++;
456                passSampleContributions += sampleContributions;
457          }
458          passSamples++;
459          totalSamples++;
460        }
461   
462        mPass++;
463               
464        int pvsSize = 0;
465        float avgRayContrib = (passContributingSamples > 0) ?
466          passSampleContributions/(float)passContributingSamples : 0;
467               
468        cout << "#Pass " << mPass << " : t = " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl;
469        cout << "#TotalSamples=" << totalSamples/1000
470                 << "k   #SampleContributions=" << passSampleContributions << " ("
471                 << 100*passContributingSamples/(float)passSamples<<"%)" << " avgPVS="
472                 << pvsSize/(float)mObjects.size() << endl
473                 << "avg ray contrib=" << avgRayContrib << endl;
474               
475        mStats <<
476          "#Pass\n" <<mPass<<endl<<
477          "#Time\n" << TimeDiff(startTime, GetTime())*1e-3 << endl<<
478          "#TotalSamples\n" << totalSamples<< endl<<
479          "#SampleContributions\n" << passSampleContributions << endl <<
480          "#PContributingSamples\n"<<100*passContributingSamples/(float)passSamples<<endl <<
481          "#AvgPVS\n"<< pvsSize/(float)mObjects.size() << endl <<
482          "#AvgRayContrib\n" << avgRayContrib << endl;
483  }
484 
485  cout << "#totalPvsSize=" << mKdTree->CollectLeafPvs() << endl;
486  cout << "#totalRayStackSize=" << mVssRays.size() << endl <<flush;
487 
488
489  if (numExportRays) {
490        char filename[64];
491        sprintf(filename, "rss-rays-initial.x3d");
492        ExportRays(filename, mVssRays, numExportRays);
493  }
494 
495  if (useViewcells)
496        // construct view cells
497        mViewCellsManager->Construct(mObjects, mVssRays, mViewSpaceBox);
498
499  rssTree = new RssTree;
500  // viewcells = Construct(mVssRays);
501       
502  if (fromBoxVisibility)
503        rssTree->Construct(mVssRays, mViewSpaceBox);
504  else
505        rssTree->Construct(mVssRays, NULL);
506
507  cout<<"RssTree root PVS size = "<<rssTree->GetRootPvsSize()<<endl;
508
509  if (exportRssTree) {
510        ExportRssTree("rss-tree-100.x3d", rssTree, Vector3(1,0,0));
511        ExportRssTree("rss-tree-001.x3d", rssTree, Vector3(0,0,1));
512        ExportRssTree("rss-tree-101.x3d", rssTree, Vector3(1,0,1));
513        ExportRssTree("rss-tree-101m.x3d", rssTree, Vector3(-1,0,-1));
514        ExportRssTreeLeaves(rssTree, 10);
515  }
516
517  if (exportPvs) {
518        ExportPvs("rss-pvs-initial.x3d", rssTree);
519  }
520
521  // viewcells->UpdatePVS(newVssRays);
522  // get viewcells as kd tree boxes
523  vector<AxisAlignedBox3> kdViewcells;
524  if (0) {
525        vector<KdLeaf *> leaves;
526        mKdTree->CollectLeaves(leaves);
527        vector<KdLeaf *>::const_iterator it;
528        int targetLeaves = 50;
529        float prob = targetLeaves/(float)leaves.size();
530        for (it = leaves.begin(); it != leaves.end(); ++it)
531          if (RandomValue(0.0f,1.0f) < prob)
532                kdViewcells.push_back(mKdTree->GetBox(*it));
533               
534        float avgPvs = GetAvgPvsSize(rssTree, kdViewcells);
535        cout<<"Initial average PVS size = "<<avgPvs<<endl;
536  }
537
538       
539  int samples = 0;
540  int pass = 0;
541  while (1) {
542        int num = mRssSamplesPerPass;
543        SimpleRayContainer rays;
544        VssRayContainer vssRays;
545               
546        if (!mUseImportanceSampling) {
547          for (int j=0; j < num; j++) {
548                Vector3 viewpoint = GetViewpoint(mViewSpaceBox);
549                Vector3 direction = GetDirection(viewpoint, mViewSpaceBox);
550                rays.push_back(SimpleRay(viewpoint, direction));
551          }
552        } else {
553          num = GenerateImportanceRays(rssTree, num, rays);
554        }
555               
556               
557        for (int i=0; i < rays.size(); i++)
558          CastRay(rays[i].mOrigin, rays[i].mDirection, vssRays);
559               
560        rssTree->AddRays(vssRays);
561               
562        if (1) {
563          int subdivided = rssTree->UpdateSubdivision();
564          cout<<"subdivided leafs = "<<subdivided<<endl;
565          cout<<"#total leaves = "<<rssTree->stat.Leaves()<<endl;
566
567        }
568
569        if (useViewcells) {
570          float avgPvs = GetAvgPvsSize(rssTree, kdViewcells);
571          cout<<"Average PVS size = "<<avgPvs<<endl;
572        }
573
574        if (numExportRays) {
575          char filename[64];
576          if (mUseImportanceSampling)
577                sprintf(filename, "rss-rays-i%04d.x3d", pass);
578          else
579                sprintf(filename, "rss-rays-%04d.x3d", pass);
580         
581          ExportRays(filename, vssRays, numExportRays);
582        }
583
584        samples+=num;
585
586        if (useViewcells) {
587         
588          //-- prepare traversal rays for view cell intersections
589          RayContainer passRays;
590         
591          VssRayContainer::const_iterator it, it_end = vssRays.end();
592         
593          for (it = vssRays.begin(); it != it_end; ++ it)
594                passRays.push_back(new Ray(*(*it)));
595         
596          int sampleContributions = 0;
597          int contributingSamples = 0;
598         
599          /// compute view cell contribution of rays
600          mViewCellsManager->ComputeSampleContributions(passRays,
601                                                                                                        sampleContributions,
602                                                                                                        contributingSamples);
603         
604          //-- save rays for post processing
605          if (((int)storedRays.size() < mViewCellsManager->GetPostProcessSamples()) ||
606                  ((int)storedRays.size() < mViewCellsManager->GetVisualizationSamples()))
607                {
608                  RayContainer::const_iterator it, it_end = passRays.end();
609                 
610                  for (it = passRays.begin(); it != it_end; ++ it)
611                        storedRays.push_back(new Ray(*(*it)));
612                }
613          else
614                {
615                  CLEAR_CONTAINER(passRays);
616                }
617         
618          float pvs = rssTree->GetAvgPvsSize();
619          cout<<"*****************************\n";
620          cout<<samples<<" avgPVS ="<<pvs<<endl;
621          cout<<"sample contributions ="<<sampleContributions<<endl;
622          cout<<"contributing sample ="<<contributingSamples<<endl;
623          cout<<"RssTree root PVS size = "<<rssTree->GetRootPvsSize()<<endl;
624          cout<<"*****************************\n";
625        }
626       
627        if (exportPvs) {
628          char filename[64];
629          sprintf(filename, "rss-pvs-%04d.x3d", pass);
630          ExportPvs(filename, rssTree);
631        }
632
633        if (samples >= mRssSamples)
634          break;
635
636       
637        pass++;
638  }
639 
640  if (useViewcells) {
641       
642        //-- post process view cells
643        mViewCellsManager->PostProcess(mObjects, storedRays);
644       
645        //-- several visualizations and statistics
646        mViewCellsManager->PrintStatistics(Debug);
647       
648        //-- render simulation after merge
649        cout << "\nevaluating render time of final view cells ... ";
650       
651        const SimulationStatistics ss = mViewCellsManager->SimulateRendering();
652       
653        cout << " finished" << endl;
654       
655        cout << ss << endl;
656        Debug << ss << endl;
657       
658        mViewCellsManager->Visualize(mObjects, storedRays);
659  }
660 
661  delete rssTree;
662 
663  return true;
664}
665
Note: See TracBrowser for help on using the repository browser.