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

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