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

Revision 1966, 16.8 KB checked in by bittner, 17 years ago (diff)

samplign preprocessor updates, merge

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
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                        int passContributingSamples = 0;
410                        int passSampleContributions = 0;
411                        int passSamples = 0;
412
413                        int index = 0;
414
415                        int sampleContributions;
416
417                        int s = Min(mSamplesPerPass, mInitialSamples);
418                        for (int k=0; k < s; k++)
419                        {
420                                Vector3 viewpoint;
421
422                                mViewCellsManager->GetViewPoint(viewpoint);
423                                const Vector3 direction = GetDirection(viewpoint, &mViewCellsManager->GetViewSpaceBox());
424
425                                const SimpleRay sray(viewpoint, direction,
426                                                                         SamplingStrategy::DIRECTION_BOX_BASED_DISTRIBUTION,
427                                                                         1.0f);
428                                sampleContributions = mRayCaster->CastRay(sray,
429                                                                                                                  mVssRays,
430                                                                                                                  mViewCellsManager->GetViewSpaceBox(),
431                                                                                                                  true);
432
433                                if (sampleContributions) {
434                                        passContributingSamples ++;
435                                        passSampleContributions += sampleContributions;
436                                }
437                                passSamples++;
438                                totalSamples++;
439                        }
440
441                        mPass++;
442                        int pvsSize = 0;
443                        float avgRayContrib = (passContributingSamples > 0) ?
444                                passSampleContributions/(float)passContributingSamples : 0;
445
446                        cout << "#Pass " << mPass << " : t = " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl;
447                        cout << "#TotalSamples=" << totalSamples/1000
448                                << "#SampleContributions=" << passSampleContributions << " ("
449                                << 100*passContributingSamples/(float)passSamples<<"%)" << " avgPVS="
450                                << pvsSize/(float)mObjects.size() << endl
451                                << "avg ray contrib=" << avgRayContrib << endl;
452
453                        mStats <<
454                                "#Pass\n" <<mPass<<endl<<
455                                "#Time\n" << TimeDiff(startTime, GetTime())*1e-3 << endl<<
456                                "#TotalSamples\n" << totalSamples<< endl<<
457                                "#SampleContributions\n" << passSampleContributions << endl <<
458                                "#PContributingSamples\n"<<100*passContributingSamples/(float)passSamples<<endl <<
459                                "#AvgPVS\n"<< pvsSize/(float)mObjects.size() << endl <<
460                                "#AvgRayContrib\n" << avgRayContrib << endl;
461                }
462
463                cout << "#totalPvsSize=" << mKdTree->CollectLeafPvs() << endl;
464
465
466
467        }
468
469
470        cout << "#totalRayStackSize=" << (int)mVssRays.size() << endl << flush;
471        Debug << (int)mVssRays.size() << " rays generated in "
472                << TimeDiff(initialTime, GetTime()) * 1e-3 << " seconds" << endl;
473
474        if (mStoreInitialSamples)
475        {
476                cout << "Writing " << (int)mVssRays.size() << " samples to file ... ";
477                ExportSamples(mVssRays);
478                cout << "finished\n" << endl;
479
480                /*VssRayContainer dummyRays;
481                LoadSamples(dummyRays, mObjects);
482                Debug << "rays " << (int)mVssRays.size() << " " << dummyRays.size() << endl;
483
484                for (int i = 0; i < (int)mVssRays.size(); ++ i)
485                {
486                Debug << mVssRays[i]->GetOrigin() << " " << mVssRays[i]->GetTermination() << " " << mVssRays[i]->mOriginObject << " " << mVssRays[i]->mTerminationObject << endl;
487                Debug << dummyRays[i]->GetOrigin() << " " << dummyRays[i]->GetTermination() << " " << dummyRays[i]->mOriginObject << " " << dummyRays[i]->mTerminationObject << endl << endl;
488                }*/
489        }
490
491
492        //int numExportRays = 2000;
493        int numExportRays = 0;
494
495        if (numExportRays) {
496                char filename[64];
497                sprintf(filename, "vss-rays-initial.x3d");
498                ExportRays(filename, mVssRays, numExportRays);
499        }
500
501        vssTree = new VssTree;
502        // viewcells = Construct(mVssRays);
503
504        vssTree->Construct(mVssRays, NULL);
505        cout<<"VssTree root PVS size = "<<vssTree->GetRootPvsSize()<<endl;
506
507        if (0) ExportRays("kdtree.x3d", mVssRays, 10);
508
509        if (0)
510        {
511                ExportVssTree("vss-tree-100.x3d", vssTree, Vector3(1,0,0));
512                ExportVssTree("vss-tree-001.x3d", vssTree, Vector3(0,0,1));
513                ExportVssTree("vss-tree-101.x3d", vssTree, Vector3(1,0,1));
514                ExportVssTree("vss-tree-101m.x3d", vssTree, Vector3(-1,0,-1));
515                ExportVssTreeLeaves(vssTree, 10);
516        }
517
518        // viewcells->UpdatePVS(newVssRays);
519        // get viewcells as kd tree boxes
520        vector<AxisAlignedBox3> kdViewcells;
521        if (0) {
522                vector<KdLeaf *> leaves;
523                mKdTree->CollectLeaves(leaves);
524                vector<KdLeaf *>::const_iterator it;
525                int targetLeaves = 50;
526                float prob = targetLeaves/(float)leaves.size();
527                for (it = leaves.begin(); it != leaves.end(); ++it)
528                        if (RandomValue(0.0f,1.0f) < prob)
529                                kdViewcells.push_back(mKdTree->GetBox(*it));
530
531                float avgPvs = GetAvgPvsSize(vssTree, kdViewcells);
532                cout<<"Initial average PVS size = "<<avgPvs<<endl;
533        }
534
535
536        int samples = 0;
537        int pass = 0;
538
539
540        // cast view cell samples
541        while (samples < mVssSamples)
542        {
543
544                int num = mVssSamplesPerPass;
545                SimpleRayContainer rays;
546                VssRayContainer vssRays;
547
548                if (!mUseImportanceSampling) {
549                        for (int j=0; j < num; j++) {
550                                Vector3 viewpoint;
551                                mViewCellsManager->GetViewPoint(viewpoint);
552                                Vector3 direction = GetDirection(viewpoint, NULL);
553                                rays.push_back(SimpleRay(viewpoint, direction,
554                                                                                 SamplingStrategy::DIRECTION_BOX_BASED_DISTRIBUTION,
555                                                                                 1.0f)
556                                                           );
557                        }
558                } else {
559                        num = GenerateImportanceRays(vssTree, num, rays);
560                }
561
562                CastRays(rays, vssRays, true);
563                vssTree->AddRays(vssRays);
564
565                if (0) {
566                        int subdivided = vssTree->UpdateSubdivision();
567                        cout<<"subdivided leafs = "<<subdivided<<endl;
568                }
569
570                float avgPvs = GetAvgPvsSize(vssTree, kdViewcells);
571                cout<<"Average PVS size = "<<avgPvs<<endl;
572
573                /// compute view cell contribution of rays
574                mViewCellsManager->ComputeSampleContributions(vssRays, true, false);
575
576                if (numExportRays) {
577                        char filename[64];
578                        if (mUseImportanceSampling)
579                                sprintf(filename, "vss-rays-i%04d.x3d", pass);
580                        else
581                                sprintf(filename, "vss-rays-%04d.x3d", pass);
582
583                        ExportRays(filename, vssRays, numExportRays);
584                }
585
586                samples+=num;
587                float pvs = vssTree->GetAvgPvsSize();
588                cout<<"*****************************\n";
589                cout<<samples<<" avgPVS ="<<pvs<<endl;
590                cout<<"VssTree root PVS size = "<<vssTree->GetRootPvsSize()<<endl;
591                cout<<"*****************************\n";
592                //      if (samples >= mVssSamples) break;
593                pass ++;
594        }
595
596        if (mTestBeamSampling && mUseGlRenderer)
597        {       
598                TestBeamCasting(vssTree, mViewCellsManager, mObjects);
599        }
600
601        if (0)  Debug << vssTree->stat << endl;
602
603        if (0)
604        {
605                VssRayContainer viewCellRays;
606                // compute rays used for view cells construction
607                const int numRays = mViewCellsManager->GetVisualizationSamples();
608                vssTree->CollectRays(viewCellRays, numRays);
609        }
610
611
612        ////////////////////
613        //-- render simulation after construction
614
615        mRenderSimulator->RenderScene();
616        SimulationStatistics ss;
617        mRenderSimulator->GetStatistics(ss);
618        Debug << "\nFinal view cells partition render time\n" << ss << endl;
619        cout << "\nFinal view cells partition render time\n" << ss << endl;
620
621        delete vssTree;
622
623        return true;
624}
625
626}
Note: See TracBrowser for help on using the repository browser.