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

Revision 1771, 16.5 KB checked in by bittner, 18 years ago (diff)

merge, preparing sampling strategy support for mixed distributions, filter changes, histogram output for preprocessor

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