source: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp @ 587

Revision 587, 73.4 KB checked in by mattausch, 18 years ago (diff)

updated vspkdtree for regular sudbivision

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