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

Revision 2116, 16.4 KB checked in by mattausch, 17 years ago (diff)

implemented hashpvs

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