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

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