source: GTP/trunk/Lib/Vis/Preprocessing/src/VssPreprocessor.cpp @ 1528

Revision 1528, 18.0 KB checked in by mattausch, 18 years ago (diff)

worked on gvs

Line 
1#include "SceneGraph.h"
2#include "KdTree.h"
3#include "VssPreprocessor.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 "VssTree.h"
11#include "ViewCellsManager.h"
12#include "RenderSimulator.h"
13#include "Beam.h"
14#include "GlRenderer.h"
15#include "Intersectable.h"
16#include "RayCaster.h"
17
18
19namespace GtpVisibilityPreprocessor {
20
21bool use2dSampling = false;
22bool useViewspacePlane = false;
23
24VssPreprocessor::VssPreprocessor():
25  mVssRays()
26{
27  // this should increase coherence of the samples
28  Environment::GetSingleton()->GetIntValue("VssPreprocessor.samplesPerPass", mSamplesPerPass);
29  Environment::GetSingleton()->GetIntValue("VssPreprocessor.initialSamples", mInitialSamples);
30  Environment::GetSingleton()->GetIntValue("VssPreprocessor.vssSamples", mVssSamples);
31  Environment::GetSingleton()->GetIntValue("VssPreprocessor.vssSamplesPerPass", mVssSamplesPerPass);
32  Environment::GetSingleton()->GetBoolValue("VssPreprocessor.useImportanceSampling", mUseImportanceSampling);
33 
34  Environment::GetSingleton()->GetBoolValue("VssPreprocessor.loadInitialSamples", mLoadInitialSamples);
35  Environment::GetSingleton()->GetBoolValue("VssPreprocessor.storeInitialSamples", mStoreInitialSamples);
36  Environment::GetSingleton()->GetBoolValue("VssPreprocessor.useViewSpaceBox", mUseViewSpaceBox);
37  Environment::GetSingleton()->GetBoolValue("VssPreprocessor.testBeamSampling", mTestBeamSampling);
38  Environment::GetSingleton()->GetBoolValue("VssPreprocessor.enlargeViewSpace", mEnlargeViewSpace);
39  Environment::GetSingleton()->GetBoolValue("Preprocessor.detectEmptyViewSpace", mDetectEmptyViewSpace);
40 
41  useViewspacePlane = mUseViewSpaceBox; //hack
42
43  mViewSpaceBox.Initialize();
44 
45  Debug << "*********** vss preprocessor options **************" << endl;
46  Debug << "use view space box=" << mUseViewSpaceBox << endl;
47  Debug << "enlarge view space=" << mEnlargeViewSpace << endl;
48  Debug << "*********** end vss preprocessor options **************" << endl;
49
50  mStats.open("stats.log");
51}
52
53
54VssPreprocessor::~VssPreprocessor()
55{
56        CLEAR_CONTAINER(mVssRays);
57}
58
59
60Vector3
61VssPreprocessor::GetViewpoint(AxisAlignedBox3 *viewSpaceBox)
62{
63  AxisAlignedBox3 box;
64
65  if (viewSpaceBox)
66        box =*viewSpaceBox;
67  else
68        box = mKdTree->GetBox();
69
70  // shrink the box in the y direction
71  return box.GetRandomPoint();
72}
73
74Vector3
75VssPreprocessor::GetDirection(const Vector3 &viewpoint,
76                                                          AxisAlignedBox3 *viewSpaceBox
77                                                          )
78{
79  Vector3 point;
80  if (!use2dSampling)
81  {
82          if (0)
83          {
84                  Vector3 normal;
85                  int i = Random((int)mObjects.size());
86                  Intersectable *object = mObjects[i];
87                  object->GetRandomSurfacePoint(point, normal);
88          }
89          else
90                  point = mKdTree->GetBox().GetRandomPoint();
91        //        point = viewpoint + UniformRandomVector();
92  }
93  else
94  {
95          AxisAlignedBox3 box;
96
97          if (viewSpaceBox)
98                  box =*viewSpaceBox;
99          else
100                  box = mKdTree->GetBox();
101
102          point = box.GetRandomPoint();
103          point.y = viewpoint.y;
104  }
105
106  return point - viewpoint;
107}
108
109int
110VssPreprocessor::GenerateImportanceRays(VssTree *vssTree,
111                                                                                const int desiredSamples,
112                                                                                SimpleRayContainer &rays
113                                                                                )
114{
115  int num;
116  if (0) {
117        float minRayContribution;
118        float maxRayContribution;
119        float avgRayContribution;
120
121        vssTree->GetRayContributionStatistics(minRayContribution,
122                                                                                  maxRayContribution,
123                                                                                  avgRayContribution);
124
125        cout<<
126          "#MIN_RAY_CONTRIB\n"<<minRayContribution<<endl<<
127          "#MAX_RAY_CONTRIB\n"<<maxRayContribution<<endl<<
128          "#AVG_RAY_CONTRIB\n"<<avgRayContribution<<endl;
129
130        float p = desiredSamples/(float)(avgRayContribution*vssTree->stat.Leaves());
131        num = vssTree->GenerateRays(p, rays);
132  } else {
133        int leaves = vssTree->stat.Leaves();
134        num = vssTree->GenerateRays(desiredSamples, leaves, rays);
135  }
136
137  cout<<"Generated "<<num<<" rays."<<endl;
138
139  return num;
140}
141
142
143bool
144VssPreprocessor::ExportRays(const char *filename,
145                                                        const VssRayContainer &vssRays,
146                                                        const int number
147                                                        )
148{
149  cout<<"Exporting vss rays..."<<endl<<flush;
150
151  Exporter *exporter = NULL;
152  exporter = Exporter::GetExporter(filename);
153  exporter->SetWireframe();
154  exporter->ExportKdTree(*mKdTree);
155  exporter->SetFilled();
156  exporter->ExportScene(mSceneGraph->GetRoot());
157  exporter->SetWireframe();
158
159  exporter->SetForcedMaterial(RgbColor(1,0,1));
160  exporter->ExportBox(mViewSpaceBox);
161  exporter->ResetForcedMaterial();
162
163
164  VssRayContainer rays;
165  vssRays.SelectRays(number, rays);
166 
167  //exporter->ExportRays(rays, RgbColor(1, 0, 0));
168
169  delete exporter;
170
171  cout<<"done."<<endl<<flush;
172
173  return true;
174}
175
176
177bool
178VssPreprocessor::ExportVssTree(char *filename,
179                                                           VssTree *tree,
180                                                           const Vector3 &dir
181                                                           )
182{
183  Exporter *exporter = Exporter::GetExporter(filename);
184  exporter->SetFilled();
185  exporter->ExportScene(mSceneGraph->GetRoot());
186  //  exporter->SetWireframe();
187  bool result = exporter->ExportVssTree2( *tree, dir );
188  delete exporter;
189  return result;
190}
191
192bool
193VssPreprocessor::ExportVssTreeLeaf(char *filename,
194                                                                   VssTree *tree,
195                                                                   VssTreeLeaf *leaf)
196{
197  Exporter *exporter = NULL;
198  exporter = Exporter::GetExporter(filename);
199  exporter->SetWireframe();
200  exporter->ExportKdTree(*mKdTree);
201
202  exporter->SetForcedMaterial(RgbColor(1,0,0));
203  exporter->ExportBox(mViewSpaceBox);
204  exporter->ResetForcedMaterial();
205
206  exporter->SetForcedMaterial(RgbColor(0,0,1));
207  exporter->ExportBox(tree->GetBBox(leaf));
208  exporter->ResetForcedMaterial();
209
210  VssRayContainer rays[4];
211  for (int i=0; i < leaf->rays.size(); i++) {
212        int k = leaf->rays[i].GetRayClass();
213        rays[k].push_back(leaf->rays[i].mRay);
214  }
215
216  // SOURCE RAY
217  exporter->ExportRays(rays[0], RgbColor(1, 0, 0));
218  // TERMINATION RAY
219  exporter->ExportRays(rays[1], RgbColor(1, 1, 1));
220  // PASSING_RAY
221  exporter->ExportRays(rays[2], RgbColor(1, 1, 0));
222  // CONTAINED_RAY
223  exporter->ExportRays(rays[3], RgbColor(0, 0, 1));
224
225  delete exporter;
226  return true;
227}
228
229void
230VssPreprocessor::ExportVssTreeLeaves(VssTree *tree, const int number)
231{
232  vector<VssTreeLeaf *> leaves;
233  tree->CollectLeaves(leaves);
234
235  int num = 0;
236  int i;
237  float p = number / (float)leaves.size();
238  for (i=0; i < leaves.size(); i++) {
239        if (RandomValue(0,1) < p) {
240          char filename[64];
241          sprintf(filename, "vss-leaf-%04d.x3d", num);
242          ExportVssTreeLeaf(filename, tree, leaves[i]);
243          num++;
244        }
245        if (num >= number)
246          break;
247  }
248}
249
250
251void VssPreprocessor::TestBeamCasting(VssTree *tree,
252                                                                          ViewCellsManager *vm,
253                                                                          const ObjectContainer &objects)
254{
255        //debuggerWidget = new GlDebuggerWidget(renderer);
256        //  renderer->resize(640, 480);
257        //debuggerWidget->resize(640, 480);
258
259        vector<VssTreeLeaf *> leaves;
260        tree->CollectLeaves(leaves);
261
262        Exporter *exporter = Exporter::GetExporter("shafts.x3d");
263
264        exporter->SetWireframe();
265        exporter->ExportGeometry(objects);
266        exporter->SetFilled();
267        //Randomize();
268// §§matt
269//      debuggerWidget = new GlDebuggerWidget(renderer);
270
271        /*debuggerWidget->mBeam = beam;
272        debuggerWidget->mSourceObject = sourceObj;
273        debuggerWidget->mSamples = 10000;
274       
275        Debug << "showing window" << endl;
276        debuggerWidget->show();
277       
278        renderer->makeCurrent();*/
279
280        for (int i = 0; i < 10; ++ i)
281        {
282                Beam beam;
283                Intersectable *sourceObj = mObjects[5];
284
285                const int index = (int)RandomValue(0, (Real)((int)leaves.size() - 1));
286                VssTreeLeaf *leaf = leaves[index];
287
288                AxisAlignedBox3 dirBox = tree->GetDirBBox(leaf);
289                AxisAlignedBox3 box = tree->GetBBox(leaf);
290               
291                beam.Construct(box, dirBox);
292
293                // collect kd leaves and view cells
294                mKdTree->CastBeam(beam);
295                vm->CastBeam(beam);
296
297                Debug << "found " << (int)beam.mViewCells.size() << " view cells and "
298                          << (int)beam.mKdNodes.size() << " kd nodes" << endl;
299
300                BeamSampleStatistics stats;
301// §§matt
302/*              renderer->SampleBeamContributions(sourceObj,
303                                                                                  beam,
304                                                                                  200000,
305                                                                                  stats);
306
307                char s[64]; sprintf(s, "shaft%04d.png", i);
308
309                QImage image = renderer->toImage();
310                image.save(s, "PNG");
311                Debug << "beam statistics: " << stats << endl << endl;
312*/
313                if (1)
314                {
315                        AxisAlignedBox3 sbox = mSceneGraph->GetBox();
316                        Vector3 bmin = sbox.Min() - 150.0f;
317                        Vector3 bmax = sbox.Max() + 150.0f;
318                        AxisAlignedBox3 vbox(bmin, bmax);
319               
320                        exporter->ExportBeam(beam, vbox);
321                }
322
323                bool exportViewCells = false;
324                if (exportViewCells)
325                {
326                        ViewCellContainer::const_iterator it, it_end = beam.mViewCells.end();
327                       
328                        for (it = beam.mViewCells.begin(); it != beam.mViewCells.end(); ++ it)
329                        {
330                                BspNodeGeometry geom;
331                                AxisAlignedBox3 vbox;
332                                vbox.Initialize();
333                                vbox.Include((*it)->GetMesh());
334                       
335                                exporter->SetWireframe();
336                                exporter->ExportBox(vbox);
337                                exporter->SetFilled();
338                                exporter->ExportViewCell(*it);
339                        }
340
341                        /*vector<KdNode *>::const_iterator it, it_end = beam.mKdNodes.end();
342                       
343                        for (it = beam.mKdNodes.begin(); it != beam.mKdNodes.end(); ++ it)
344                        {
345                                exporter->ExportBox(mKdTree->GetBox((*it)));
346                        }*/
347                }
348        }
349        /*while (1)
350        { debuggerWidget->repaint();
351        };*/
352        delete exporter;
353}
354
355
356float
357VssPreprocessor::GetAvgPvsSize(VssTree *tree,
358                                                           const vector<AxisAlignedBox3> &viewcells
359                                                           )
360{
361  vector<AxisAlignedBox3>::const_iterator it, it_end = viewcells.end();
362
363  int sum = 0;
364  for (it = viewcells.begin(); it != it_end; ++ it)
365        sum += tree->GetPvsSize(*it);
366
367  return sum/(float)viewcells.size();
368}
369
370bool
371VssPreprocessor::ComputeVisibility()
372{
373        Debug << "type: vss" << endl;
374
375  long startTime = GetTime();
376
377  int totalSamples = 0;
378
379
380  AxisAlignedBox3 box(mKdTree->GetBox());
381 
382  if (!useViewspacePlane) {
383        float size = 0.05f;
384        float s = 0.5f - size;
385        float olds = Magnitude(box.Size());
386        box.Enlarge(box.Size()*Vector3(-s));
387        Vector3 translation = Vector3(-olds*0.1f, 0, 0);
388        box.SetMin(box.Min() + translation);
389        box.SetMax(box.Max() + translation);
390  } else {
391
392        // sample city like heights
393        box.SetMin(1, box.Min(1) + box.Size(1)*0.2f);
394        box.SetMax(1, box.Min(1) + box.Size(1)*0.3f);
395  }
396
397  if (use2dSampling)
398        box.SetMax(1, box.Min(1));
399
400  cout << "use view space box=" << mUseViewSpaceBox << endl;
401
402 
403  if (mUseViewSpaceBox)
404  {
405          if (!mEnlargeViewSpace)
406          {
407                  mViewSpaceBox = AxisAlignedBox3(box);
408          }
409          else
410          {
411                  mViewSpaceBox = AxisAlignedBox3(mKdTree->GetBox());
412
413                  if (0)
414                  {
415                          // HACK: enlarge in y directon
416                          Vector3 size = mViewSpaceBox.Size();
417                       
418                          size[1] *= 1.25;
419                          Vector3 enlarge(size[0] * 0.25f, size[1] * 0.0f, size[2] * 0.25f);
420                          //Vector3 enlarge(size[0] * 4.0f, 0.0f, 0.0f);
421
422                          mViewSpaceBox.Enlarge(enlarge);
423                          mViewSpaceBox.SetMax(mViewSpaceBox.Max() + enlarge);
424                  }
425                  else
426                  {
427                          AxisAlignedBox3 tbox(mViewSpaceBox);
428
429                          Vector3 size = mViewSpaceBox.Size();
430                          tbox.SetMax(0, mViewSpaceBox.Max(0) + size[0] * 0.5f);
431                          tbox.SetMin(0, mViewSpaceBox.Min(0) + size[0]);
432                          mViewSpaceBox = tbox;
433                  }             
434          }
435  }
436  else
437  {
438          mViewSpaceBox = AxisAlignedBox3(mKdTree->GetBox());
439  }
440 
441  mSceneGraph->CollectObjects(&mObjects);
442
443  if (!mLoadViewCells)
444  {
445          //-- generate new view cells from the scratch
446          //-- for construction the manager uses it's own set of samples
447          ConstructViewCells(mViewSpaceBox);
448  }
449#if 0
450  else
451  {     
452          //-- load view cells from file
453          //-- test successful view cells loading by exporting them again
454      VssRayContainer dummies;
455          mViewCellsManager->Visualize(mObjects, dummies);
456          mViewCellsManager->ExportViewCells("test.xml.zip", mViewCellsManager->GetExportPvs(), mObjects);
457  }
458#endif
459
460  VssTree *vssTree = NULL;
461  const long initialTime = GetTime();
462
463  if (mLoadInitialSamples)
464  {
465          cout << "Loading samples from file ... ";
466          LoadSamples(mVssRays, mObjects);
467          cout << "finished\n" << endl;
468          totalSamples = (int)mVssRays.size();
469  }
470  else
471  {
472        while (totalSamples < mInitialSamples) {
473                int passContributingSamples = 0;
474                int passSampleContributions = 0;
475                int passSamples = 0;
476
477                int index = 0;
478
479                int sampleContributions;
480
481                int s = Min(mSamplesPerPass, mInitialSamples);
482                for (int k=0; k < s; k++)
483                {
484                        Vector3 viewpoint;
485               
486                        mViewCellsManager->GetViewPoint(viewpoint);
487                        const Vector3 direction = GetDirection(viewpoint, &mViewSpaceBox);
488
489                        const SimpleRay sray(viewpoint, direction);
490                        sampleContributions = mRayCaster->CastRay(sray, mVssRays, mViewSpaceBox, true);
491
492                        if (sampleContributions) {
493                                passContributingSamples ++;
494                                passSampleContributions += sampleContributions;
495                        }
496                        passSamples++;
497                        totalSamples++;
498                }
499
500                mPass++;
501                int pvsSize = 0;
502                float avgRayContrib = (passContributingSamples > 0) ?
503                        passSampleContributions/(float)passContributingSamples : 0;
504
505                cout << "#Pass " << mPass << " : t = " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl;
506                cout << "#TotalSamples=" << totalSamples/1000
507                        << "#SampleContributions=" << passSampleContributions << " ("
508                        << 100*passContributingSamples/(float)passSamples<<"%)" << " avgPVS="
509                        << pvsSize/(float)mObjects.size() << endl
510                        << "avg ray contrib=" << avgRayContrib << endl;
511
512                mStats <<
513                        "#Pass\n" <<mPass<<endl<<
514                        "#Time\n" << TimeDiff(startTime, GetTime())*1e-3 << endl<<
515                        "#TotalSamples\n" << totalSamples<< endl<<
516                        "#SampleContributions\n" << passSampleContributions << endl <<
517                        "#PContributingSamples\n"<<100*passContributingSamples/(float)passSamples<<endl <<
518                        "#AvgPVS\n"<< pvsSize/(float)mObjects.size() << endl <<
519                        "#AvgRayContrib\n" << avgRayContrib << endl;
520          }
521 
522          cout << "#totalPvsSize=" << mKdTree->CollectLeafPvs() << endl;
523
524
525         
526  }
527 
528
529  cout << "#totalRayStackSize=" << (int)mVssRays.size() << endl << flush;
530  Debug << (int)mVssRays.size() << " rays generated in "
531            << TimeDiff(initialTime, GetTime()) * 1e-3 << " seconds" << endl;
532
533  if (mStoreInitialSamples)
534  {
535          cout << "Writing " << (int)mVssRays.size() << " samples to file ... ";
536          ExportSamples(mVssRays);
537          cout << "finished\n" << endl;
538
539          /*VssRayContainer dummyRays;
540          LoadSamples(dummyRays, mObjects);
541          Debug << "rays " << (int)mVssRays.size() << " " << dummyRays.size() << endl;
542
543          for (int i = 0; i < (int)mVssRays.size(); ++ i)
544          {
545                  Debug << mVssRays[i]->GetOrigin() << " " << mVssRays[i]->GetTermination() << " " << mVssRays[i]->mOriginObject << " " << mVssRays[i]->mTerminationObject << endl;
546                  Debug << dummyRays[i]->GetOrigin() << " " << dummyRays[i]->GetTermination() << " " << dummyRays[i]->mOriginObject << " " << dummyRays[i]->mTerminationObject << endl << endl;
547          }*/
548  }
549
550 
551  //int numExportRays = 2000;
552  int numExportRays = 0;
553
554  if (numExportRays) {
555        char filename[64];
556        sprintf(filename, "vss-rays-initial.x3d");
557        ExportRays(filename, mVssRays, numExportRays);
558  }
559
560  vssTree = new VssTree;
561  // viewcells = Construct(mVssRays);
562
563  vssTree->Construct(mVssRays, NULL);
564  cout<<"VssTree root PVS size = "<<vssTree->GetRootPvsSize()<<endl;
565
566  if (0) ExportRays("kdtree.x3d", mVssRays, 10);
567
568  if (0)
569  {
570          ExportVssTree("vss-tree-100.x3d", vssTree, Vector3(1,0,0));
571          ExportVssTree("vss-tree-001.x3d", vssTree, Vector3(0,0,1));
572          ExportVssTree("vss-tree-101.x3d", vssTree, Vector3(1,0,1));
573          ExportVssTree("vss-tree-101m.x3d", vssTree, Vector3(-1,0,-1));
574          ExportVssTreeLeaves(vssTree, 10);
575  }
576
577  // viewcells->UpdatePVS(newVssRays);
578  // get viewcells as kd tree boxes
579  vector<AxisAlignedBox3> kdViewcells;
580  if (0) {
581        vector<KdLeaf *> leaves;
582        mKdTree->CollectLeaves(leaves);
583        vector<KdLeaf *>::const_iterator it;
584        int targetLeaves = 50;
585        float prob = targetLeaves/(float)leaves.size();
586        for (it = leaves.begin(); it != leaves.end(); ++it)
587          if (RandomValue(0.0f,1.0f) < prob)
588                kdViewcells.push_back(mKdTree->GetBox(*it));
589
590        float avgPvs = GetAvgPvsSize(vssTree, kdViewcells);
591        cout<<"Initial average PVS size = "<<avgPvs<<endl;
592  }
593
594
595  int samples = 0;
596  int pass = 0;
597
598 
599  // cast view cell samples
600  while (samples < mVssSamples)
601  {
602       
603        int num = mVssSamplesPerPass;
604        SimpleRayContainer rays;
605        VssRayContainer vssRays;
606
607        if (!mUseImportanceSampling) {
608          for (int j=0; j < num; j++) {
609                Vector3 viewpoint;
610                mViewCellsManager->GetViewPoint(viewpoint);
611                Vector3 direction = GetDirection(viewpoint, NULL);
612                rays.push_back(SimpleRay(viewpoint, direction));
613          }
614        } else {
615          num = GenerateImportanceRays(vssTree, num, rays);
616        }
617
618        CastRays(rays, vssRays, true);
619        vssTree->AddRays(vssRays);
620
621        if (0) {
622          int subdivided = vssTree->UpdateSubdivision();
623          cout<<"subdivided leafs = "<<subdivided<<endl;
624        }
625
626        float avgPvs = GetAvgPvsSize(vssTree, kdViewcells);
627        cout<<"Average PVS size = "<<avgPvs<<endl;
628
629        /// compute view cell contribution of rays
630        mViewCellsManager->ComputeSampleContributions(vssRays, true, false);
631       
632        if (numExportRays) {
633          char filename[64];
634          if (mUseImportanceSampling)
635                sprintf(filename, "vss-rays-i%04d.x3d", pass);
636          else
637                sprintf(filename, "vss-rays-%04d.x3d", pass);
638
639          ExportRays(filename, vssRays, numExportRays);
640        }
641
642        samples+=num;
643        float pvs = vssTree->GetAvgPvsSize();
644        cout<<"*****************************\n";
645        cout<<samples<<" avgPVS ="<<pvs<<endl;
646        cout<<"VssTree root PVS size = "<<vssTree->GetRootPvsSize()<<endl;
647        cout<<"*****************************\n";
648//      if (samples >= mVssSamples) break;
649        pass ++;
650  }
651
652  if (mTestBeamSampling && mUseGlRenderer)
653  {     
654          TestBeamCasting(vssTree, mViewCellsManager, mObjects);
655  }
656
657  if (0)  Debug << vssTree->stat << endl;
658
659  if (0)
660  {
661          VssRayContainer viewCellRays;
662          // compute rays used for view cells construction
663          const int numRays = mViewCellsManager->GetVisualizationSamples();
664          vssTree->CollectRays(viewCellRays, numRays);
665  }
666
667
668  ////////////////////
669  //-- render simulation after construction
670
671  mRenderSimulator->RenderScene();
672  SimulationStatistics ss;
673  mRenderSimulator->GetStatistics(ss);
674  Debug << "\nFinal view cells partition render time\n" << ss << endl;
675  cout << "\nFinal view cells partition render time\n" << ss << endl;
676
677  delete vssTree;
678 
679  return true;
680}
681
682}
Note: See TracBrowser for help on using the repository browser.