source: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp @ 693

Revision 693, 90.4 KB checked in by mattausch, 19 years ago (diff)
Line 
1#include "ViewCellsManager.h"
2#include "RenderSimulator.h"
3#include "Mesh.h"
4#include "Triangle3.h"
5#include "ViewCell.h"
6#include "Environment.h"
7#include "X3dParser.h"
8#include "ViewCellBsp.h"
9#include "KdTree.h"
10#include "VspKdTree.h"
11#include "Exporter.h"
12#include "VspBspTree.h"
13#include "ViewCellsParser.h"
14#include "Beam.h"
15#include "VssPreprocessor.h"
16#include "RssPreprocessor.h"
17
18#define SAMPLE_AFTER_SUBDIVISION 1
19
20
21ViewCellsManager::ViewCellsManager():
22mRenderer(NULL),
23mInitialSamples(0),
24mConstructionSamples(0),
25mPostProcessSamples(0),
26mVisualizationSamples(0),
27mTotalAreaValid(false),
28mTotalArea(0.0f),
29mViewCellsFinished(false),
30mMaxPvsSize(9999999),
31mMinPvsSize(0), // one means only empty view cells are invalid
32mMaxPvsRatio(1.0)
33{
34        mViewSpaceBox.Initialize();
35        ParseEnvironment();
36
37        mViewCellsTree = new ViewCellsTree(this);
38}
39
40
41void ViewCellsManager::ParseEnvironment()
42{
43        // visualization stuff
44        environment->GetBoolValue("ViewCells.Visualization.exportRays", mExportRays);
45        environment->GetBoolValue("ViewCells.Visualization.exportGeometry", mExportGeometry);
46        environment->GetFloatValue("ViewCells.maxPvsRatio", mMaxPvsRatio);
47       
48        bool emptyViewCells = false;
49        environment->GetBoolValue("ViewCells.pruneEmptyViewCells", emptyViewCells);
50        mMinPvsSize = emptyViewCells ? 1 : 0;
51
52        environment->GetBoolValue("ViewCells.processOnlyValidViewCells", mOnlyValidViewCells);
53
54        environment->GetIntValue("ViewCells.Construction.samples", mConstructionSamples);
55        environment->GetIntValue("ViewCells.PostProcess.samples", mPostProcessSamples);
56        environment->GetBoolValue("ViewCells.PostProcess.useRaysForMerge", mUseRaysForMerge);
57
58        environment->GetIntValue("ViewCells.Visualization.samples", mVisualizationSamples);
59
60        environment->GetIntValue("ViewCells.Construction.samplesPerPass", mSamplesPerPass);
61        environment->GetBoolValue("ViewCells.exportToFile", mExportViewCells);
62       
63        environment->GetIntValue("ViewCells.active", mNumActiveViewCells);
64        environment->GetBoolValue("ViewCells.PostProcess.compress", mCompressViewCells);
65        environment->GetBoolValue("ViewCells.Visualization.useClipPlane", mUseClipPlaneForViz);
66        environment->GetBoolValue("ViewCells.PostProcess.merge", mMergeViewCells);
67        environment->GetBoolValue("ViewCells.evaluateViewCells", mEvaluateViewCells);
68        environment->GetBoolValue("ViewCells.showVisualization", mShowVisualization);
69       
70        char buf[100];
71        environment->GetStringValue("ViewCells.samplingType", buf);
72
73       
74        if (strcmp(buf, "box") == 0)
75                mSamplingType = Preprocessor::SPATIAL_BOX_BASED_DISTRIBUTION;
76        else if (strcmp(buf, "directional") == 0)
77                mSamplingType = Preprocessor::DIRECTION_BASED_DISTRIBUTION;
78        else
79        {
80                Debug << "error! wrong sampling type" << endl;
81                exit(0);
82        }
83
84        environment->GetStringValue("ViewCells.Visualization.colorCode", buf);
85
86        if (strcmp(buf, "PVS") == 0)
87                mColorCode = 1;
88        else if (strcmp(buf, "MergedLeaves") == 0)
89                mColorCode = 2;
90        else if (strcmp(buf, "MergedTreeDiff") == 0)
91                mColorCode = 3;
92        else
93                mColorCode = 0;
94
95
96        Debug << "***********View Cells options ****************" << endl;
97        Debug << "color code: " << mColorCode << endl;
98
99        Debug << "export rays: " << mExportRays << endl;
100        Debug << "export geometry: " << mExportGeometry << endl;
101        Debug << "max pvs ratio: " << mMaxPvsRatio << endl;
102       
103        Debug << "prune empty view cells: " << emptyViewCells << endl;
104       
105        Debug << "process only valid view cells: " << mOnlyValidViewCells << endl;
106        Debug << "construction samples: " << mConstructionSamples << endl;
107        Debug << "post process samples: " << mPostProcessSamples << endl;
108        Debug << "post process use rays for merge: " << mUseRaysForMerge << endl;
109        Debug << "visualization samples: " << mVisualizationSamples << endl;
110        Debug << "construction samples per pass: " << mSamplesPerPass << endl;
111        Debug << "export to file: " << mExportViewCells << endl;
112       
113        Debug << "active: " << mNumActiveViewCells << endl;
114        Debug << "post process compress: " << mCompressViewCells << endl;
115        Debug << "visualization use clipPlane: " << mUseClipPlaneForViz << endl;
116        Debug << "post process merge: " << mMergeViewCells << endl;
117        Debug << "evaluate view cells: " << mEvaluateViewCells << endl;
118        Debug << "sampling type: " << mSamplingType << endl;
119        Debug << "show visualization: " << mShowVisualization << endl;
120
121        Debug << endl;
122}
123
124
125ViewCellsManager::~ViewCellsManager()
126{
127        DEL_PTR(mRenderer);
128
129        if (!ViewCellsTreeConstructed())
130                CLEAR_CONTAINER(mViewCells);
131        else
132                DEL_PTR(mViewCellsTree);
133
134        CLEAR_CONTAINER(mMeshContainer);
135}
136
137
138void ViewCellsManager::CollectEmptyViewCells()
139{
140        mEmptyViewCells.clear();
141        ViewCellContainer leaves;
142        mViewCellsTree->CollectLeaves(mViewCellsTree->GetRoot(), leaves);
143
144        ViewCellContainer::const_iterator it, it_end = leaves.end();
145
146        cout << "collecting empty view cells" << endl;
147        int i = 0;
148        for (it = leaves.begin(); it != it_end; ++ it)
149        {
150                if ((*it)->GetPvs().Empty())
151                {
152                        ++ i;
153                        mEmptyViewCells.push_back(*it);
154                }
155        }
156        cout << "view cells found: " << i << endl;
157}
158
159
160void ViewCellsManager::TestEmptyViewCells()
161{
162        mViewCellsTree->CollectLeaves(mViewCellsTree->GetRoot(), mEmptyViewCells);
163
164        ViewCellContainer::const_iterator it, it_end = mEmptyViewCells.end();
165
166        char buf[50];
167        int i = 0;
168        for (it = mEmptyViewCells.begin(); it != it_end; ++ it)
169        {
170                if (!(*it)->GetPvs().Empty())
171                {
172                        sprintf(buf, "empty-viewcells-%09d.x3d", (*it)->GetId());
173                        Exporter *exporter = Exporter::GetExporter(buf);
174                       
175                        if (exporter && i < 20)
176                        {
177                                Debug << "view cell " << (*it)->GetId() << " not empty, pvs: " << (*it)->GetPvs().GetSize() << endl;
178                                ExportViewCellGeometry(exporter, *it);
179                        }
180
181                        ++ i;
182                }
183        }
184        Debug << "\nfound " << i << " new view cells (" << " of " << mEmptyViewCells.size() << ")" << endl << endl;
185}
186
187
188int ViewCellsManager::CastPassSamples(const int samplesPerPass,
189                                                                          const int sampleType,
190                                                                          VssRayContainer &passSamples) const
191{
192        SimpleRayContainer simpleRays;
193
194        preprocessor->GenerateRays(samplesPerPass,
195                                                           sampleType,
196                                                           simpleRays);
197
198        // shoot simple ray and add it to importance samples
199        preprocessor->CastRays(simpleRays, passSamples);
200
201        return (int)passSamples.size();
202}
203
204
205
206/// helper function which destroys rays or copies them into the output ray container
207inline void disposeRays(VssRayContainer &rays, VssRayContainer *outRays)
208{
209        cout << "disposing samples ... ";
210        long startTime = GetTime();
211        int n = (int)rays.size();
212
213        if (outRays)
214        {
215                VssRayContainer::const_iterator it, it_end = rays.end();
216
217                for (it = rays.begin(); it != it_end; ++ it)
218                {
219                        outRays->push_back(*it);
220                }
221        }
222        else
223        {
224                VssRayContainer::const_iterator it, it_end = rays.end();
225
226                for (it = rays.begin(); it != it_end; ++ it)
227                {
228                        //(*it)->Unref();
229                        if (!(*it)->IsActive())
230                                delete (*it);
231                }
232        }
233
234        cout << "finished" << endl;
235        Debug << "disposed " << n << " samples in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl;
236}
237
238
239int ViewCellsManager::Construct(Preprocessor *preprocessor, VssRayContainer *outRays)
240{
241        int numSamples = 0;
242        SimpleRayContainer simpleRays;
243       
244        VssRayContainer initialSamples;
245
246        cout << "view cell construction: casting " << mInitialSamples << " initial samples ... ";
247        //-- construction rays => we use uniform samples for this
248        CastPassSamples(mInitialSamples,
249                                        mSamplingType,
250                                        initialSamples);
251       
252        cout << "finished" << endl;
253
254       
255        // construct view cells
256        const int numInitialSamples =
257                ConstructSubdivision(preprocessor->mObjects, initialSamples);
258
259        numSamples += numInitialSamples;
260
261        // rays can be passed or deleted
262        disposeRays(initialSamples, outRays);
263       
264
265        // -- stats after contruction
266        ResetViewCells();
267
268        Debug << "\nView cells after initial sampling:\n" << mCurrentViewCellsStats << endl;
269
270        if (1) // export initial view cells
271        {
272                cout << "exporting initial view cells (=leaves) ... ";
273                Exporter *exporter = Exporter::GetExporter("view_cells.x3d");
274
275                if (exporter)
276                {
277                        if (mExportGeometry)
278                                exporter->ExportGeometry(preprocessor->mObjects);
279
280                        ExportViewCellsForViz(exporter);
281
282                        delete exporter;
283                }
284                cout << "finished" << endl;
285        }
286
287        //-- guided rays are used for further sampling
288        const int n = mConstructionSamples; //+initialSamples;
289
290        // should we use directional samples?
291        bool dirSamples = mSamplingType == Preprocessor::DIRECTION_BASED_DISTRIBUTION;
292
293        while (numSamples < n)
294        {
295                cout << "casting " << mSamplesPerPass << " samples of " << n << " ... ";
296                VssRayContainer constructionSamples;
297
298                const int samplingType =
299                        dirSamples ?
300                                                Preprocessor::DIRECTION_BASED_DISTRIBUTION :
301                                                Preprocessor::SPATIAL_BOX_BASED_DISTRIBUTION;
302
303                if (0)
304                        dirSamples = !dirSamples; // toggle sampling method
305
306                numSamples += CastPassSamples(mSamplesPerPass,
307                                                                          samplingType,
308                                                                          constructionSamples);
309
310                cout << "finished" << endl;
311
312                cout << "computing sample contribution for " << (int)constructionSamples.size() << " samples ... ";
313
314                // TODO: leak?
315                if (SAMPLE_AFTER_SUBDIVISION)
316                        ComputeSampleContributions(constructionSamples, true, false);
317                cout << "finished" << endl;
318
319
320                disposeRays(constructionSamples, outRays);
321
322                cout << "total samples: " << numSamples << endl;
323        }
324       
325
326        //-- post processing
327        VssRayContainer postProcessSamples;
328
329        //-- construction rays => we use uniform samples for this
330        CastPassSamples(mPostProcessSamples,
331                                    Preprocessor::DIRECTION_BASED_DISTRIBUTION,
332                                        postProcessSamples);
333
334
335        // stats before post processing (i.e., merge)
336        EvaluateViewCellsStats();
337        Debug << "\noriginal view cell partition before post process:\n" << mCurrentViewCellsStats << endl;
338
339        mRenderer->RenderScene();
340        SimulationStatistics ss;
341        dynamic_cast<RenderSimulator *>(mRenderer)->GetStatistics(ss);
342
343    Debug << ss << endl;
344
345
346
347        cout << "starting post processing and visualization" << endl;
348
349
350        // store view cells for postprocessing
351        const bool storeViewCells = true;
352
353
354        if (SAMPLE_AFTER_SUBDIVISION)
355                ComputeSampleContributions(postProcessSamples, true, storeViewCells);
356
357        // merge the view cells
358        PostProcess(preprocessor->mObjects, postProcessSamples);
359
360        // only for testing
361        CollectEmptyViewCells();
362
363
364        //-- visualization
365        if (mShowVisualization)
366        {
367                VssRayContainer visualizationSamples;
368
369                //-- construction rays => we use uniform samples for this
370                CastPassSamples(mVisualizationSamples,
371                                            Preprocessor::DIRECTION_BASED_DISTRIBUTION,
372                                                visualizationSamples);
373
374                if (SAMPLE_AFTER_SUBDIVISION)
375                        ComputeSampleContributions(visualizationSamples, true, storeViewCells);
376
377                // different visualizations
378                Visualize(preprocessor->mObjects, visualizationSamples);
379
380                disposeRays(visualizationSamples, outRays);
381        }
382
383        if (mEvaluateViewCells)
384        {
385                EvalViewCellPartition(preprocessor);
386        }
387       
388        if (0)
389        {
390                ViewCellContainer leaves;
391                mViewCellsTree->CollectLeaves(mViewCellsTree->GetRoot(), leaves);
392                mViewCellsTree->ResetPvs();
393                VssRayContainer dummyRays;
394                CastPassSamples(mInitialSamples, mSamplingType, dummyRays);
395       
396                //ComputeSampleContributions(initialSamples, true, false);
397                ComputeSampleContributions(dummyRays, true, false);
398
399                ViewCellContainer::const_iterator it, it_end = leaves.end();
400
401                for (it = leaves.begin(); it != it_end; ++ it)
402                {
403                        mViewCellsTree->PropagatePvs(*it);
404                }
405
406                mViewCellsTree->ExportStats("dummy.log");
407        }
408
409        return numSamples;
410}
411
412
413void ViewCellsManager::EvalViewCellPartition(Preprocessor *preprocessor)
414{
415        int samplesPerPass;
416        int numSamples;
417        int castSamples = 0;
418
419        char s[64];
420
421        environment->GetIntValue("ViewCells.Evaluation.samplesPerPass", samplesPerPass);
422        environment->GetIntValue("ViewCells.Evaluation.samples", numSamples);
423
424        char statsPrefix[100];
425        environment->GetStringValue("ViewCells.Evaluation.statsPrefix", statsPrefix);
426
427        Debug << "view cell evaluation samples per pass: " << samplesPerPass << endl;
428        Debug << "view cell evaluation samples: " << numSamples << endl;
429        Debug << "view cell stats prefix: " << statsPrefix << endl;
430
431        //VssRayContainer outRays;
432        // should directional sampling be used?
433        bool dirSamples = mSamplingType == Preprocessor::DIRECTION_BASED_DISTRIBUTION;
434
435        cout << "Evaluating view cell partition" << endl;
436
437        ViewCellContainer leaves;
438        mViewCellsTree->CollectLeaves(mViewCellsTree->GetRoot(), leaves);
439
440        bool startFromZero = true;
441
442        // reset pvs and start over from zero
443        if (startFromZero)
444        {
445                mViewCellsTree->ResetPvs();
446        }
447        else // statistics without addidtional samples
448        {
449                cout << "compute new statistics ... ";
450                sprintf(s, "-%09d-eval.log", castSamples);
451                string fName = string(statsPrefix) + string(s);
452
453                mViewCellsTree->ExportStats(fName);
454                cout << "finished" << endl;
455        }
456       
457
458        while (castSamples < numSamples)
459        {
460                VssRayContainer evaluationSamples;
461
462                const int samplingType = mSamplingType;
463                /*      dirSamples ?
464                                                Preprocessor::DIRECTION_BASED_DISTRIBUTION :
465                                                Preprocessor::SPATIAL_BOX_BASED_DISTRIBUTION;
466                */
467                //-- construction rays => we use uniform samples for this
468                CastPassSamples(samplesPerPass, samplingType, evaluationSamples);
469               
470                castSamples += samplesPerPass;
471
472                cout << "casting " << (int)evaluationSamples.size() << " samples " << endl;
473
474                ComputeSampleContributions(evaluationSamples, true, false);
475
476                cout << "compute new statistics ... ";
477
478                ViewCellContainer::const_iterator it, it_end = leaves.end();
479
480                for (it = leaves.begin(); it != it_end; ++ it)
481                {
482                        mViewCellsTree->PropagatePvs(*it);
483                }
484
485                // output stats
486                sprintf(s, "-%09d-eval.log", castSamples);
487                string fileName = string(statsPrefix) + string(s);
488
489                mViewCellsTree->ExportStats(fileName);
490
491                cout << "finished" << endl;
492       
493                disposeRays(evaluationSamples, NULL);
494        }
495
496        // find empty view cells bug
497        TestEmptyViewCells();
498}
499
500
501bool ViewCellsManager::CheckValidity(ViewCell *vc,
502                                                                         int minPvsSize,
503                                                                         int maxPvsSize) const
504{
505
506  if ((vc->GetPvs().GetSize() > maxPvsSize) ||
507          (vc->GetPvs().GetSize() < minPvsSize))
508        {
509          return false;
510        }
511
512  return true;
513}
514
515
516bool ViewCellsManager::ViewCellsTreeConstructed() const
517{
518        return mViewCellsTree->GetRoot();
519}
520
521
522void ViewCellsManager::SetValidity(ViewCell *vc,
523                                                                   int minPvs,
524                                                                   int maxPvs) const
525{
526        vc->SetValid(CheckValidity(vc, minPvs, maxPvs));
527}
528
529
530void
531ViewCellsManager::SetValidity(
532                                                          int minPvsSize,
533                                                          int maxPvsSize) const
534{
535  ViewCellContainer::const_iterator it, it_end = mViewCells.end();
536
537  for (it = mViewCells.begin(); it != it_end; ++ it) {
538        SetValidity(*it, minPvsSize, maxPvsSize);
539  }
540}
541
542void
543ViewCellsManager::SetValidityPercentage(
544                                                                                const float minValid,
545                                                                                const float maxValid
546                                                                                )
547{
548  sort(mViewCells.begin(), mViewCells.end(), ViewCell::SmallerPvs);
549
550  int start = mViewCells.size()*minValid;
551  int end = mViewCells.size()*maxValid;
552
553  for (int i=0; i < mViewCells.size(); i++)
554        mViewCells[i]->SetValid(i >= start && i <= end);
555}
556
557int
558ViewCellsManager::CountValidViewcells() const
559{
560  ViewCellContainer::const_iterator it, it_end = mViewCells.end();
561  int valid = 0;
562  for (it = mViewCells.begin(); it != it_end; ++ it) {
563        if ((*it)->GetValid())
564          valid++;
565  }
566  return valid;
567}
568
569
570bool ViewCellsManager::LoadViewCellsGeometry(const string filename)
571{
572        X3dParser parser;
573
574        environment->GetFloatValue("ViewCells.height", parser.mViewCellHeight);
575
576        bool success = parser.ParseFile(filename, *this);
577        Debug << (int)mViewCells.size() << " view cells loaded" << endl;
578
579        return success;
580}
581
582
583bool ViewCellsManager::GetViewPoint(Vector3 &viewPoint) const
584{
585        viewPoint = mViewSpaceBox.GetRandomPoint();
586
587        return true;
588}
589
590
591float ViewCellsManager::GetViewSpaceVolume()
592{
593        return mViewSpaceBox.GetVolume() * (2.0f * sqr((float)M_PI));
594}
595
596
597bool ViewCellsManager::ViewPointValid(const Vector3 &viewPoint) const
598{
599  if (!ViewCellsConstructed())
600        return mViewSpaceBox.IsInside(viewPoint);
601  else {
602        if (!mViewSpaceBox.IsInside(viewPoint))
603          return false;
604        ViewCell *viewcell = GetViewCell(viewPoint);
605        if (!viewcell || !viewcell->GetValid())
606          return false;
607  }
608  return true;
609}
610
611
612float
613ViewCellsManager::ComputeSampleContributions(const VssRayContainer &rays,
614                                                                                         const bool addRays,
615                                                                                         const bool storeViewCells
616                                                                                         )
617{
618  // view cells not yet constructed
619  if (!ViewCellsConstructed())
620        return 0.0f;
621
622  VssRayContainer::const_iterator it, it_end = rays.end();
623
624  float sum = 0.0f;
625  for (it = rays.begin(); it != it_end; ++ it)
626  {
627          sum += ComputeSampleContributions(*(*it), addRays, storeViewCells);
628          //ComputeSampleContributions(*(*it), addRays);
629          //    sum += (*it)->mPvsContribution;
630  }
631
632  return sum;
633}
634
635
636void ViewCellsManager::EvaluateViewCellsStats()
637{
638        mCurrentViewCellsStats.Reset();
639
640        ViewCellContainer::const_iterator it, it_end = mViewCells.end();
641
642        for (it = mViewCells.begin(); it != it_end; ++ it)
643        {
644                mViewCellsTree->UpdateViewCellsStats(*it, mCurrentViewCellsStats);
645        }
646}
647
648
649void ViewCellsManager::EvaluateRenderStatistics(float &totalRenderCost,
650                                                                                                float &expectedRenderCost,
651                                                                                                float &deviation,
652                                                                                                float &variance,
653                                                                                                int &totalPvs,
654                                                                                                float &avgRenderCost)
655{
656        ViewCellContainer::const_iterator it, it_end = mViewCells.end();
657
658
659        //-- compute expected value
660
661        totalRenderCost = 0;
662        totalPvs = 0;
663
664        for (it = mViewCells.begin(); it != it_end; ++ it)
665        {
666                ViewCell *vc = *it;
667                totalRenderCost += vc->GetPvs().GetSize() * vc->GetVolume();
668                totalPvs += (int)vc->GetPvs().GetSize();
669        }
670
671        // normalize with view space box
672        totalRenderCost /= mViewSpaceBox.GetVolume();
673        expectedRenderCost = totalRenderCost / (float)mViewCells.size();
674        avgRenderCost = totalPvs / (float)mViewCells.size();
675
676
677        //-- compute standard defiation
678        variance = 0;
679        deviation = 0;
680
681        for (it = mViewCells.begin(); it != it_end; ++ it)
682        {
683                ViewCell *vc = *it;
684
685                float renderCost = vc->GetPvs().GetSize() * vc->GetVolume();
686                float dev;
687
688                if (1)
689                        dev = fabs(avgRenderCost - (float)vc->GetPvs().GetSize());
690                else
691                        dev = fabs(expectedRenderCost - renderCost);
692
693                deviation += dev;
694                variance += dev * dev;
695        }
696
697        variance /= (float)mViewCells.size();
698        deviation /= (float)mViewCells.size();
699}
700
701
702
703void ViewCellsManager::AddViewCell(ViewCell *viewCell)
704{
705        mViewCells.push_back(viewCell);
706}
707
708
709float ViewCellsManager::GetArea(ViewCell *viewCell) const
710{
711        return viewCell->GetArea();
712}
713
714
715float ViewCellsManager::GetVolume(ViewCell *viewCell) const
716{
717        return viewCell->GetVolume();
718}
719
720
721void ViewCellsManager::DeriveViewCells(const ObjectContainer &objects,
722                                                                           ViewCellContainer &viewCells,
723                                                                           const int maxViewCells) const
724{
725        // maximal max viewcells
726        int limit = maxViewCells > 0 ?
727                Min((int)objects.size(), maxViewCells) : (int)objects.size();
728
729        for (int i = 0; i < limit; ++ i)
730        {
731                Intersectable *object = objects[i];
732
733                // extract the mesh instances
734                if (object->Type() == Intersectable::MESH_INSTANCE)
735                {
736                        MeshInstance *inst = dynamic_cast<MeshInstance *>(object);
737
738                        ViewCell *viewCell = GenerateViewCell(inst->GetMesh());
739                        viewCells.push_back(viewCell);
740                }
741                //TODO: transformed meshes
742        }
743}
744
745
746ViewCell *ViewCellsManager::ExtrudeViewCell(const Triangle3 &baseTri,
747                                                                                        const float height) const
748{
749        // one mesh per view cell
750        Mesh *mesh = new Mesh();
751
752        //-- construct prism
753
754        // bottom
755        mesh->mFaces.push_back(new Face(2,1,0));
756        // top
757    mesh->mFaces.push_back(new Face(3,4,5));
758        // sides
759        mesh->mFaces.push_back(new Face(1, 4, 3, 0));
760        mesh->mFaces.push_back(new Face(2, 5, 4, 1));
761        mesh->mFaces.push_back(new Face(3, 5, 2, 0));
762
763        //--- extrude new vertices for top of prism
764        Vector3 triNorm = baseTri.GetNormal();
765
766        Triangle3 topTri;
767
768        // add base vertices and calculate top vertices
769        for (int i = 0; i < 3; ++ i)
770                mesh->mVertices.push_back(baseTri.mVertices[i]);
771
772        // add top vertices
773        for (int i = 0; i < 3; ++ i)
774                mesh->mVertices.push_back(baseTri.mVertices[i] + height * triNorm);
775
776        mesh->Preprocess();
777
778        return GenerateViewCell(mesh);
779}
780
781
782void ViewCellsManager::FinalizeViewCells(const bool createMesh)
783{
784        ViewCellContainer::const_iterator it, it_end = mViewCells.end();
785
786        // volume and area of the view cells are recomputed and a view cell mesh is created
787        for (it = mViewCells.begin(); it != it_end; ++ it)
788        {
789                Finalize(*it, createMesh);
790        }
791
792        mTotalAreaValid = false;
793}
794
795
796void ViewCellsManager::Finalize(ViewCell *viewCell, const bool createMesh)
797{
798        // implemented in subclasses
799}
800
801
802ViewCellInterior *ViewCellsManager::MergeViewCells(ViewCell *left, ViewCell *right) const
803{
804        // generate parent view cell
805        ViewCellInterior *vc = new ViewCellInterior();//GenerateViewCell();
806
807        vc->GetPvs() = left->GetPvs();
808        // merge pvs
809        vc->GetPvs().Merge(right->GetPvs());
810
811        //-- merge ray sets
812        if (0)
813        {
814                stable_sort(left->mPiercingRays.begin(), left->mPiercingRays.end());
815                stable_sort(right->mPiercingRays.begin(), right->mPiercingRays.end());
816
817                std::merge(left->mPiercingRays.begin(), left->mPiercingRays.end(),
818                                   right->mPiercingRays.begin(), right->mPiercingRays.end(),
819                                   vc->mPiercingRays.begin());
820        }
821
822
823        vc->SetupChildLink(left);
824        vc->SetupChildLink(right);
825
826
827        return vc;
828}
829
830
831ViewCellInterior *ViewCellsManager::MergeViewCells(ViewCellContainer &children) const
832{
833        ViewCellInterior *vc = new ViewCellInterior();//GenerateViewCell();
834
835        ViewCellContainer::const_iterator it, it_end = children.end();
836
837        for (it = children.begin(); it != it_end; ++ it)
838        {
839                // merge pvs
840                vc->GetPvs().Merge((*it)->GetPvs());
841
842                vc->SetupChildLink(*it);
843        }
844
845        return vc;
846}
847
848
849void ViewCellsManager::SetRenderer(Renderer *renderer)
850{
851        mRenderer = renderer;
852}
853
854
855ViewCellsTree *ViewCellsManager::GetViewCellsTree()
856{
857        return mViewCellsTree;
858}
859
860
861void ViewCellsManager::SetVisualizationSamples(const int visSamples)
862{
863        mVisualizationSamples = visSamples;
864}
865
866
867void ViewCellsManager::SetConstructionSamples(const int constructionSamples)
868{
869        mConstructionSamples = constructionSamples;
870}
871
872
873void ViewCellsManager::SetInitialSamples(const int initialSamples)
874{
875        mInitialSamples = initialSamples;
876}
877
878
879void ViewCellsManager::SetPostProcessSamples(const int postProcessSamples)
880{
881        mPostProcessSamples = postProcessSamples;
882}
883
884
885int ViewCellsManager::GetVisualizationSamples() const
886{
887        return mVisualizationSamples;
888}
889
890
891int ViewCellsManager::GetConstructionSamples() const
892{
893        return mConstructionSamples;
894}
895
896
897int ViewCellsManager::GetPostProcessSamples() const
898{
899        return mPostProcessSamples;
900}
901
902
903void ViewCellsManager::GetPvsStatistics(PvsStatistics &stat)
904{
905  ViewCellContainer::const_iterator it = mViewCells.begin();
906  stat.viewcells = 0;
907  stat.minPvs = 100000000;
908  stat.maxPvs = 0;
909  stat.avgPvs = 0.0f;
910
911  for (; it != mViewCells.end(); ++it) {
912        ViewCell *viewcell = *it;
913        int pvsSize = viewcell->GetPvs().GetSize();
914        if ( pvsSize < stat.minPvs)
915          stat.minPvs = pvsSize;
916        if (pvsSize > stat.maxPvs)
917          stat.maxPvs = pvsSize;
918        stat.avgPvs += pvsSize;
919        stat.viewcells++;
920  }
921  if (stat.viewcells)
922        stat.avgPvs/=stat.viewcells;
923}
924
925
926void ViewCellsManager::PrintPvsStatistics(ostream &s)
927{
928  s<<"############# Viewcell PVS STAT ##################\n";
929  PvsStatistics pvsStat;
930  GetPvsStatistics(pvsStat);
931  s<<"#AVG_PVS\n"<<pvsStat.avgPvs<<endl;
932  s<<"#MAX_PVS\n"<<pvsStat.maxPvs<<endl;
933  s<<"#MIN_PVS\n"<<pvsStat.minPvs<<endl;
934}
935
936
937int ViewCellsManager::CastBeam(Beam &beam)
938{
939        return 0;
940}
941
942
943ViewCellContainer &ViewCellsManager::GetViewCells()
944{
945        return mViewCells;
946}
947
948
949void ViewCellsManager::SetViewSpaceBox(const AxisAlignedBox3 &box)
950{
951        mViewSpaceBox = box;
952
953        CreateClipPlane();
954       
955        mTotalAreaValid = false;
956}
957
958
959void ViewCellsManager::CreateClipPlane()
960{
961        int axis = 0;
962        float pos;
963
964        environment->GetFloatValue("ViewCells.Visualization.clipPlanePos", pos);
965
966        Vector3 point = mViewSpaceBox.Min() +  mViewSpaceBox.Size() * pos;
967
968        if (mUseClipPlaneForViz)
969        environment->GetIntValue("ViewCells.Visualization.clipPlaneAxis", axis);
970
971        Vector3 normal(0,0,0);
972        normal[axis] = 1;
973
974        mClipPlane = Plane3(normal, point);
975}
976
977
978AxisAlignedBox3 ViewCellsManager::GetViewSpaceBox() const
979{
980        return mViewSpaceBox;
981}
982
983
984void ViewCellsManager::ResetViewCells()
985{
986        mViewCells.clear();
987       
988        CollectViewCells();
989       
990        mCurrentViewCellsStats.Reset();
991        EvaluateViewCellsStats();
992
993        // has to be recomputed
994        mTotalAreaValid = false;
995}
996
997
998int ViewCellsManager::GetMaxPvsSize() const
999{
1000        return mMaxPvsSize;
1001}
1002
1003
1004void
1005ViewCellsManager::AddSampleContributions(const VssRayContainer &rays)
1006{
1007  if (!ViewCellsConstructed())
1008        return;
1009
1010  VssRayContainer::const_iterator it, it_end = rays.end();
1011
1012  for (it = rays.begin(); it != it_end; ++ it) {
1013        AddSampleContributions(*(*it));
1014  }
1015}
1016
1017
1018int ViewCellsManager::GetMinPvsSize() const
1019{
1020        return mMinPvsSize;
1021}
1022
1023
1024
1025float ViewCellsManager::GetMaxPvsRatio() const
1026{
1027        return mMaxPvsRatio;
1028}
1029
1030
1031void
1032ViewCellsManager::AddSampleContributions(VssRay &ray)
1033{
1034  // assumes viewcells have been stored...
1035  ViewCellContainer *viewcells = &ray.mViewCells;
1036  ViewCellContainer::const_iterator it;
1037  for (it = viewcells->begin(); it != viewcells->end(); ++it) {
1038        ViewCell *viewcell = *it;
1039        if (viewcell->GetValid()) {
1040          // if ray not outside of view space
1041          viewcell->GetPvs().AddSample(ray.mTerminationObject, ray.mPdf);
1042        }
1043  }
1044}
1045
1046
1047float ViewCellsManager::ComputeSampleContributions(VssRay &ray,
1048                                                                                                   const bool addRays,
1049                                                                                                   const bool storeViewCells)
1050{
1051        ViewCellContainer viewcells;
1052
1053        ray.mPvsContribution = 0;
1054        ray.mRelativePvsContribution = 0.0f;
1055
1056        static Ray hray;
1057        hray.Init(ray);
1058        //hray.mFlags |= Ray::CULL_BACKFACES;
1059        //Ray hray(ray);
1060
1061        float tmin = 0, tmax = 1.0;
1062
1063        if (!GetViewSpaceBox().GetRaySegment(hray, tmin, tmax) || (tmin > tmax))
1064                return 0;
1065
1066        Vector3 origin = hray.Extrap(tmin);
1067        Vector3 termination = hray.Extrap(tmax);
1068
1069        CastLineSegment(origin, termination, viewcells);
1070
1071        // copy viewcells memory efficiently
1072        //const bool storeViewcells = !addRays;
1073
1074        if (storeViewCells)
1075        {
1076                ray.mViewCells.reserve(viewcells.size());
1077                ray.mViewCells = viewcells;
1078        }
1079
1080        ViewCellContainer::const_iterator it = viewcells.begin();
1081
1082        for (; it != viewcells.end(); ++ it)
1083        {
1084                ViewCell *viewcell = *it;
1085                if (viewcell->GetValid())
1086                {
1087                        // if ray not outside of view space
1088                        float contribution;
1089                        if (ray.mTerminationObject &&
1090                                viewcell->GetPvs().GetSampleContribution(ray.mTerminationObject,
1091                                                                                                                 ray.mPdf,
1092                                                                                                                 contribution))
1093                        {
1094                                ++ ray.mPvsContribution;
1095                                ray.mRelativePvsContribution += contribution;
1096                        }
1097                        if (ray.mOriginObject &&
1098                                viewcell->GetPvs().GetSampleContribution(ray.mOriginObject,
1099                                                                                                                 ray.mPdf,
1100                                                                                                                 contribution))
1101                        {
1102                                ++ ray.mPvsContribution;
1103                                ray.mRelativePvsContribution += contribution;
1104                        }
1105                }
1106        }
1107
1108       
1109        if (addRays)
1110        {
1111                for (it = viewcells.begin(); it != viewcells.end(); ++ it)
1112                {
1113                        ViewCell *viewcell = *it;
1114           
1115                        if (viewcell->GetValid())
1116                        {
1117                                // if ray not outside of view space
1118                                 if (ray.mTerminationObject)
1119                                         viewcell->GetPvs().AddSample(ray.mTerminationObject, ray.mPdf);
1120                                 if (ray.mOriginObject)
1121                                         viewcell->GetPvs().AddSample(ray.mOriginObject, ray.mPdf);
1122                        }
1123                }
1124        }
1125
1126        return ray.mRelativePvsContribution;
1127}
1128
1129
1130void ViewCellsManager::GetRaySets(const VssRayContainer &sourceRays,
1131                                                                  const int maxSize,
1132                                                                  VssRayContainer &usedRays,
1133                                                                  VssRayContainer *savedRays) const
1134{
1135        const int limit = min(maxSize, (int)sourceRays.size());
1136        const float prop = (float)limit / ((float)sourceRays.size() + Limits::Small);
1137
1138        VssRayContainer::const_iterator it, it_end = sourceRays.end();
1139        for (it = sourceRays.begin(); it != it_end; ++ it)
1140        {
1141                if (Random(1.0f) < prop)
1142                        usedRays.push_back(*it);
1143                else if (savedRays)
1144                        savedRays->push_back(*it);
1145        }
1146}
1147
1148
1149float ViewCellsManager::GetRendercost(ViewCell *viewCell, float objRendercost) const
1150{
1151        return mViewCellsTree->GetPvsSize(viewCell) * objRendercost;
1152}
1153
1154
1155float ViewCellsManager::GetAccVcArea()
1156{
1157        // if already computed
1158        if (mTotalAreaValid)
1159                return mTotalArea;
1160
1161        mTotalArea = 0;
1162        ViewCellContainer::const_iterator it, it_end = mViewCells.end();
1163
1164        for (it = mViewCells.begin(); it != it_end; ++ it)
1165        {
1166                //Debug << "area: " << GetArea(*it);
1167        mTotalArea += GetArea(*it);
1168        }
1169
1170        mTotalAreaValid = true;
1171
1172        return mTotalArea;
1173}
1174
1175
1176void ViewCellsManager::PrintStatistics(ostream &s) const
1177{
1178        s << mCurrentViewCellsStats << endl;
1179}
1180
1181
1182void ViewCellsManager::CreateUniqueViewCellIds()
1183{
1184        if (ViewCellsTreeConstructed())
1185                mViewCellsTree->CreateUniqueViewCellsIds();
1186        else
1187                for (int i = 0; i < (int)mViewCells.size(); ++ i)
1188                        mViewCells[i]->SetId(i);
1189}
1190
1191
1192void ViewCellsManager::ExportViewCellsForViz(Exporter *exporter) const
1193{
1194        ViewCellContainer::const_iterator it, it_end = mViewCells.end();
1195
1196        for (it = mViewCells.begin(); it != it_end; ++ it)
1197        {
1198                if (!mOnlyValidViewCells || (*it)->GetValid())
1199                {
1200                        ExportColor(exporter, *it);             
1201                        ExportViewCellGeometry(exporter, *it,
1202                                mUseClipPlaneForViz ? &mClipPlane : NULL);
1203                }
1204        }
1205}
1206
1207
1208void ViewCellsManager::CreateViewCellMeshes()
1209{
1210        // convert to meshes
1211        ViewCellContainer::const_iterator it, it_end = mViewCells.end();
1212
1213        for (it = mViewCells.begin(); it != it_end; ++ it)
1214        {
1215                if (!(*it)->GetMesh())
1216                        CreateMesh(*it);
1217        }
1218}
1219
1220
1221bool ViewCellsManager::ExportViewCells(const string filename)
1222{
1223        return false;
1224}
1225
1226
1227void ViewCellsManager::CollectViewCells(const int n)
1228{
1229        mNumActiveViewCells = n;
1230        mViewCells.clear();
1231        CollectViewCells();
1232}
1233
1234
1235void ViewCellsManager::SetViewCellsActive()
1236{
1237        ++ ViewCell::sLastUpdated;
1238        ViewCellContainer::const_iterator it, it_end = mViewCells.end();
1239        for (it = mViewCells.begin(); it != it_end; ++ it)
1240        {
1241                (*it)->SetActive();
1242        }
1243}
1244
1245/**********************************************************************/
1246/*                   BspViewCellsManager implementation               */
1247/**********************************************************************/
1248
1249
1250BspViewCellsManager::BspViewCellsManager(BspTree *bspTree):
1251ViewCellsManager(), mBspTree(bspTree)
1252{
1253        environment->GetIntValue("BspTree.Construction.samples", mInitialSamples);
1254        mBspTree->SetViewCellsManager(this);
1255        mBspTree->mViewCellsTree = mViewCellsTree;
1256}
1257
1258
1259bool BspViewCellsManager::ViewCellsConstructed() const
1260{
1261        return mBspTree->GetRoot() != NULL;
1262}
1263
1264
1265ViewCell *BspViewCellsManager::GenerateViewCell(Mesh *mesh) const
1266{
1267        return new BspViewCell(mesh);
1268}
1269
1270
1271int BspViewCellsManager::ConstructSubdivision(const ObjectContainer &objects,
1272                                                                                          const VssRayContainer &rays)
1273{
1274        // if view cells were already constructed
1275        if (ViewCellsConstructed())
1276                return 0;
1277
1278        int sampleContributions = 0;
1279
1280        // construct view cells using the collected samples
1281        RayContainer constructionRays;
1282        VssRayContainer savedRays;
1283
1284        const int limit = min(mInitialSamples, (int)rays.size());
1285
1286        VssRayContainer::const_iterator it, it_end = rays.end();
1287
1288        const float prop = (float)limit / ((float)rays.size() + Limits::Small);
1289
1290        for (it = rays.begin(); it != it_end; ++ it)
1291        {
1292                if (Random(1.0f) < prop)
1293                        constructionRays.push_back(new Ray(*(*it)));
1294                else
1295                        savedRays.push_back(*it);
1296        }
1297
1298    if (mViewCells.empty())
1299        {
1300                // no view cells loaded
1301                mBspTree->Construct(objects, constructionRays, &mViewSpaceBox);
1302                // collect final view cells
1303                mBspTree->CollectViewCells(mViewCells);
1304        }
1305        else
1306        {
1307                mBspTree->Construct(mViewCells);
1308        }
1309
1310        // destroy rays created only for construction
1311        CLEAR_CONTAINER(constructionRays);
1312
1313        Debug << mBspTree->GetStatistics() << endl;
1314
1315        //EvaluateViewCellsStats();
1316        Debug << "\nView cells after construction:\n" << mCurrentViewCellsStats << endl;
1317
1318        // recast rest of the rays
1319        if (SAMPLE_AFTER_SUBDIVISION)
1320                ComputeSampleContributions(savedRays, true, false);
1321
1322        return sampleContributions;
1323}
1324
1325
1326void BspViewCellsManager::CollectViewCells()
1327{
1328        // view cells tree constructed
1329        if (!ViewCellsTreeConstructed())
1330        {               
1331                mBspTree->CollectViewCells(mViewCells);
1332        }
1333        else
1334        {
1335                // we can use the view cells tree hierarchy to get the right set
1336                mViewCellsTree->CollectBestViewCellSet(mViewCells,
1337                                                                                           mNumActiveViewCells);
1338        }
1339}
1340
1341
1342float BspViewCellsManager::GetProbability(ViewCell *viewCell)
1343{
1344        // compute view cell area as subsititute for probability
1345        if (1)
1346                return GetVolume(viewCell) / GetViewSpaceBox().GetVolume();
1347        else
1348                return GetArea(viewCell) / GetAccVcArea();
1349}
1350
1351
1352
1353int BspViewCellsManager::CastLineSegment(const Vector3 &origin,
1354                                                                                 const Vector3 &termination,
1355                                                                                 ViewCellContainer &viewcells)
1356{
1357        return mBspTree->CastLineSegment(origin, termination, viewcells);
1358}
1359
1360
1361int BspViewCellsManager::PostProcess(const ObjectContainer &objects,
1362                                                                         const VssRayContainer &rays)
1363{
1364        if (!ViewCellsConstructed())
1365        {
1366                Debug << "view cells not constructed" << endl;
1367                return 0;
1368        }
1369       
1370        // view cells already finished before post processing step (i.e. because they were loaded)
1371        if (mViewCellsFinished)
1372        {
1373                FinalizeViewCells(true);
1374                EvaluateViewCellsStats();
1375
1376                return 0;
1377        }
1378
1379        //-- post processing of bsp view cells
1380
1381    int vcSize = 0;
1382        int pvsSize = 0;
1383
1384        //-- merge view cells
1385        cout << "starting post processing using " << mPostProcessSamples << " samples ... ";
1386        long startTime = GetTime();
1387       
1388        VssRayContainer postProcessRays;
1389        GetRaySets(rays, mPostProcessSamples, postProcessRays);
1390
1391        if (mMergeViewCells)
1392        {
1393                cout << "constructing visibility based merge tree" << endl;
1394                mViewCellsTree->ConstructMergeTree(rays, objects);
1395        }
1396        else
1397        {
1398                cout << "constructing spatial merge tree" << endl;
1399                // create spatial merge hierarchy
1400                mViewCellsTree->SetRoot(ConstructSpatialMergeTree(mBspTree->GetRoot()));
1401        }
1402
1403        // export statistics after merge
1404        if (1)
1405        {
1406                char mstats[100];
1407                environment->GetStringValue("ViewCells.mergeStats", mstats);
1408                mViewCellsTree->ExportStats(mstats);
1409        }
1410
1411        //-- stats and visualizations
1412        cout << "finished" << endl;
1413        cout << "merged view cells in "
1414                 << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl;
1415
1416        Debug << "Postprocessing: Merged view cells in "
1417                << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl << endl;
1418       
1419
1420        //-- visualization and statistics
1421    // reset view cells and stats
1422        ResetViewCells();
1423        Debug << "\nView cells after merge:\n" << mCurrentViewCellsStats << endl;
1424
1425
1426        int savedColorCode  = mColorCode;
1427       
1428        //BspLeaf::NewMail();
1429        if (1) // export merged view cells
1430        {
1431                mColorCode = 0;
1432               
1433                Exporter *exporter = Exporter::GetExporter("merged_view_cells.x3d");
1434               
1435
1436                cout << "exporting view cells after merge ... ";
1437
1438                if (exporter)
1439                {
1440                        if (mExportGeometry)
1441                                exporter->ExportGeometry(objects);
1442
1443                        //exporter->SetWireframe();
1444                        exporter->SetFilled();
1445                        ExportViewCellsForViz(exporter);
1446
1447
1448                        delete exporter;
1449                }
1450                cout << "finished" << endl;
1451        }
1452
1453        if (1) // export merged view cells
1454        {
1455                mColorCode = 1;
1456
1457                Exporter *exporter = Exporter::GetExporter("merged_view_cells_pvs.x3d");
1458       
1459                cout << "exporting view cells after merge (pvs size) ... ";     
1460
1461                if (exporter)
1462                {
1463                        //exporter->SetWireframe();
1464                       
1465                        if (mExportGeometry)
1466                                exporter->ExportGeometry(objects);
1467
1468                        //exporter->SetWireframe();
1469                        exporter->SetFilled();
1470                        ExportViewCellsForViz(exporter);
1471
1472                        delete exporter;
1473                }
1474                cout << "finished" << endl;
1475        }
1476
1477       
1478        // only for testing
1479        TestSubdivision();
1480
1481        mColorCode = savedColorCode;
1482
1483        FinalizeViewCells(true);
1484       
1485        // write view cells to disc
1486        if (mExportViewCells)
1487        {
1488                char buff[100];
1489                environment->GetStringValue("ViewCells.filename", buff);
1490                string vcFilename(buff);
1491
1492                ExportViewCells(buff);
1493        }
1494
1495        return 0;
1496}
1497
1498
1499BspViewCellsManager::~BspViewCellsManager()
1500{
1501}
1502
1503
1504int BspViewCellsManager::GetType() const
1505{
1506        return BSP;
1507}
1508
1509
1510void BspViewCellsManager::Visualize(const ObjectContainer &objects,
1511                                                                        const VssRayContainer &sampleRays)
1512{
1513        if (!ViewCellsConstructed())
1514                return;
1515       
1516        int savedColorCode = mColorCode;
1517
1518       
1519       
1520        if (1) // export final view cells
1521        {
1522                mColorCode = 1;
1523
1524                Exporter *exporter = Exporter::GetExporter("final_view_cells.x3d");
1525       
1526                cout << "exporting view cells after merge (pvs size) ... ";     
1527
1528                if (exporter)
1529                {
1530                        //exporter->SetWireframe();
1531                       
1532                        if (mExportGeometry)
1533                                exporter->ExportGeometry(objects);
1534
1535                        //exporter->SetWireframe();
1536                        exporter->SetFilled();
1537                        ExportViewCellsForViz(exporter);
1538
1539                        delete exporter;
1540                }
1541                cout << "finished" << endl;
1542        }
1543
1544        mColorCode = savedColorCode;
1545
1546        //-- visualization of the BSP splits
1547        bool exportSplits = false;
1548        environment->GetBoolValue("BspTree.Visualization.exportSplits", exportSplits);
1549
1550        if (exportSplits)
1551        {
1552                cout << "exporting splits ... ";
1553                ExportSplits(objects);
1554                cout << "finished" << endl;
1555        }
1556
1557        // export single view cells
1558        ExportBspPvs(objects);
1559}
1560
1561
1562inline bool vc_gt(ViewCell *a, ViewCell *b)
1563{
1564        return a->GetPvs().GetSize() > b->GetPvs().GetSize();
1565}
1566
1567
1568void BspViewCellsManager::ExportSplits(const ObjectContainer &objects)
1569{
1570        Exporter *exporter = Exporter::GetExporter("bsp_splits.x3d");
1571
1572        if (exporter)
1573        {
1574                //exporter->SetFilled();
1575
1576                if (mExportGeometry)
1577                        exporter->ExportGeometry(objects);
1578
1579                Material m;
1580                m.mDiffuseColor = RgbColor(1, 0, 0);
1581                exporter->SetForcedMaterial(m);
1582                exporter->SetWireframe();
1583
1584                exporter->ExportBspSplits(*mBspTree, true);
1585
1586                //NOTE: take forced material, else big scenes cannot be viewed
1587                m.mDiffuseColor = RgbColor(0, 1, 0);
1588                exporter->SetForcedMaterial(m);
1589                //exporter->ResetForcedMaterial();
1590
1591                delete exporter;
1592        }
1593}
1594
1595
1596void BspViewCellsManager::ExportBspPvs(const ObjectContainer &objects)
1597{
1598        const int leafOut = 10;
1599
1600        ViewCell::NewMail();
1601
1602        //-- some rays for output
1603        const int raysOut = min((int)mBspRays.size(), mVisualizationSamples);
1604
1605        cout << "visualization using " << mVisualizationSamples << " samples" << endl;
1606        Debug << "\nOutput view cells: " << endl;
1607
1608        // sort view cells to get largest view cells
1609        if (0)
1610                stable_sort(mViewCells.begin(), mViewCells.end(), vc_gt);
1611
1612        int limit = min(leafOut, (int)mViewCells.size());
1613
1614        for (int i = 0; i < limit; ++ i)
1615        {
1616                cout << "creating output for view cell " << i << " ... ";
1617                VssRayContainer vcRays;
1618                Intersectable::NewMail();
1619                ViewCell *vc;
1620
1621                if (0)
1622                        vc = mViewCells[i];
1623                else
1624                        vc = mViewCells[Random((int)mViewCells.size())];
1625
1626                cout << "creating output for view cell " << i << " ... ";
1627
1628                if(0)
1629                {
1630                        // check whether we can add the current ray to the output rays
1631                        for (int k = 0; k < raysOut; ++ k)
1632                        {
1633                                BspRay *ray = mBspRays[k];
1634                                for     (int j = 0; j < (int)ray->intersections.size(); ++ j)
1635                                {
1636                                        BspLeaf *leaf = ray->intersections[j].mLeaf;
1637                                        if (vc == leaf->GetViewCell())
1638                                                vcRays.push_back(ray->vssRay);
1639                                }
1640                        }
1641                }
1642
1643                //bspLeaves[j]->Mail();
1644                char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i);
1645
1646                Exporter *exporter = Exporter::GetExporter(s);
1647
1648                exporter->SetWireframe();
1649
1650                Material m;//= RandomMaterial();
1651                m.mDiffuseColor = RgbColor(0, 1, 0);
1652                exporter->SetForcedMaterial(m);
1653
1654                ExportViewCellGeometry(exporter, vc);
1655               
1656                // export rays piercing this view cell
1657                exporter->ExportRays(vcRays, RgbColor(0, 1, 0));
1658
1659                m.mDiffuseColor = RgbColor(1, 0, 0);
1660                exporter->SetForcedMaterial(m);
1661
1662                ObjectPvsMap::const_iterator it,
1663                        it_end = vc->GetPvs().mEntries.end();
1664
1665                exporter->SetFilled();
1666
1667                // output PVS of view cell
1668                for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it)
1669                {
1670                        Intersectable *intersect = (*it).first;
1671
1672                        if (!intersect->Mailed())
1673                        {
1674                                Material m = RandomMaterial();
1675                                exporter->SetForcedMaterial(m);
1676
1677                                exporter->ExportIntersectable(intersect);
1678                                intersect->Mail();
1679                        }
1680                }
1681
1682                DEL_PTR(exporter);
1683                cout << "finished" << endl;
1684        }
1685
1686        Debug << endl;
1687}
1688
1689
1690void BspViewCellsManager::ExportColor(Exporter *exporter,
1691                                                                          ViewCell *vc) const
1692{
1693        const bool vcValid = CheckValidity(vc, mMinPvsSize, mMaxPvsSize);
1694
1695        float importance = 0;
1696        static Material m;
1697
1698        switch (mColorCode)
1699        {
1700        case 0: // Random
1701                {
1702                        if (vcValid)
1703                        {
1704                                m.mDiffuseColor.r = 0.5f + RandomValue(0.0f, 0.5f);
1705                                m.mDiffuseColor.g = 0.5f + RandomValue(0.0f, 0.5f);
1706                                m.mDiffuseColor.b = 0.5f + RandomValue(0.0f, 0.5f);
1707                        }
1708                        else
1709                        {
1710                                m.mDiffuseColor.r = 0.0f;
1711                                m.mDiffuseColor.g = 1.0f;
1712                                m.mDiffuseColor.b = 0.0f;
1713                        }
1714
1715                        exporter->SetForcedMaterial(m);
1716                        return;
1717                }
1718               
1719        case 1: // pvs
1720                {
1721                        importance = (float)vc->GetPvs().GetSize() /
1722                                (float)mCurrentViewCellsStats.maxPvs;
1723
1724                }
1725                break;
1726        case 2: // merges
1727                {
1728            int lSize = mViewCellsTree->GetSize(vc);
1729                        importance = (float)lSize / (float)mCurrentViewCellsStats.maxLeaves;
1730                }
1731                //break;
1732        case 3: // merge tree differene
1733                {
1734                        // TODO
1735                        //importance = (float)GetMaxTreeDiff(vc) /
1736                        //      (float)(mVspBspTree->GetStatistics().maxDepth * 2);
1737
1738                }
1739                break;
1740        default:
1741                break;
1742        }
1743
1744        // special color code for invalid view cells
1745        m.mDiffuseColor.r = importance;
1746        m.mDiffuseColor.g = 1.0f - m.mDiffuseColor.r;
1747        m.mDiffuseColor.b = vcValid ? 1.0f : 0.0f;
1748
1749        //Debug << "importance: " << importance << endl;
1750        exporter->SetForcedMaterial(m);
1751}
1752
1753
1754void BspViewCellsManager::TestSubdivision()
1755{
1756        ViewCellContainer leaves;
1757        mViewCellsTree->CollectLeaves(mViewCellsTree->GetRoot(), leaves);
1758
1759        ViewCellContainer::const_iterator it, it_end = leaves.end();
1760
1761        const float vol = mViewSpaceBox.GetVolume();
1762        float subdivVol = 0;
1763        float newVol = 0;
1764
1765        for (it = leaves.begin(); it != it_end; ++ it)
1766        {
1767                BspNodeGeometry geom;
1768                BspLeaf *leaf = dynamic_cast<BspViewCell *>(*it)->mLeaf;
1769                mBspTree->ConstructGeometry(leaf, geom);
1770
1771                const float lVol = geom.GetVolume();
1772               
1773                newVol += lVol;
1774                subdivVol += (*it)->GetVolume();
1775        }
1776       
1777        Debug << "exact volume: " << vol << endl;
1778        Debug << "subdivision volume: " << subdivVol << endl;
1779        Debug << "new volume: " << newVol << endl;
1780}
1781
1782
1783void BspViewCellsManager::ExportViewCellGeometry(Exporter *exporter,
1784                                                                                                 ViewCell *vc,
1785                                                                                                 const Plane3 *clipPlane) const
1786{
1787        if (vc->GetMesh())
1788        {
1789                exporter->ExportMesh(vc->GetMesh());
1790                return;
1791        }
1792
1793        BspNodeGeometry geom;
1794        mBspTree->ConstructGeometry(vc, geom);
1795
1796        if (clipPlane)
1797        {
1798                const int cf = Polygon3::ClassifyPlane(geom.GetPolys(), *clipPlane, 0.0001f);
1799
1800                if (cf == Polygon3::BACK_SIDE)
1801                {
1802                        exporter->ExportPolygons(geom.GetPolys());
1803                }
1804                else if (cf == Polygon3::SPLIT)
1805                {
1806                        BspNodeGeometry front;
1807                        BspNodeGeometry back;
1808
1809                        geom.SplitGeometry(front,
1810                                                           back,
1811                                                           *clipPlane,
1812                                                           mViewSpaceBox,
1813                                                           0.0001f);
1814
1815                        if (back.Valid())
1816                                exporter->ExportPolygons(back.GetPolys());
1817                }
1818        }
1819        else
1820        {
1821                exporter->ExportPolygons(geom.GetPolys());
1822        }
1823}
1824
1825
1826void BspViewCellsManager::CreateMesh(ViewCell *vc)
1827{
1828        if (vc->GetMesh())
1829                delete vc->GetMesh();
1830
1831        BspNodeGeometry geom;
1832       
1833        mBspTree->ConstructGeometry(vc, geom);
1834
1835        Mesh *mesh = new Mesh();
1836        geom.AddToMesh(*mesh);
1837        vc->SetMesh(mesh);
1838        mMeshContainer.push_back(mesh);
1839}
1840
1841
1842void BspViewCellsManager::Finalize(ViewCell *viewCell,
1843                                                                   const bool createMesh)
1844{
1845        float area = 0;
1846        float volume = 0;
1847
1848        ViewCellContainer leaves;
1849        mViewCellsTree->CollectLeaves(viewCell, leaves);
1850
1851        ViewCellContainer::const_iterator it, it_end = leaves.end();
1852
1853    for (it = leaves.begin(); it != it_end; ++ it)
1854        {
1855                BspNodeGeometry geom;
1856                BspLeaf *leaf = dynamic_cast<BspViewCell *>(*it)->mLeaf;
1857                mBspTree->ConstructGeometry(leaf, geom);
1858
1859                float lVol = geom.GetVolume();
1860                float lArea = geom.GetArea();
1861
1862                //(*it)->SetVolume(vol);
1863                //(*it)->SetArea(area);
1864
1865                area += lArea;
1866                volume += lVol;
1867
1868        CreateMesh(*it);
1869        }
1870
1871        viewCell->SetVolume(volume);
1872        viewCell->SetArea(area);
1873}
1874
1875
1876ViewCell *BspViewCellsManager::GetViewCell(const Vector3 &point) const
1877{
1878        if (!mBspTree)
1879                return NULL;
1880
1881        if (!mViewSpaceBox.IsInside(point))
1882                return NULL;
1883       
1884        return mBspTree->GetViewCell(point);
1885}
1886
1887
1888void BspViewCellsManager::CollectMergeCandidates(const VssRayContainer &rays,
1889                                                                                                 vector<MergeCandidate> &candidates)
1890{
1891        cout << "collecting merge candidates ... " << endl;
1892
1893        if (mUseRaysForMerge)
1894        {
1895                mBspTree->CollectMergeCandidates(rays, candidates);
1896        }
1897        else
1898        {
1899                vector<BspLeaf *> leaves;
1900                mBspTree->CollectLeaves(leaves);
1901                mBspTree->CollectMergeCandidates(leaves, candidates);
1902        }
1903
1904        cout << "fininshed collecting candidates" << endl;
1905}
1906
1907
1908
1909bool BspViewCellsManager::ExportViewCells(const string filename)
1910{
1911        cout << "exporting view cells to xml ... ";
1912        std::ofstream stream;
1913
1914        // for output we need unique ids for each view cell
1915        CreateUniqueViewCellIds();
1916
1917
1918        stream.open(filename.c_str());
1919        stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"<<endl;
1920        stream << "<Visibility_Solution>" << endl;
1921
1922        //-- the view space bounding box
1923        stream << "<ViewSpaceBox"
1924                   << " min=\"" << mViewSpaceBox.Min().x << " " << mViewSpaceBox.Min().y << " " << mViewSpaceBox.Min().z << "\""
1925                   << " max=\"" << mViewSpaceBox.Max().x << " " << mViewSpaceBox.Max().y << " " << mViewSpaceBox.Max().z << "\" />" << endl;
1926
1927        //-- the type of the view cells hierarchy
1928        //stream << "<Hierarchy name=\"bspTree\" />" << endl;
1929        stream << "<Hierarchy name=\"vspBspTree\" />" << endl; // write vsp bsp here because can use same tree and is bug free
1930        //-- load the view cells itself, i.e., the ids and the pvs
1931        stream << "<ViewCells>" << endl;
1932
1933#if 0
1934       
1935        ViewCellContainer::const_iterator it, it_end = mViewCells.end();
1936               
1937        for (it = mViewCells.begin(); it != it_end; ++ it)
1938                ExportViewCell(*it, stream);
1939#else
1940        mViewCellsTree->Export(stream);
1941#endif
1942
1943        stream << "</ViewCells>" << endl;
1944
1945        //-- load the hierarchy
1946        stream << "<Hierarchy>" << endl;
1947        mBspTree->Export(stream);
1948        stream << endl << "</Hierarchy>" << endl;
1949
1950        stream << "</Visibility_Solution>" << endl;
1951        stream.close();
1952
1953        cout << "finished" << endl;
1954
1955        return true;
1956}
1957
1958
1959void BspViewCellsManager::AddCurrentViewCellsToHierarchy()
1960{
1961        ViewCellContainer::const_iterator it, it_end = mViewCells.end();
1962        for (it = mViewCells.begin(); it != it_end; ++ it)
1963        {
1964                ViewCell *vc = *it;
1965                ViewCellContainer leaves;
1966                mViewCellsTree->CollectLeaves(vc, leaves);
1967               
1968                ViewCellContainer::const_iterator lit, lit_end = leaves.end();
1969
1970                for (lit = leaves.begin(); lit != lit_end; ++ lit)
1971                {
1972                        BspViewCell *bspVc = dynamic_cast<BspViewCell *>(*lit);
1973                        bspVc->mLeaf->SetViewCell(vc);
1974                }
1975        }
1976}
1977
1978
1979ViewCell *BspViewCellsManager::ConstructSpatialMergeTree(BspNode *root)
1980{
1981        if (root->IsLeaf())
1982        {
1983                ViewCell *viewCell = dynamic_cast<BspLeaf *>(root)->GetViewCell();
1984
1985                viewCell->SetMergeCost(0.0f);
1986
1987                return viewCell;
1988        }
1989       
1990        BspInterior *interior = dynamic_cast<BspInterior *>(root);
1991        ViewCellInterior *viewCellInterior = new ViewCellInterior();
1992               
1993        float mergeCost = 1.0f / (float)root->mTimeStamp;
1994        //Debug << "timestamp: " << root->mTimeStamp;
1995        //Debug << "merge cost: " << mergeCost << endl;
1996
1997        viewCellInterior->SetMergeCost(mergeCost);
1998
1999        float volume = 0;
2000       
2001        BspNode *front = interior->GetFront();
2002        BspNode *back = interior->GetBack();
2003
2004        // recursivly compute child hierarchies
2005        ViewCell *backVc = ConstructSpatialMergeTree(back);
2006        ViewCell *frontVc = ConstructSpatialMergeTree(front);
2007
2008        viewCellInterior->SetupChildLink(frontVc);
2009        viewCellInterior->SetupChildLink(backVc);
2010
2011
2012        viewCellInterior->GetPvs().Merge(backVc->GetPvs());
2013        viewCellInterior->GetPvs().Merge(frontVc->GetPvs());
2014
2015        volume += backVc->GetVolume();
2016        volume += frontVc->GetVolume();
2017
2018        viewCellInterior->SetVolume(volume);
2019
2020        return viewCellInterior;
2021}
2022
2023
2024/************************************************************************/
2025/*                   KdViewCellsManager implementation                  */
2026/************************************************************************/
2027
2028
2029
2030KdViewCellsManager::KdViewCellsManager(KdTree *kdTree):
2031ViewCellsManager(), mKdTree(kdTree), mKdPvsDepth(100)
2032{
2033}
2034
2035
2036float KdViewCellsManager::GetProbability(ViewCell *viewCell)
2037{
2038        // compute view cell area / volume as subsititute for probability
2039        if (0)
2040                return GetArea(viewCell) / GetViewSpaceBox().SurfaceArea();
2041        else
2042                return GetVolume(viewCell) / GetViewSpaceBox().GetVolume();
2043}
2044
2045
2046
2047
2048void KdViewCellsManager::CollectViewCells()
2049{
2050        //mKdTree->CollectViewCells(mViewCells); TODO
2051}
2052
2053
2054int KdViewCellsManager::ConstructSubdivision(const ObjectContainer &objects,
2055                                                                  const VssRayContainer &rays)
2056{
2057        // if view cells already constructed
2058        if (ViewCellsConstructed())
2059                return 0;
2060
2061        mKdTree->Construct();
2062
2063        mTotalAreaValid = false;
2064        // create the view cells
2065        mKdTree->CreateAndCollectViewCells(mViewCells);
2066
2067        // cast rays
2068        ComputeSampleContributions(rays, true, false);
2069
2070        EvaluateViewCellsStats();
2071        Debug << "\nView cells after construction:\n" << mCurrentViewCellsStats << endl;
2072
2073        return 0;
2074}
2075
2076
2077bool KdViewCellsManager::ViewCellsConstructed() const
2078{
2079        return mKdTree->GetRoot() != NULL;
2080}
2081
2082int KdViewCellsManager::PostProcess(const ObjectContainer &objects,
2083                                                                        const VssRayContainer &rays)
2084{
2085        return 0;
2086}
2087
2088void KdViewCellsManager::Visualize(const ObjectContainer &objects,
2089                                                                   const VssRayContainer &sampleRays)
2090{
2091        if (!ViewCellsConstructed())
2092                return;
2093
2094        // using view cells instead of the kd PVS of objects
2095        const bool useViewCells = true;
2096        bool exportRays = false;
2097
2098        int limit = min(mVisualizationSamples, (int)sampleRays.size());
2099        const int pvsOut = min((int)objects.size(), 10);
2100        VssRayContainer *rays = new VssRayContainer[pvsOut];
2101
2102        if (useViewCells)
2103        {
2104                const int leafOut = 10;
2105
2106                ViewCell::NewMail();
2107
2108                //-- some rays for output
2109                const int raysOut = min((int)sampleRays.size(), mVisualizationSamples);
2110                Debug << "visualization using " << raysOut << " samples" << endl;
2111
2112                //-- some random view cells and rays for output
2113                vector<KdLeaf *> kdLeaves;
2114
2115                for (int i = 0; i < leafOut; ++ i)
2116                        kdLeaves.push_back(dynamic_cast<KdLeaf *>(mKdTree->GetRandomLeaf()));
2117
2118                for (int i = 0; i < kdLeaves.size(); ++ i)
2119                {
2120                        KdLeaf *leaf = kdLeaves[i];
2121                        RayContainer vcRays;
2122
2123                        cout << "creating output for view cell " << i << " ... ";
2124#if 0
2125                        // check whether we can add the current ray to the output rays
2126                        for (int k = 0; k < raysOut; ++ k)
2127                        {
2128                                Ray *ray = sampleRays[k];
2129
2130                                for (int j = 0; j < (int)ray->bspIntersections.size(); ++ j)
2131                                {
2132                                        BspLeaf *leaf2 = ray->bspIntersections[j].mLeaf;
2133
2134                                        if (leaf->GetViewCell() == leaf2->GetViewCell())
2135                                        {
2136                                                vcRays.push_back(ray);
2137                                        }
2138                                }
2139                        }
2140#endif
2141                        Intersectable::NewMail();
2142
2143                        ViewCell *vc = leaf->mViewCell;
2144
2145                        //bspLeaves[j]->Mail();
2146                        char s[64]; sprintf(s, "kd-pvs%04d.x3d", i);
2147
2148                        Exporter *exporter = Exporter::GetExporter(s);
2149                        exporter->SetFilled();
2150
2151                        exporter->SetWireframe();
2152                        //exporter->SetFilled();
2153
2154                        Material m;//= RandomMaterial();
2155                        m.mDiffuseColor = RgbColor(1, 1, 0);
2156                        exporter->SetForcedMaterial(m);
2157
2158                        AxisAlignedBox3 box = mKdTree->GetBox(leaf);
2159                        exporter->ExportBox(box);
2160
2161                        // export rays piercing this view cell
2162                        exporter->ExportRays(vcRays, 1000, RgbColor(0, 1, 0));
2163
2164                        m.mDiffuseColor = RgbColor(1, 0, 0);
2165                        exporter->SetForcedMaterial(m);
2166
2167                        // exporter->SetWireframe();
2168                        exporter->SetFilled();
2169
2170                        ObjectPvsMap::iterator it, it_end = vc->GetPvs().mEntries.end();
2171                        // output PVS of view cell
2172                        for (it = vc->GetPvs().mEntries.begin(); it !=  it_end; ++ it)
2173                        {
2174                                Intersectable *intersect = (*it).first;
2175                                if (!intersect->Mailed())
2176                                {
2177                                        exporter->ExportIntersectable(intersect);
2178                                        intersect->Mail();
2179                                }
2180                        }
2181
2182                        DEL_PTR(exporter);
2183                        cout << "finished" << endl;
2184                }
2185
2186                DEL_PTR(rays);
2187        }
2188        else // using kd PVS of objects
2189        {
2190                for (int i = 0; i < limit; ++ i)
2191                {
2192                        VssRay *ray = sampleRays[i];
2193
2194                        // check whether we can add this to the rays
2195                        for (int j = 0; j < pvsOut; j++)
2196                        {
2197                                if (objects[j] == ray->mTerminationObject)
2198                                {
2199                                        rays[j].push_back(ray);
2200                                }
2201                        }
2202                }
2203
2204                if (exportRays)
2205                {
2206                        Exporter *exporter = NULL;
2207                        exporter = Exporter::GetExporter("sample-rays.x3d");
2208                        exporter->SetWireframe();
2209                        exporter->ExportKdTree(*mKdTree);
2210
2211                        for (i=0; i < pvsOut; i++)
2212                                exporter->ExportRays(rays[i], RgbColor(1, 0, 0));
2213
2214                        exporter->SetFilled();
2215
2216                        delete exporter;
2217                }
2218
2219                for (int k=0; k < pvsOut; k++)
2220                {
2221                        Intersectable *object = objects[k];
2222                        char s[64];
2223                        sprintf(s, "sample-pvs%04d.x3d", k);
2224
2225                        Exporter *exporter = Exporter::GetExporter(s);
2226                        exporter->SetWireframe();
2227
2228                        KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
2229                        Intersectable::NewMail();
2230
2231                        // avoid adding the object to the list
2232                        object->Mail();
2233                        ObjectContainer visibleObjects;
2234
2235                        for (; i != object->mKdPvs.mEntries.end(); i++)
2236                        {
2237                                KdNode *node = (*i).first;
2238                                exporter->ExportBox(mKdTree->GetBox(node));
2239
2240                                mKdTree->CollectObjects(node, visibleObjects);
2241                        }
2242
2243                        exporter->ExportRays(rays[k],  RgbColor(0, 1, 0));
2244                        exporter->SetFilled();
2245
2246                        for (int j = 0; j < visibleObjects.size(); j++)
2247                                exporter->ExportIntersectable(visibleObjects[j]);
2248
2249                        Material m;
2250                        m.mDiffuseColor = RgbColor(1, 0, 0);
2251                        exporter->SetForcedMaterial(m);
2252                        exporter->ExportIntersectable(object);
2253
2254                        delete exporter;
2255                }
2256        }
2257}
2258
2259
2260void KdViewCellsManager::ExportColor(Exporter *exporter,
2261                                                                         ViewCell *vc) const
2262{
2263        // TODO
2264}
2265
2266
2267ViewCell *KdViewCellsManager::GenerateViewCell(Mesh *mesh) const
2268{
2269        return new KdViewCell(mesh);
2270}
2271
2272
2273void KdViewCellsManager::ExportViewCellGeometry(Exporter *exporter,
2274                                                                                                ViewCell *vc,
2275                                                                                                const Plane3 *clipPlane) const
2276{
2277        ViewCellContainer leaves;
2278
2279        mViewCellsTree->CollectLeaves(vc, leaves);
2280        ViewCellContainer::const_iterator it, it_end = leaves.end();
2281
2282        for (it = leaves.begin(); it != it_end; ++ it)
2283        {
2284                KdViewCell *kdVc = dynamic_cast<KdViewCell *>(*it);
2285       
2286                exporter->ExportBox(mKdTree->GetBox(kdVc->mLeaf));
2287        }
2288}
2289
2290
2291int KdViewCellsManager::GetType() const
2292{
2293        return ViewCellsManager::KD;
2294}
2295
2296
2297
2298KdNode *KdViewCellsManager::GetNodeForPvs(KdLeaf *leaf)
2299{
2300        KdNode *node = leaf;
2301
2302        while (node->mParent && node->mDepth > mKdPvsDepth)
2303                node = node->mParent;
2304        return node;
2305}
2306
2307int KdViewCellsManager::CastLineSegment(const Vector3 &origin,
2308                                                                                const Vector3 &termination,
2309                                                                                ViewCellContainer &viewcells)
2310{
2311        return mKdTree->CastLineSegment(origin, termination, viewcells);
2312}
2313
2314
2315void KdViewCellsManager::CreateMesh(ViewCell *vc)
2316{
2317        // TODO
2318}
2319
2320
2321
2322void KdViewCellsManager::CollectMergeCandidates(const VssRayContainer &rays,
2323                                                                                                vector<MergeCandidate> &candidates)
2324{
2325        // TODO
2326}
2327
2328
2329/**********************************************************************/
2330/*                   VspKdViewCellsManager implementation             */
2331/**********************************************************************/
2332
2333
2334VspKdViewCellsManager::VspKdViewCellsManager(VspKdTree *vspKdTree):
2335ViewCellsManager(), mVspKdTree(vspKdTree)
2336{
2337        environment->GetIntValue("VspKdTree.Construction.samples", mInitialSamples);
2338        mVspKdTree->SetViewCellsManager(this);
2339}
2340
2341float VspKdViewCellsManager::GetProbability(ViewCell *viewCell)
2342{
2343        // compute view cell area / volume as subsititute for probability
2344        if (0)
2345                return GetArea(viewCell) / GetViewSpaceBox().SurfaceArea();
2346        else
2347                return GetVolume(viewCell) / GetViewSpaceBox().GetVolume();
2348}
2349
2350
2351
2352
2353void VspKdViewCellsManager::CollectViewCells()
2354{
2355        mVspKdTree->CollectViewCells(mViewCells);
2356}
2357
2358
2359int VspKdViewCellsManager::ConstructSubdivision(const ObjectContainer &objects,
2360                                                                                                const VssRayContainer &rays)
2361{
2362        // if view cells already constructed
2363        if (ViewCellsConstructed())
2364                return 0;
2365
2366        VssRayContainer constructionRays;
2367        VssRayContainer savedRays;
2368
2369        GetRaySets(rays,
2370                           mInitialSamples,
2371                           constructionRays,
2372                           &savedRays);
2373
2374        Debug << "constructing vsp kd tree using "
2375                  << (int)constructionRays.size() << " samples" << endl;
2376
2377        mVspKdTree->Construct(constructionRays, &mViewSpaceBox);
2378        Debug << mVspKdTree->GetStatistics() << endl;
2379
2380        // export leaf building blocks
2381        ExportLeaves(objects, rays);
2382
2383        // finally merge kd leaf building blocks to view cells
2384        const int merged = mVspKdTree->MergeViewCells(rays);
2385
2386        // collapse siblings belonging to the same view cell
2387        mVspKdTree->RefineViewCells(rays);
2388
2389        // collapse siblings belonging to the same view cell
2390        mVspKdTree->CollapseTree();
2391
2392        // evaluale view cell stats
2393        ResetViewCells();
2394
2395        Debug << "\nView cells after construction:\n" << mCurrentViewCellsStats << endl;
2396
2397        long startTime = GetTime();
2398
2399        // recast rest of rays
2400        ComputeSampleContributions(savedRays, true, false);
2401
2402        Debug << "Computed remaining ray contribution in " << TimeDiff(startTime, GetTime()) * 1e-3
2403                  << " secs" << endl;
2404
2405        return merged;
2406}
2407
2408bool VspKdViewCellsManager::ViewCellsConstructed() const
2409{
2410        return mVspKdTree->GetRoot() != NULL;
2411}
2412
2413
2414ViewCell *VspKdViewCellsManager::GenerateViewCell(Mesh *mesh) const
2415{
2416        return new VspKdViewCell(mesh);
2417}
2418
2419int VspKdViewCellsManager::PostProcess(const ObjectContainer &objects,
2420                                                                           const VssRayContainer &rays)
2421{
2422        if (!ViewCellsConstructed())
2423                return 0;
2424
2425        // recalculate stats
2426        EvaluateViewCellsStats();
2427
2428        return 0;
2429}
2430
2431
2432void VspKdViewCellsManager::ExportLeaves(const ObjectContainer &objects,
2433                                                                                 const VssRayContainer &sampleRays)
2434{
2435        if (!ViewCellsConstructed())
2436                return;
2437
2438        //-- export leaf building blocks
2439        Exporter *exporter = Exporter::GetExporter("vspkdtree.x3d");
2440        if (!exporter)
2441                return;
2442
2443        if (mExportGeometry)
2444                exporter->ExportGeometry(objects);
2445       
2446        //exporter->SetWireframe();
2447        //exporter->ExportVspKdTree(*mVspKdTree, mVspKdTree->GetStatistics().maxPvsSize);
2448        exporter->ExportVspKdTree(*mVspKdTree);
2449
2450        if (mExportRays)
2451        {
2452                const float prob = (float)mVisualizationSamples
2453                        / ((float)sampleRays.size() + Limits::Small);
2454
2455                exporter->SetWireframe();
2456
2457                //-- collect uniformly distributed rays
2458                VssRayContainer rays;
2459
2460                for (int i = 0; i < sampleRays.size(); ++ i)
2461                {
2462                        if (RandomValue(0,1) < prob)
2463                                rays.push_back(sampleRays[i]);
2464                }
2465                exporter->ExportRays(rays, RgbColor(1, 0, 0));
2466        }
2467
2468        delete exporter;
2469}
2470
2471void VspKdViewCellsManager::Visualize(const ObjectContainer &objects,
2472                                                                          const VssRayContainer &sampleRays)
2473{
2474        if (!ViewCellsConstructed())
2475                return;
2476
2477        //-- export single view cells
2478        for (int i = 0; i < 10; ++ i)
2479        {
2480                char s[64];
2481                sprintf(s, "vsp_viewcell%04d.x3d", i);
2482                Exporter *exporter = Exporter::GetExporter(s);
2483                const int idx =
2484                        (int)RandomValue(0.0, (Real)((int)mViewCells.size() - 1));
2485
2486                VspKdViewCell *vc = dynamic_cast<VspKdViewCell *>(mViewCells[idx]);
2487
2488                //-- export geometry
2489                Material m;
2490                m.mDiffuseColor = RgbColor(0, 1, 1);
2491
2492                exporter->SetForcedMaterial(m);
2493                exporter->SetWireframe();
2494
2495                ExportViewCellGeometry(exporter, vc);
2496
2497                //-- export stored rays
2498               
2499                if (mExportRays)
2500                {
2501                        ViewCellContainer leaves;
2502                        mViewCellsTree->CollectLeaves(vc, leaves);
2503
2504                        ViewCellContainer::const_iterator it,
2505                                it_end = leaves.end();
2506
2507                        for (it = leaves.begin(); it != it_end; ++ it)
2508                        {
2509                                VspKdViewCell *vspKdVc = dynamic_cast<VspKdViewCell *>(*it);
2510                                VspKdLeaf *leaf = vspKdVc->mLeaf;
2511                                AxisAlignedBox3 box = mVspKdTree->GetBBox(leaf);
2512
2513                                VssRayContainer vssRays;
2514
2515                                VssRayContainer castRays;
2516                                VssRayContainer initRays;
2517
2518                                leaf->GetRays(vssRays);
2519
2520                                VssRayContainer::const_iterator it, it_end = vssRays.end();
2521                                const float prop = 200.0f / (float)vssRays.size();
2522
2523                                for (it = vssRays.begin(); it != it_end; ++ it)
2524                                {
2525                                        if (Random(1) < prop)
2526                                                if ((*it)->mTerminationObject == NULL)
2527                                                        castRays.push_back(*it);
2528                                                else
2529                                                        initRays.push_back(*it);
2530                                }
2531
2532                                exporter->ExportRays(castRays, RgbColor(1, 0, 0));
2533                                exporter->ExportRays(initRays, RgbColor(0, 1, 0));
2534                        }
2535                }
2536       
2537                //-- output PVS of view cell
2538                m.mDiffuseColor = RgbColor(1, 0, 0);
2539                exporter->SetForcedMaterial(m);
2540
2541                Intersectable::NewMail();
2542
2543                ObjectPvsMap::const_iterator it,
2544                        it_end = vc->GetPvs().mEntries.end();
2545
2546                exporter->SetFilled();
2547
2548                for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it)
2549                {
2550                        Intersectable *intersect = (*it).first;
2551
2552                        if (!intersect->Mailed())
2553                        {
2554                                Material m = RandomMaterial();
2555                                exporter->SetForcedMaterial(m);
2556
2557                                exporter->ExportIntersectable(intersect);
2558                                intersect->Mail();
2559                        }
2560                }
2561
2562                delete exporter;
2563        }
2564
2565        //-- export final view cells
2566        Exporter *exporter = Exporter::GetExporter("vspkdtree_merged.x3d");
2567
2568        //if (exportGeometry) exporter->SetWireframe();
2569        //else exporter->SetFilled();
2570
2571        ExportViewCellsForViz(exporter);
2572
2573        if (mExportGeometry)
2574        {
2575                exporter->SetFilled();
2576                exporter->ExportGeometry(objects);
2577        }
2578
2579        if (mExportRays)
2580        {
2581                const float prob = (float)mVisualizationSamples
2582                        / ((float)sampleRays.size() + Limits::Small);
2583
2584                exporter->SetWireframe();
2585
2586                VssRayContainer rays;
2587
2588                for (int i = 0; i < sampleRays.size(); ++ i)
2589                {
2590                  if (RandomValue(0,1) < prob)
2591                        rays.push_back(sampleRays[i]);
2592                }
2593                exporter->ExportRays(rays, RgbColor(1, 0, 0));
2594        }
2595
2596        delete exporter;
2597}
2598
2599int VspKdViewCellsManager::GetType() const
2600{
2601        return VSP_KD;
2602}
2603
2604
2605int VspKdViewCellsManager::CastLineSegment(const Vector3 &origin,
2606                                                                                   const Vector3 &termination,
2607                                                                                   ViewCellContainer &viewcells)
2608{
2609        return mVspKdTree->CastLineSegment(origin, termination, viewcells);
2610}
2611
2612
2613void VspKdViewCellsManager::ExportColor(Exporter *exporter,
2614                                                                                ViewCell *vc) const
2615{
2616        if (mColorCode == 0) // Random color
2617                return;
2618
2619        float importance = 0;
2620
2621        switch (mColorCode)
2622        {
2623        case 1: // pvs
2624                {
2625                        importance = (float)vc->GetPvs().GetSize() /
2626                                (float)mCurrentViewCellsStats.maxPvs;
2627                }
2628                break;
2629        case 2: // merged leaves
2630                {
2631                int lSize = mViewCellsTree->GetSize(vc);
2632                        importance = (float)lSize /
2633                                (float)mCurrentViewCellsStats.maxLeaves;
2634                }
2635                break;
2636        case 3: // merged tree depth difference
2637                {
2638                        //importance = (float)GetMaxTreeDiff(vc) /
2639                        //      (float)(mVspBspTree->GetStatistics().maxDepth * 2);
2640                }
2641                break;
2642        default:
2643                break;
2644        }
2645
2646        Material m;
2647        m.mDiffuseColor.b = 1.0f;
2648        m.mDiffuseColor.r = importance;
2649        m.mDiffuseColor.g = 1.0f - m.mDiffuseColor.r;
2650        //Debug << "importance: " << importance << endl;
2651        exporter->SetForcedMaterial(m);
2652}
2653
2654
2655void VspKdViewCellsManager::ExportViewCellGeometry(Exporter *exporter,
2656                                                                                                   ViewCell *vc,
2657                                                                                                   const Plane3 *clipPlane) const
2658{
2659        VspKdViewCell *kdVc = dynamic_cast<VspKdViewCell *>(vc);
2660
2661        Mesh m;
2662
2663        ViewCellContainer leaves;
2664        mViewCellsTree->CollectLeaves(vc, leaves);
2665
2666        ViewCellContainer::const_iterator it, it_end = leaves.end();
2667
2668        for (it = leaves.begin(); it != it_end; ++ it)
2669        {
2670                VspKdLeaf *l = dynamic_cast<VspKdViewCell *>(*it)->mLeaf;
2671                mVspKdTree->GetBBox(l).AddBoxToMesh(&m);
2672        }
2673
2674        exporter->ExportMesh(&m);
2675}
2676
2677
2678void VspKdViewCellsManager::CreateMesh(ViewCell *vc)
2679{
2680        //TODO
2681}
2682
2683
2684void VspKdViewCellsManager::CollectMergeCandidates(const VssRayContainer &rays,
2685                                                                                                   vector<MergeCandidate> &candidates)
2686{
2687        // TODO
2688}
2689
2690
2691/**************************************************************************/
2692/*                   VspBspViewCellsManager implementation                */
2693/**************************************************************************/
2694
2695
2696VspBspViewCellsManager::VspBspViewCellsManager(VspBspTree *vspBspTree):
2697ViewCellsManager(), mVspBspTree(vspBspTree)
2698{
2699        environment->GetIntValue("VspBspTree.Construction.samples", mInitialSamples);
2700        mVspBspTree->SetViewCellsManager(this);
2701        mVspBspTree->mViewCellsTree = mViewCellsTree;
2702}
2703
2704
2705VspBspViewCellsManager::~VspBspViewCellsManager()
2706{
2707}
2708
2709
2710float VspBspViewCellsManager::GetProbability(ViewCell *viewCell)
2711{
2712        if (0 && mVspBspTree->mUseAreaForPvs)
2713                return GetArea(viewCell) / GetAccVcArea();
2714        else
2715                return GetVolume(viewCell) / mViewSpaceBox.GetVolume();
2716}
2717
2718
2719void VspBspViewCellsManager::CollectViewCells()
2720{
2721        // view cells tree constructed
2722        if (!ViewCellsTreeConstructed())
2723        {
2724                mVspBspTree->CollectViewCells(mViewCells, false);
2725        }
2726        else
2727        {       // we can use the view cells tree hierarchy to get the right set
2728                mViewCellsTree->CollectBestViewCellSet(mViewCells, mNumActiveViewCells);
2729        }
2730
2731}
2732
2733
2734
2735bool VspBspViewCellsManager::ViewCellsConstructed() const
2736{
2737        return mVspBspTree->GetRoot() != NULL;
2738}
2739
2740
2741ViewCell *VspBspViewCellsManager::GenerateViewCell(Mesh *mesh) const
2742{
2743        return new BspViewCell(mesh);
2744}
2745
2746
2747int VspBspViewCellsManager::ConstructSubdivision(const ObjectContainer &objects,
2748                                                                                                 const VssRayContainer &rays)
2749{
2750        // if view cells were already constructed
2751        if (ViewCellsConstructed())
2752                return 0;
2753
2754        int sampleContributions = 0;
2755
2756        VssRayContainer sampleRays;
2757
2758        int limit = min (mInitialSamples, (int)rays.size());
2759
2760        VssRayContainer constructionRays;
2761        VssRayContainer savedRays;
2762
2763        Debug << "samples used for vsp bsp subdivision: " << mInitialSamples
2764                  << ", actual rays: " << (int)rays.size() << endl;
2765
2766        GetRaySets(rays, mInitialSamples, constructionRays, &savedRays);
2767
2768        Debug << "initial rays: " << (int)constructionRays.size() << endl;
2769        Debug << "saved rays: " << (int)savedRays.size() << endl;
2770
2771        mMaxPvsSize = (int)(mMaxPvsRatio * (float)objects.size());
2772
2773        //TODO: remove
2774        if (1)
2775                mVspBspTree->Construct(constructionRays, &mViewSpaceBox);
2776        else
2777                mVspBspTree->Construct(rays, &mViewSpaceBox);
2778
2779        // collapse invalid regions
2780        cout << "collapsing invalid tree regions ... ";
2781        long startTime = GetTime();
2782        int collapsedLeaves = mVspBspTree->CollapseTree();
2783        Debug << "collapsed in " << TimeDiff(startTime, GetTime()) * 1e-3
2784                  << " seconds" << endl;
2785
2786    cout << "finished" << endl;
2787
2788        // -- stats
2789        Debug << mVspBspTree->GetStatistics() << endl;
2790
2791        ResetViewCells();
2792        Debug << "\nView cells after construction:\n" << mCurrentViewCellsStats << endl;
2793
2794
2795        startTime = GetTime();
2796
2797        cout << "Computing remaining ray contributions ... ";
2798
2799        // recast rest of rays
2800        if (SAMPLE_AFTER_SUBDIVISION)
2801                ComputeSampleContributions(savedRays, true, false);
2802        cout << "finished" << endl;
2803
2804        Debug << "Computed remaining ray contribution in " << TimeDiff(startTime, GetTime()) * 1e-3
2805                  << " secs" << endl;
2806
2807        cout << "construction finished" << endl;
2808
2809        return sampleContributions;
2810}
2811
2812
2813void VspBspViewCellsManager::MergeViewCells(const VssRayContainer &rays,
2814                                                                                        const ObjectContainer &objects)
2815{
2816        //-- post processing of bsp view cells
2817    int vcSize = 0;
2818        int pvsSize = 0;
2819
2820        //-- merge view cells
2821       
2822        cout << "starting merge using " << mPostProcessSamples << " samples ... " << endl;
2823        long startTime = GetTime();
2824
2825
2826        if (mMergeViewCells)
2827        {
2828                // TODO: should be done BEFORE the ray casting
2829                mViewCellsTree->ConstructMergeTree(rays, objects);
2830        }
2831        else
2832        {
2833                mViewCellsTree->SetRoot(ConstructSpatialMergeTree(mVspBspTree->GetRoot()));
2834        }
2835
2836        if (1)
2837        {
2838                char mstats[100];
2839                environment->GetStringValue("ViewCells.mergeStats", mstats);
2840                mViewCellsTree->ExportStats(mstats);
2841        }
2842
2843        //-- stats and visualizations
2844        cout << "finished merging" << endl;
2845        cout << "merged view cells in "
2846                 << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl;
2847
2848        Debug << "Postprocessing: Merged view cells in "
2849                  << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl << endl;
2850       
2851
2852        int savedColorCode = mColorCode;
2853       
2854        // get currently active view cell set
2855        ResetViewCells();
2856        Debug << "\nView cells after merge:\n" << mCurrentViewCellsStats << endl;
2857
2858        //BspLeaf::NewMail();
2859        if (1) // export merged view cells
2860        {
2861                mColorCode = 0;
2862                Exporter *exporter = Exporter::GetExporter("merged_view_cells.x3d");
2863               
2864                cout << "exporting view cells after merge ... ";
2865
2866                if (exporter)
2867                {
2868                        if (0)
2869                                exporter->SetWireframe();
2870                        else
2871                                exporter->SetFilled();
2872
2873                        ExportViewCellsForViz(exporter);
2874
2875                        if (mExportGeometry)
2876                        {
2877                                Material m;
2878                                m.mDiffuseColor = RgbColor(0, 1, 0);
2879                                exporter->SetForcedMaterial(m);
2880                                exporter->SetFilled();
2881
2882                                exporter->ExportGeometry(objects);
2883                        }
2884
2885                        delete exporter;
2886                }
2887                cout << "finished" << endl;
2888        }
2889
2890        if (1) // export merged view cells using pvs coding
2891        {
2892                mColorCode = 1;
2893
2894                Exporter *exporter = Exporter::GetExporter("merged_view_cells_pvs.x3d");
2895       
2896                cout << "exporting view cells after merge (pvs size) ... ";     
2897
2898                if (exporter)
2899                {
2900                        if (0)
2901                                exporter->SetWireframe();
2902                        else
2903                                exporter->SetFilled();
2904
2905                        ExportViewCellsForViz(exporter);
2906
2907                        if (mExportGeometry)
2908                        {
2909                                Material m;
2910                                m.mDiffuseColor = RgbColor(0, 1, 0);
2911                                exporter->SetForcedMaterial(m);
2912                                exporter->SetFilled();
2913
2914                                exporter->ExportGeometry(objects);
2915                        }
2916
2917                        delete exporter;
2918                }
2919                cout << "finished" << endl;
2920        }
2921
2922        mColorCode = savedColorCode;
2923
2924}
2925
2926
2927bool VspBspViewCellsManager::EqualToSpatialNode(ViewCell *viewCell) const
2928{
2929        return GetSpatialNode(viewCell) != NULL;
2930}
2931
2932
2933BspNode *VspBspViewCellsManager::GetSpatialNode(ViewCell *viewCell) const
2934{
2935        if (!viewCell->IsLeaf())
2936        {
2937                BspViewCell *bspVc = dynamic_cast<BspViewCell *>(viewCell);
2938
2939                return bspVc->mLeaf;
2940        }
2941        else
2942        {
2943                ViewCellInterior *interior = dynamic_cast<ViewCellInterior *>(viewCell);
2944
2945                // cannot be node of binary tree
2946                if (interior->mChildren.size() != 2)
2947                        return NULL;
2948
2949                ViewCell *left = interior->mChildren[0];
2950                ViewCell *right = interior->mChildren[1];
2951
2952                BspNode *leftNode = GetSpatialNode(left);
2953                BspNode *rightNode = GetSpatialNode(right);
2954
2955                if (leftNode && rightNode && leftNode->IsSibling(rightNode))
2956                {
2957                        return leftNode->GetParent();
2958                }
2959        }
2960
2961        return NULL;
2962}
2963
2964
2965void VspBspViewCellsManager::RefineViewCells(const VssRayContainer &rays,
2966                                                                                         const ObjectContainer &objects)
2967{
2968        Debug << "render time before refine:" << endl;
2969        mRenderer->RenderScene();
2970        SimulationStatistics ss;
2971        dynamic_cast<RenderSimulator *>(mRenderer)->GetStatistics(ss);
2972    Debug << ss << endl;
2973
2974        cout << "Refining the merged view cells ... ";
2975        long startTime = GetTime();
2976
2977        // refining the merged view cells
2978        const int refined = mViewCellsTree->RefineViewCells(rays, objects);
2979
2980        //-- stats and visualizations
2981        cout << "finished" << endl;
2982        cout << "refined " << refined << " view cells in "
2983                 << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl;
2984
2985        Debug << "Postprocessing: refined " << refined << " view cells in "
2986                  << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl << endl;
2987}
2988
2989
2990int VspBspViewCellsManager::PostProcess(const ObjectContainer &objects,
2991                                                                                const VssRayContainer &rays)
2992{
2993        if (!ViewCellsConstructed())
2994        {
2995                Debug << "postprocess error: no view cells constructed" << endl;
2996                return 0;
2997        }
2998
2999
3000        // view cells already finished before post processing step
3001        // (i.e. because they were loaded)
3002        if (mViewCellsFinished)
3003        {
3004                FinalizeViewCells(true);
3005                EvaluateViewCellsStats();
3006
3007                return 0;
3008        }
3009
3010
3011        // check if new view cells turned invalid
3012        SetValidity(mMinPvsSize, mMaxPvsSize);
3013        // update valid view space according to valid view cells
3014        mVspBspTree->ValidateTree();
3015
3016        // has to be recomputed
3017        mTotalAreaValid = false;
3018        VssRayContainer postProcessRays;
3019        GetRaySets(rays, mPostProcessSamples, postProcessRays);
3020
3021        Debug << "post processing using " << (int)postProcessRays.size() << " samples" << endl;
3022
3023
3024        // should maybe be done here to allow merge working with area or volume
3025        // and to correct the rendering statistics
3026        if (0)
3027        {
3028                FinalizeViewCells(false);
3029        }
3030
3031        //-- merge the individual view cells
3032        MergeViewCells(postProcessRays, objects);
3033       
3034
3035        Debug << "here4" << endl;
3036        // only for testing
3037        TestSubdivision();
3038
3039        //-- refines the merged view cells
3040        if (0)
3041                RefineViewCells(postProcessRays, objects);
3042
3043
3044        //-- render simulation after merge + refine
3045       
3046        cout << "\nevaluating bsp view cells render time before compress ... ";
3047        dynamic_cast<RenderSimulator *>(mRenderer)->RenderScene();
3048        SimulationStatistics ss;
3049        dynamic_cast<RenderSimulator *>(mRenderer)->GetStatistics(ss);
3050 
3051
3052        cout << " finished" << endl;
3053        cout << ss << endl;
3054        Debug << ss << endl;
3055
3056
3057        //-- compression
3058
3059        if (ViewCellsTreeConstructed() && mCompressViewCells)
3060        {
3061                int pvsEntries = mViewCellsTree->GetNumPvsEntries(mViewCellsTree->GetRoot());
3062                Debug << "number of entries before compress: " << pvsEntries << endl;
3063
3064                mViewCellsTree->CompressViewCellsPvs();
3065
3066                pvsEntries = mViewCellsTree->GetNumPvsEntries(mViewCellsTree->GetRoot());
3067                Debug << "number of entries after compress: " << pvsEntries << endl;
3068        }
3069
3070
3071        // collapse sibling leaves that share the same view cell
3072        if (0)
3073                mVspBspTree->CollapseTree();
3074
3075        // recompute view cell list and statistics
3076        ResetViewCells();
3077
3078        // real meshes are only contructed only at this stage
3079        FinalizeViewCells(true);
3080
3081        // write view cells to disc
3082        if (mExportViewCells)
3083        {
3084                char buff[100];
3085                environment->GetStringValue("ViewCells.filename", buff);
3086                string vcFilename(buff);
3087
3088                ExportViewCells(buff);
3089        }
3090
3091        return 0;
3092}
3093
3094
3095int VspBspViewCellsManager::GetType() const
3096{
3097        return VSP_BSP;
3098}
3099
3100
3101ViewCell *VspBspViewCellsManager::ConstructSpatialMergeTree(BspNode *root)
3102{
3103        if (root->IsLeaf())
3104        {
3105                ViewCell *viewCell = dynamic_cast<BspLeaf *>(root)->GetViewCell();
3106
3107                viewCell->SetMergeCost(0.0f);
3108
3109                return viewCell;
3110        }
3111       
3112        BspInterior *interior = dynamic_cast<BspInterior *>(root);
3113        ViewCellInterior *viewCellInterior = new ViewCellInterior();
3114               
3115        float mergeCost = 1.0f / (float)root->mTimeStamp;
3116        //Debug << "timestamp: " << root->mTimeStamp;
3117        //Debug << "merge cost: " << mergeCost << endl;
3118
3119        viewCellInterior->SetMergeCost(mergeCost);
3120
3121        float volume = 0;
3122       
3123        BspNode *front = interior->GetFront();
3124        BspNode *back = interior->GetBack();
3125
3126        // recursivly compute child hierarchies
3127        ViewCell *backVc = ConstructSpatialMergeTree(back);
3128        ViewCell *frontVc = ConstructSpatialMergeTree(front);
3129
3130        viewCellInterior->SetupChildLink(frontVc);
3131        viewCellInterior->SetupChildLink(backVc);
3132
3133
3134        viewCellInterior->GetPvs().Merge(backVc->GetPvs());
3135        viewCellInterior->GetPvs().Merge(frontVc->GetPvs());
3136
3137        volume += backVc->GetVolume();
3138        volume += frontVc->GetVolume();
3139
3140        viewCellInterior->SetVolume(volume);
3141
3142        return viewCellInterior;
3143}
3144
3145
3146bool VspBspViewCellsManager::GetViewPoint(Vector3 &viewPoint) const
3147{
3148        if (!ViewCellsConstructed())
3149                return ViewCellsManager::GetViewPoint(viewPoint);
3150
3151        // TODO: set reasonable limit
3152        const int limit = 20;
3153
3154        for (int i = 0; i < limit; ++ i)
3155        {
3156                viewPoint = mViewSpaceBox.GetRandomPoint();
3157                if (mVspBspTree->ViewPointValid(viewPoint))
3158                {
3159                        return true;
3160                }
3161        }
3162        Debug << "failed to find valid view point, taking " << viewPoint << endl;
3163        return false;
3164}
3165
3166
3167bool VspBspViewCellsManager::ViewPointValid(const Vector3 &viewPoint) const
3168{
3169  // $$JB -> implemented in viewcellsmanager (slower, but allows dynamic
3170  // validy update in preprocessor for all managers)
3171  return ViewCellsManager::ViewPointValid(viewPoint);
3172
3173  //    return mViewSpaceBox.IsInside(viewPoint) &&
3174  //               mVspBspTree->ViewPointValid(viewPoint);
3175}
3176
3177
3178void VspBspViewCellsManager::Visualize(const ObjectContainer &objects,
3179                                                                           const VssRayContainer &sampleRays)
3180{
3181        if (!ViewCellsConstructed())
3182                return;
3183
3184        VssRayContainer visRays;
3185        GetRaySets(sampleRays, mVisualizationSamples, visRays);
3186
3187       
3188        if (1) // export view cells
3189        {       // hack pvs
3190                int savedColorCode = mColorCode;
3191                mColorCode = 0;
3192                Exporter *exporter = Exporter::GetExporter("final_view_cells.x3d");
3193               
3194                if (exporter)
3195                {
3196                        cout << "exporting view cells after post process ... ";
3197
3198                        if (0)
3199                        {
3200                                exporter->SetWireframe();
3201                                exporter->ExportBox(mViewSpaceBox);
3202                                exporter->SetFilled();
3203                        }
3204
3205                        if (mExportGeometry)
3206                        {
3207                                exporter->ExportGeometry(objects);
3208                        }
3209
3210                        // export rays
3211                        if (mExportRays)
3212                        {
3213                                exporter->ExportRays(visRays, RgbColor(0, 1, 0));
3214                        }
3215
3216                        ExportViewCellsForViz(exporter);
3217                        delete exporter;
3218                        cout << "finished" << endl;
3219                }
3220
3221                mColorCode = savedColorCode;
3222        }
3223
3224        if (0)
3225        {
3226                cout << "exporting depth map ... ";
3227
3228                Exporter *exporter = Exporter::GetExporter("depth_map.x3d");
3229                if (exporter)
3230                {
3231                        if (1)
3232                        {
3233                                exporter->SetWireframe();
3234                                exporter->ExportBox(mViewSpaceBox);
3235                                exporter->SetFilled();
3236                        }
3237
3238                        if (mExportGeometry)
3239                        {
3240                                exporter->ExportGeometry(objects);
3241                        }
3242
3243                        const int maxDepth = mVspBspTree->mBspStats.maxDepth;
3244
3245                        ViewCellContainer::const_iterator vit, vit_end = mViewCells.end();
3246
3247                        for (vit = mViewCells.begin(); vit != mViewCells.end(); ++ vit)
3248                        {
3249                                ViewCell *vc = *vit;
3250
3251                                ViewCellContainer leaves;
3252                                mViewCellsTree->CollectLeaves(vc, leaves);
3253
3254                                ViewCellContainer::const_iterator lit, lit_end = leaves.end();
3255
3256                                for (lit = leaves.begin(); lit != lit_end; ++ lit)
3257                                {
3258                                        BspLeaf *leaf = dynamic_cast<BspViewCell *>(*lit)->mLeaf;
3259
3260                                        Material m;
3261
3262                                        float relDepth = (float)leaf->GetDepth() / (float)maxDepth;
3263                                        m.mDiffuseColor.r = relDepth;
3264                                        m.mDiffuseColor.g = 0.0f;
3265                                        m.mDiffuseColor.b = 1.0f - relDepth;
3266
3267                    exporter->SetForcedMaterial(m);
3268                               
3269
3270                                        BspNodeGeometry geom;
3271                                        mVspBspTree->ConstructGeometry(leaf, geom);
3272                                        exporter->ExportPolygons(geom.GetPolys());
3273                                }
3274                        }
3275
3276                        delete exporter;
3277                }
3278
3279
3280                cout << "finished" << endl;
3281        }
3282
3283        //-- visualization of the BSP splits
3284        bool exportSplits = false;
3285        environment->GetBoolValue("VspBspTree.Visualization.exportSplits", exportSplits);
3286
3287        if (exportSplits)
3288        {
3289                cout << "exporting splits ... ";
3290                ExportSplits(objects, visRays);
3291                cout << "finished" << endl;
3292        }
3293
3294        //-- export single view cells
3295        ExportBspPvs(objects, visRays);
3296}
3297
3298
3299void VspBspViewCellsManager::ExportSplits(const ObjectContainer &objects,
3300                                                                                  const VssRayContainer &rays)
3301{
3302        Exporter *exporter = Exporter::GetExporter("bsp_splits.x3d");
3303
3304        if (exporter)
3305        {
3306                Material m;
3307                m.mDiffuseColor = RgbColor(1, 0, 0);
3308                exporter->SetForcedMaterial(m);
3309                exporter->SetWireframe();
3310
3311                exporter->ExportBspSplits(*mVspBspTree, true);
3312
3313                // take forced material, else big scenes cannot be viewed
3314                m.mDiffuseColor = RgbColor(0, 1, 0);
3315                exporter->SetForcedMaterial(m);
3316                exporter->SetFilled();
3317
3318                exporter->ResetForcedMaterial();
3319
3320                // export rays
3321                if (mExportRays)
3322                        exporter->ExportRays(rays, RgbColor(1, 1, 0));
3323
3324                if (mExportGeometry)
3325                        exporter->ExportGeometry(objects);
3326
3327                delete exporter;
3328        }
3329}
3330
3331
3332void VspBspViewCellsManager::ExportBspPvs(const ObjectContainer &objects,
3333                                                                                  const VssRayContainer &rays)
3334{
3335        const int leafOut = 20;
3336
3337        ViewCell::NewMail();
3338
3339        cout << "visualization using " << (int)rays.size() << " samples" << endl;
3340        Debug << "visualization using " << (int)rays.size() << " samples" << endl;
3341        Debug << "\nOutput view cells: " << endl;
3342
3343        // sort view cells to visualize the largest view cells
3344        if (0)
3345                stable_sort(mViewCells.begin(), mViewCells.end(), vc_gt);
3346       
3347        int limit = min(leafOut, (int)mViewCells.size());
3348
3349        int raysOut = 0;
3350
3351        //-- some rays for output
3352        for (int i = 0; i < limit; ++ i)
3353        {
3354                cout << "creating output for view cell " << i << " ... ";
3355
3356       
3357                ViewCell *vc;
3358       
3359                if (0) // largest view cell pvs first
3360                        vc = mViewCells[i];
3361                else
3362                        vc = mViewCells[(int)RandomValue(0, (float)mViewCells.size() - 1)];
3363
3364                //bspLeaves[j]->Mail();
3365                char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i);
3366                Exporter *exporter = Exporter::GetExporter(s);
3367               
3368                Debug << i << ": pvs size=" << (int)mViewCellsTree->GetPvsSize(vc) << endl;
3369
3370                if (1 || mExportRays)
3371                {
3372                        if (0)
3373                        {
3374                                VssRayContainer vcRays;
3375                VssRayContainer collectRays;
3376
3377                                raysOut = min((int)rays.size(), 100);
3378
3379                                // collect intial view cells
3380                                ViewCellContainer leaves;
3381                                mViewCellsTree->CollectLeaves(vc, leaves);
3382
3383                                ViewCellContainer::const_iterator vit, vit_end = leaves.end();
3384       
3385                                for (vit = leaves.begin(); vit != vit_end; ++ vit)
3386                                {
3387                                        BspLeaf *vcLeaf = dynamic_cast<BspViewCell *>(*vit)->mLeaf;
3388                               
3389                                        VssRayContainer::const_iterator rit, rit_end = vcLeaf->mVssRays.end();
3390
3391                                        for (rit = vcLeaf->mVssRays.begin(); rit != rit_end; ++ rit)
3392                                        {
3393                                                collectRays.push_back(*rit);
3394                                        }
3395                                }
3396
3397                                VssRayContainer::const_iterator rit, rit_end = collectRays.end();
3398
3399                                for (rit = collectRays.begin(); rit != rit_end; ++ rit)
3400                                {
3401                                        float p = RandomValue(0.0f, (float)collectRays.size());
3402                       
3403                                        if (p < raysOut)
3404                                                vcRays.push_back(*rit);
3405                                }
3406                                //-- export rays piercing this view cell
3407                                exporter->ExportRays(vcRays, RgbColor(1, 1, 1));
3408                        }
3409               
3410
3411                        if (1)
3412                        {
3413                                VssRayContainer vcRays;
3414                                raysOut = min((int)rays.size(), mVisualizationSamples);
3415                                // check whether we can add the current ray to the output rays
3416                                for (int k = 0; k < raysOut; ++ k)
3417                                {
3418                                        VssRay *ray = rays[k];
3419                                        for     (int j = 0; j < (int)ray->mViewCells.size(); ++ j)
3420                                        {
3421                                                ViewCell *rayvc = ray->mViewCells[j];
3422       
3423                                                if (rayvc == vc)
3424                                                        vcRays.push_back(ray);
3425                                        }
3426                                }       
3427                               
3428                                //-- export rays piercing this view cell
3429                                exporter->ExportRays(vcRays, RgbColor(1, 1, 0));
3430                        }
3431
3432                }
3433               
3434
3435                exporter->SetWireframe();
3436
3437                Material m;//= RandomMaterial();
3438                m.mDiffuseColor = RgbColor(0, 1, 0);
3439                exporter->SetForcedMaterial(m);
3440
3441                ExportViewCellGeometry(exporter, vc);
3442       
3443                exporter->SetFilled();
3444
3445
3446                if (1)
3447                {
3448                        ObjectPvsMap::const_iterator oit,
3449                                oit_end = vc->GetPvs().mEntries.end();
3450
3451
3452                        exporter->SetFilled();
3453
3454                        Intersectable::NewMail();
3455       
3456                        // output PVS of view cell
3457                        for (oit = vc->GetPvs().mEntries.begin(); oit != oit_end; ++ oit)
3458                        {               
3459                                Intersectable *intersect = (*oit).first;
3460
3461                                if (!intersect->Mailed())
3462                                {
3463                                        m = RandomMaterial();
3464                                        exporter->SetForcedMaterial(m);
3465
3466                                        exporter->ExportIntersectable(intersect);
3467                                        intersect->Mail();
3468                                }
3469                        }
3470                }
3471                else
3472                {
3473                        m.mDiffuseColor = RgbColor(1, 0, 0);
3474                        exporter->SetForcedMaterial(m);
3475
3476                        exporter->ExportGeometry(objects);
3477                }
3478
3479                DEL_PTR(exporter);
3480                cout << "finished" << endl;
3481        }
3482
3483        Debug << endl;
3484}
3485
3486
3487int VspBspViewCellsManager::CastLineSegment(const Vector3 &origin,
3488                                                                                        const Vector3 &termination,
3489                                                                                        ViewCellContainer &viewcells)
3490{
3491        return mVspBspTree->CastLineSegment(origin, termination, viewcells);
3492}
3493
3494
3495void VspBspViewCellsManager::ExportColor(Exporter *exporter,
3496                                                                                 ViewCell *vc) const
3497{
3498        const bool vcValid = CheckValidity(vc, mMinPvsSize, mMaxPvsSize);
3499
3500        float importance = 0;
3501        static Material m;
3502
3503        switch (mColorCode)
3504        {
3505        case 0: // Random
3506                {
3507                        if (vcValid)
3508                        {
3509                                m.mDiffuseColor.r = 0.5f + RandomValue(0.0f, 0.5f);
3510                                m.mDiffuseColor.g = 0.5f + RandomValue(0.0f, 0.5f);
3511                                m.mDiffuseColor.b = 0.5f + RandomValue(0.f, 0.5f);
3512                        }
3513                        else
3514                        {
3515                                m.mDiffuseColor.r = 0.0f;
3516                                m.mDiffuseColor.g = 1.0f;
3517                                m.mDiffuseColor.b = 0.0f;
3518                        }
3519
3520                        exporter->SetForcedMaterial(m);
3521                        return;
3522                }
3523               
3524        case 1: // pvs
3525                {
3526                        importance = (float)vc->GetPvs().GetSize() /
3527                                (float)mCurrentViewCellsStats.maxPvs;
3528
3529                }
3530                break;
3531        case 2: // merges
3532                {
3533            int lSize = mViewCellsTree->GetSize(vc);
3534                        importance = (float)lSize / (float)mCurrentViewCellsStats.maxLeaves;
3535                }
3536                break;
3537        case 3: // merge tree differene
3538                {
3539                        importance = (float)GetMaxTreeDiff(vc) /
3540                                (float)(mVspBspTree->GetStatistics().maxDepth * 2);
3541
3542                }
3543                break;
3544        default:
3545                break;
3546        }
3547
3548        // special color code for invalid view cells
3549        m.mDiffuseColor.r = importance;
3550        m.mDiffuseColor.g = 1.0f - m.mDiffuseColor.r;
3551        m.mDiffuseColor.b = vcValid ? 1.0f : 0.0f;
3552
3553        //Debug << "importance: " << importance << endl;
3554        exporter->SetForcedMaterial(m);
3555}
3556
3557
3558void VspBspViewCellsManager::ExportViewCellGeometry(Exporter *exporter,
3559                                                    ViewCell *vc,
3560                                                                                                        const Plane3 *clipPlane) const
3561{
3562        if (vc->GetMesh())
3563        {
3564                exporter->ExportMesh(vc->GetMesh());
3565       
3566                return;
3567        }
3568
3569       
3570        if (clipPlane)
3571        {
3572                ViewCellContainer leaves;
3573                mViewCellsTree->CollectLeaves(vc, leaves);
3574                ViewCellContainer::const_iterator it, it_end = leaves.end();
3575
3576                for (it = leaves.begin(); it != it_end; ++ it)
3577                {
3578                        BspNodeGeometry geom;
3579
3580                        BspNodeGeometry front;
3581                        BspNodeGeometry back;
3582
3583                        BspLeaf *leaf = dynamic_cast<BspViewCell *>(*it)->mLeaf;
3584                        mVspBspTree->ConstructGeometry(leaf, geom);
3585
3586                        const int cf = Polygon3::ClassifyPlane(geom.GetPolys(), *clipPlane, 0.00000001f);
3587
3588                        if (cf == Polygon3::BACK_SIDE)
3589                        {
3590                                exporter->ExportPolygons(geom.GetPolys());
3591                        }
3592                        else if (cf == Polygon3::SPLIT)
3593                        {
3594                                geom.SplitGeometry(front,
3595                                                                   back,
3596                                                                   *clipPlane,
3597                                                                   mViewSpaceBox,
3598                                                                   0.00000001f);
3599       
3600                                //Debug << "here geo size: " << geom.Size() << endl;
3601                                //Debug << "here size b: " << back.Size() << " f: " << front.Size() << endl;
3602                                if (back.Valid())
3603                                {
3604                                        exporter->ExportPolygons(back.GetPolys());
3605                                }
3606                                //else Debug << "here2 size: " << back.Size() << endl;
3607                        }
3608                }
3609        }
3610        else
3611        {
3612                BspNodeGeometry geom;
3613                mVspBspTree->ConstructGeometry(vc, geom);
3614                       
3615                exporter->ExportPolygons(geom.GetPolys());
3616        }
3617}
3618
3619
3620int VspBspViewCellsManager::GetMaxTreeDiff(ViewCell *vc) const
3621{
3622        ViewCellContainer leaves;
3623        mViewCellsTree->CollectLeaves(vc, leaves);
3624
3625        int maxDist = 0;
3626       
3627        // compute max height difference
3628        for (int i = 0; i < (int)leaves.size(); ++ i)
3629                for (int j = 0; j < (int)leaves.size(); ++ j)
3630        {
3631                BspLeaf *leaf = dynamic_cast<BspViewCell *>(leaves[i])->mLeaf;
3632
3633                if (i != j)
3634                {
3635                        BspLeaf *leaf2 =dynamic_cast<BspViewCell *>(leaves[j])->mLeaf;
3636                        int dist = mVspBspTree->TreeDistance(leaf, leaf2);
3637                        if (dist > maxDist)
3638                                maxDist = dist;
3639                }
3640        }
3641
3642        return maxDist;
3643}
3644
3645
3646ViewCell *VspBspViewCellsManager::GetViewCell(const Vector3 &point) const
3647{
3648        if (!mVspBspTree)
3649                return NULL;
3650
3651        if (!mViewSpaceBox.IsInside(point))
3652          return NULL;
3653
3654        return mVspBspTree->GetViewCell(point);
3655}
3656
3657
3658void VspBspViewCellsManager::CreateMesh(ViewCell *vc)
3659{
3660        if (vc->GetMesh())
3661                delete vc->GetMesh();
3662
3663       
3664        BspNodeGeometry geom;
3665
3666        mVspBspTree->ConstructGeometry(vc, geom);
3667       
3668        Mesh *mesh = new Mesh();
3669        geom.AddToMesh(*mesh);
3670        vc->SetMesh(mesh);
3671        mMeshContainer.push_back(mesh);
3672}
3673
3674
3675ViewCellsManager *ViewCellsManager::LoadViewCells(const string filename,
3676                                                                                                  ObjectContainer *objects)
3677{
3678        ViewCellsParser parser;
3679
3680        ViewCellsManager *vm = NULL;
3681
3682        if (parser.ParseFile(filename, &vm, objects))
3683        {
3684                //vm->PrepareLoadedViewCells();
3685                vm->ResetViewCells();
3686
3687                vm->mViewCellsFinished = true;
3688                vm->mMaxPvsSize = (int)objects->size();
3689
3690                vm->FinalizeViewCells(true);
3691
3692                vm->mViewCellsTree->AssignRandomColors();
3693                Debug << (int)vm->mViewCells.size() << " view cells loaded" << endl;
3694        }
3695        else
3696        {
3697                Debug << "failed loading view cells" << endl;
3698                DEL_PTR(vm);
3699        }
3700
3701
3702        return vm;
3703}
3704
3705
3706inline bool ilt(Intersectable *obj1, Intersectable *obj2)
3707{
3708        return obj1->mId < obj2->mId;
3709}
3710
3711
3712bool VspBspViewCellsManager::ExportViewCells(const string filename)
3713{
3714        cout << "exporting view cells to xml ... ";
3715        std::ofstream stream;
3716
3717        // for output we need unique ids for each view cell
3718        CreateUniqueViewCellIds();
3719
3720        stream.open(filename.c_str());
3721        stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"<<endl;
3722        stream << "<Visibility_Solution>" << endl;
3723
3724        //-- the view space bounding box
3725        stream << "<ViewSpaceBox"
3726                   << " min=\"" << mViewSpaceBox.Min().x << " " << mViewSpaceBox.Min().y << " " << mViewSpaceBox.Min().z << "\""
3727                   << " max=\"" << mViewSpaceBox.Max().x << " " << mViewSpaceBox.Max().y << " " << mViewSpaceBox.Max().z << "\" />" << endl;
3728
3729        //-- the type of the view cells hierarchy
3730        stream << "<Hierarchy name=\"vspBspTree\" />" << endl;
3731
3732        //-- load the view cells itself, i.e., the ids and the pvs
3733        stream << "<ViewCells>" << endl;
3734       
3735#if 0
3736       
3737        ViewCellContainer::const_iterator it, it_end = mViewCells.end();
3738               
3739        for (it = mViewCells.begin(); it != it_end; ++ it)
3740                ExportViewCell(*it, stream);
3741#else
3742        mViewCellsTree->Export(stream);
3743#endif
3744
3745        stream << "</ViewCells>" << endl;
3746
3747        //-- load the hierarchy
3748        stream << "<Hierarchy>" << endl;
3749        mVspBspTree->Export(stream);
3750        stream << endl << "</Hierarchy>" << endl;
3751
3752        stream << "</Visibility_Solution>" << endl;
3753        stream.close();
3754
3755        cout << "finished" << endl;
3756
3757        return true;
3758}
3759
3760
3761int VspBspViewCellsManager::CastBeam(Beam &beam)
3762{
3763        return mVspBspTree->CastBeam(beam);
3764}
3765
3766
3767void VspBspViewCellsManager::Finalize(ViewCell *viewCell,
3768                                                                          const bool createMesh)
3769{
3770        float area = 0;
3771        float volume = 0;
3772
3773        ViewCellContainer leaves;
3774        mViewCellsTree->CollectLeaves(viewCell, leaves);
3775
3776        ViewCellContainer::const_iterator it, it_end = leaves.end();
3777
3778    for (it = leaves.begin(); it != it_end; ++ it)
3779        {
3780                BspNodeGeometry geom;
3781                BspLeaf *leaf = dynamic_cast<BspViewCell *>(*it)->mLeaf;
3782                mVspBspTree->ConstructGeometry(leaf, geom);
3783
3784                float lVol = geom.GetVolume();
3785                float lArea = geom.GetArea();
3786
3787                //(*it)->SetVolume(vol);
3788                //(*it)->SetArea(area);
3789
3790                area += lArea;
3791                volume += lVol;
3792
3793        CreateMesh(*it);
3794        }
3795
3796        viewCell->SetVolume(volume);
3797        viewCell->SetArea(area);
3798}
3799
3800
3801void VspBspViewCellsManager::TestSubdivision()
3802{
3803        ViewCellContainer leaves;
3804        mViewCellsTree->CollectLeaves(mViewCellsTree->GetRoot(), leaves);
3805
3806        ViewCellContainer::const_iterator it, it_end = leaves.end();
3807
3808        const float vol = mViewSpaceBox.GetVolume();
3809        float subdivVol = 0;
3810        float newVol = 0;
3811
3812        for (it = leaves.begin(); it != it_end; ++ it)
3813        {
3814                BspNodeGeometry geom;
3815                BspLeaf *leaf = dynamic_cast<BspViewCell *>(*it)->mLeaf;
3816                mVspBspTree->ConstructGeometry(leaf, geom);
3817
3818                const float lVol = geom.GetVolume();
3819               
3820                newVol += lVol;
3821                subdivVol += (*it)->GetVolume();
3822        }
3823       
3824        Debug << "exact volume: " << vol << endl;
3825        Debug << "subdivision volume: " << subdivVol << endl;
3826        Debug << "new volume: " << newVol << endl;
3827}
3828
3829
3830void VspBspViewCellsManager::PrepareLoadedViewCells()
3831{
3832        // TODO: do I still need this here?
3833        if (0)
3834                mVspBspTree->RepairViewCellsLeafLists();
3835}
3836
3837
3838
3839void VspBspViewCellsManager::CollectMergeCandidates(const VssRayContainer &rays,
3840                                                                                                        vector<MergeCandidate> &candidates)
3841{       
3842        cout << "collecting merge candidates ... " << endl;
3843
3844        if (mUseRaysForMerge)
3845        {
3846                mVspBspTree->CollectMergeCandidates(rays, candidates);
3847        }
3848        else
3849        {
3850                vector<BspLeaf *> leaves;
3851                mVspBspTree->CollectLeaves(leaves);
3852                mVspBspTree->CollectMergeCandidates(leaves, candidates);
3853        }
3854
3855        cout << "fininshed collecting candidates" << endl;
3856}
3857
3858
3859void VspBspViewCellsManager::AddCurrentViewCellsToHierarchy()
3860{
3861        ViewCellContainer::const_iterator it, it_end = mViewCells.end();
3862        for (it = mViewCells.begin(); it != it_end; ++ it)
3863        {
3864        }
3865}
3866
3867//////////////////////////////////
3868ViewCellsManager *ViewCellsManagerFactory::Create(const string mName)
3869{
3870        //TODO
3871        return NULL;// new VspBspViewCellsManager();
3872}
3873
Note: See TracBrowser for help on using the repository browser.