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

Revision 527, 56.9 KB checked in by mattausch, 19 years ago (diff)
Line 
1#include "ViewCellsManager.h"
2#include "RenderSimulator.h"
3#include "Mesh.h"
4#include "Triangle3.h"
5#include "ViewCell.h"
6#include "Environment.h"
7#include "X3dParser.h"
8#include "ViewCellBsp.h"
9#include "KdTree.h"
10#include "VspKdTree.h"
11#include "Exporter.h"
12#include "VspBspTree.h"
13#include "ViewCellsParser.h"
14
15
16ViewCellsManager::ViewCellsManager():
17mRenderer(NULL),
18mConstructionSamples(0),
19mPostProcessSamples(0),
20mVisualizationSamples(0),
21mTotalAreaValid(false),
22mTotalArea(0.0f),
23mViewCellsFinished(false)
24{
25        mSceneBox.Initialize();
26        ParseEnvironment();
27}
28
29
30ViewCellsManager::ViewCellsManager(int constructionSamples):
31mConstructionSamples(constructionSamples),
32mRenderer(NULL),
33mPostProcessSamples(0),
34mVisualizationSamples(0),
35mViewCellsFinished(false)
36{
37        mSceneBox.Initialize();
38        ParseEnvironment();
39}
40
41
42void ViewCellsManager::ParseEnvironment()
43{
44        // visualization stuff
45        environment->GetBoolValue("ViewCells.Visualization.exportRays", mExportRays);
46        environment->GetBoolValue("ViewCells.Visualization.exportGeometry", mExportGeometry);
47
48        char buf[50];
49
50        environment->GetStringValue("ViewCells.Visualization.colorCode", buf);
51
52        if (strcmp(buf, "PVS") == 0)
53                mColorCode = 1;
54        else if (strcmp(buf, "MergedLeaves") == 0)
55                mColorCode = 2;
56        else if (strcmp(buf, "MergedTreeDiff") == 0)
57                mColorCode = 3;
58        else
59                mColorCode = 0;
60
61        Debug << "colorCode: " << mColorCode << endl;
62}
63
64
65ViewCellsManager::~ViewCellsManager()
66{
67        DEL_PTR(mRenderer);
68        CLEAR_CONTAINER(mViewCells);
69        CLEAR_CONTAINER(mMeshContainer);
70}
71
72
73int ViewCellsManager::Construct(VssRayContainer &rays)
74{
75        return 0;
76}
77
78bool ViewCellsManager::LoadViewCells(const string filename, ObjectContainer *objects)
79{
80        X3dParser parser;
81
82        environment->GetFloatValue("ViewCells.height", parser.mViewCellHeight);
83
84        bool success = parser.ParseFile(filename, *this);
85        Debug << (int)mViewCells.size() << " view cells loaded" << endl;
86
87        return success;
88}
89
90
91bool ViewCellsManager::GetViewPoint(Vector3 &viewPoint) const
92{
93        viewPoint = mSceneBox.GetRandomPoint();
94
95        return true;
96}
97
98
99bool ViewCellsManager::ViewPointValid(const Vector3 &viewPoint) const
100{
101        return mSceneBox.IsInside(viewPoint);
102}
103
104
105void ViewCellsManager::ComputeSampleContributions(const VssRayContainer &rays)
106{
107        // view cells not yet constructed
108        if (!ViewCellsConstructed())
109                return;
110
111        VssRayContainer::const_iterator it, it_end = rays.end();
112
113        for (it = rays.begin(); it != it_end; ++ it)
114        {
115                ComputeSampleContributions(*(*it));
116        }
117}
118
119
120void ViewCellsManager::EvaluateViewCellsStats()
121{
122        mViewCellsStats.Reset();
123
124        ViewCellContainer::const_iterator it, it_end = mViewCells.end();
125
126        for (it = mViewCells.begin(); it != it_end; ++ it)
127        {
128                (*it)->UpdateViewCellsStats(mViewCellsStats);
129        }
130}
131
132
133void ViewCellsManager::AddViewCell(ViewCell *viewCell)
134{
135        mViewCells.push_back(viewCell);
136}
137
138
139float ViewCellsManager::GetArea(ViewCell *viewCell) const
140{
141        return viewCell->GetArea();
142}
143
144
145float ViewCellsManager::GetVolume(ViewCell *viewCell) const
146{
147        return viewCell->GetVolume();
148}
149
150
151void ViewCellsManager::DeriveViewCells(const ObjectContainer &objects,
152                                                                           ViewCellContainer &viewCells,
153                                                                           const int maxViewCells) const
154{
155        // maximal max viewcells
156        int limit = maxViewCells > 0 ?
157                Min((int)objects.size(), maxViewCells) : (int)objects.size();
158
159        for (int i = 0; i < limit; ++ i)
160        {
161                Intersectable *object = objects[i];
162
163                // extract the mesh instances
164                if (object->Type() == Intersectable::MESH_INSTANCE)
165                {
166                        MeshInstance *inst = dynamic_cast<MeshInstance *>(object);
167
168                        ViewCell *viewCell = GenerateViewCell(inst->GetMesh());
169                        viewCells.push_back(viewCell);
170                }
171                //TODO: transformed meshes
172        }
173}
174
175
176ViewCell *ViewCellsManager::ExtrudeViewCell(const Triangle3 &baseTri,
177                                                                                        const float height) const
178{
179        // one mesh per view cell
180        Mesh *mesh = new Mesh();
181
182        //-- construct prism
183
184        // bottom
185        mesh->mFaces.push_back(new Face(2,1,0));
186        // top
187    mesh->mFaces.push_back(new Face(3,4,5));
188        // sides
189        mesh->mFaces.push_back(new Face(1, 4, 3, 0));
190        mesh->mFaces.push_back(new Face(2, 5, 4, 1));
191        mesh->mFaces.push_back(new Face(3, 5, 2, 0));
192
193        //--- extrude new vertices for top of prism
194        Vector3 triNorm = baseTri.GetNormal();
195
196        Triangle3 topTri;
197
198        // add base vertices and calculate top vertices
199        for (int i = 0; i < 3; ++ i)
200                mesh->mVertices.push_back(baseTri.mVertices[i]);
201
202        // add top vertices
203        for (int i = 0; i < 3; ++ i)
204                mesh->mVertices.push_back(baseTri.mVertices[i] + height * triNorm);
205
206        mesh->Preprocess();
207
208        return GenerateViewCell(mesh);
209}
210
211
212ViewCell *ViewCellsManager::MergeViewCells(ViewCell &front, ViewCell &back) const
213{
214        // generate merged view cell
215        ViewCell *vc = GenerateViewCell();
216
217        // merge pvs
218        vc->GetPvs().Merge(front.GetPvs(), back.GetPvs());
219
220        //-- merge ray sets
221        stable_sort(front.mPiercingRays.begin(), front.mPiercingRays.end());
222        stable_sort(back.mPiercingRays.begin(), back.mPiercingRays.end());
223
224        std::merge(front.mPiercingRays.begin(), front.mPiercingRays.end(),
225                           back.mPiercingRays.begin(), back.mPiercingRays.end(),
226                           vc->mPiercingRays.begin());
227
228        return vc;
229}
230
231
232void ViewCellsManager::SetRenderer(Renderer *renderer)
233{
234        mRenderer = renderer;
235}
236
237
238ViewCell *ViewCellsManager::GenerateViewCell(Mesh *mesh) const
239{
240        return new ViewCell(mesh);
241}
242
243
244void ViewCellsManager::SetVisualizationSamples(const int visSamples)
245{
246        mVisualizationSamples = visSamples;
247}
248
249
250void ViewCellsManager::SetConstructionSamples(const int constructionSamples)
251{
252        mConstructionSamples = constructionSamples;
253}
254
255
256void ViewCellsManager::SetPostProcessSamples(const int postProcessSamples)
257{
258        mPostProcessSamples = postProcessSamples;
259}
260
261
262int ViewCellsManager::GetVisualizationSamples() const
263{
264        return mVisualizationSamples;
265}
266
267
268int ViewCellsManager::GetConstructionSamples() const
269{
270        return mConstructionSamples;
271}
272
273
274int ViewCellsManager::GetPostProcessSamples() const
275{
276        return mPostProcessSamples;
277}
278
279
280void ViewCellsManager::GetPvsStatistics(PvsStatistics &stat)
281{
282  ViewCellContainer::const_iterator it = mViewCells.begin();
283  stat.viewcells = 0;
284  stat.minPvs = 100000000;
285  stat.maxPvs = 0;
286  stat.avgPvs = 0.0f;
287
288  for (; it != mViewCells.end(); ++it) {
289        ViewCell *viewcell = *it;
290        int pvsSize = viewcell->GetPvs().GetSize();
291        if ( pvsSize < stat.minPvs)
292          stat.minPvs = pvsSize;
293        if (pvsSize > stat.maxPvs)
294          stat.maxPvs = pvsSize;
295        stat.avgPvs += pvsSize;
296        stat.viewcells++;
297  }
298  if (stat.viewcells)
299        stat.avgPvs/=stat.viewcells;
300}
301
302
303void ViewCellsManager::PrintPvsStatistics(ostream &s)
304{
305  s<<"############# Viewcell PVS STAT ##################\n";
306  PvsStatistics pvsStat;
307  GetPvsStatistics(pvsStat);
308  s<<"#AVG_PVS\n"<<pvsStat.avgPvs<<endl;
309  s<<"#MAX_PVS\n"<<pvsStat.maxPvs<<endl;
310  s<<"#MIN_PVS\n"<<pvsStat.minPvs<<endl;
311}
312
313
314ViewCellContainer &ViewCellsManager::GetViewCells()
315{
316        return mViewCells;
317}
318
319
320void ViewCellsManager::SetViewSpaceBox(const AxisAlignedBox3 &box)
321{
322        mSceneBox = box;
323}
324
325
326AxisAlignedBox3 ViewCellsManager::GetViewSpaceBox() const
327{
328        return mSceneBox;
329}
330
331
332void ViewCellsManager::ResetViewCells()
333{
334        mViewCells.clear();
335       
336        CollectViewCells();
337       
338        mViewCellsStats.Reset();
339        EvaluateViewCellsStats();
340        // has to be recomputed
341        mTotalAreaValid = false;
342}
343
344
345void ViewCellsManager::ComputeSampleContributions(VssRay &ray)
346{
347  ViewCellContainer viewcells;
348
349  ray.mPvsContribution = 0;
350  ray.mRelativePvsContribution = 0.0f;
351
352  // matt TODO: remove this!!
353  Ray hray(ray);
354  float tmin = 0, tmax = 1.0;
355
356  //hray.Init(ray.GetOrigin(), ray.GetDir(), Ray::LINE_SEGMENT);
357  if (!GetViewSpaceBox().GetRaySegment(hray, tmin, tmax) || (tmin > tmax))
358        return;
359
360  Vector3 origin = hray.Extrap(tmin);
361  Vector3 termination = hray.Extrap(tmax);
362
363  CastLineSegment(origin,
364                                  termination,
365                                  viewcells);
366  //Debug << "constribution: " << (int)viewcells.size() << endl;
367  // copy viewcells memory efficiently
368  const bool storeViewcells = false;
369  if (storeViewcells) {
370        ray.mViewCells.reserve(viewcells.size());
371        ray.mViewCells = viewcells;
372  }
373
374  ViewCellContainer::const_iterator it = viewcells.begin();
375
376  bool addInPlace = false;
377
378  if (addInPlace) {
379        for (; it != viewcells.end(); ++it) {
380          ViewCell *viewcell = *it;
381
382          // if ray not outside of view space
383          float contribution;
384          bool added =
385                viewcell->GetPvs().AddSample(ray.mTerminationObject,
386                                                                         contribution
387                                                                         );
388          if (added)
389                ray.mPvsContribution++;
390
391          ray.mRelativePvsContribution += contribution;
392        }
393  } else {
394    for (; it != viewcells.end(); ++it) {
395          ViewCell *viewcell = *it;
396          // if ray not outside of view space
397          float contribution;
398          if (viewcell->GetPvs().GetSampleContribution(ray.mTerminationObject,
399                                                                                                   contribution
400                                                                                                   ))
401                ray.mPvsContribution++;
402
403          ray.mRelativePvsContribution += contribution;
404        }
405
406        for (it = viewcells.begin(); it != viewcells.end(); ++it) {
407          ViewCell *viewcell = *it;
408          // if ray not outside of view space
409          viewcell->GetPvs().AddSample(ray.mTerminationObject);
410        }
411  }
412}
413
414
415void ViewCellsManager::GetRaySets(const VssRayContainer &sourceRays,
416                                                                  const int maxSize,
417                                                                  VssRayContainer &usedRays,
418                                                                  VssRayContainer *savedRays) const
419{
420        const int limit = min(maxSize, (int)sourceRays.size());
421        const float prop = (float)limit / ((float)sourceRays.size() + Limits::Small);
422
423        VssRayContainer::const_iterator it, it_end = sourceRays.end();
424        for (it = sourceRays.begin(); it != it_end; ++ it)
425        {
426                if (Random(1.0f) < prop)
427                        usedRays.push_back(*it);
428                else if (savedRays)
429                        savedRays->push_back(*it);
430        }
431}
432
433
434float ViewCellsManager::GetAccVcArea()
435{
436        // if already computed
437        if (mTotalAreaValid)
438                return mTotalArea;
439
440        mTotalArea = 0;
441        ViewCellContainer::const_iterator it, it_end = mViewCells.end();
442
443        for (it = mViewCells.begin(); it != it_end; ++ it)
444        {
445                //Debug << "area: " << GetArea(*it);
446        mTotalArea += GetArea(*it);
447        }
448
449        mTotalAreaValid = true;
450
451        return mTotalArea;
452}
453
454
455void ViewCellsManager::PrintStatistics(ostream &s) const
456{
457        s << mViewCellsStats << endl;
458}
459
460
461void ViewCellsManager::CreateUniqueViewCellIds()
462{
463        for (int i = 0; i < (int)mViewCells.size(); ++ i)
464                mViewCells[i]->SetId(i);
465}
466
467
468void ViewCellsManager::ExportViewCellsForViz(Exporter *exporter) const
469{
470        ViewCellContainer::const_iterator it, it_end = mViewCells.end();
471
472        for (it = mViewCells.begin(); it != it_end; ++ it)
473        {
474                ExportColor(exporter, *it);
475                ExportVcGeometry(exporter, *it);
476        }
477}
478
479
480void ViewCellsManager::CreateViewCellMeshes()
481{
482        // convert to meshes
483        ViewCellContainer::const_iterator it, it_end = mViewCells.end();
484
485        for (it = mViewCells.begin(); it != it_end; ++ it)
486        {
487                if (!(*it)->GetMesh())
488                        CreateMesh(*it);
489        }
490}
491
492
493bool ViewCellsManager::ExportViewCells(const string filename)
494{
495        return false;
496}
497
498
499void ViewCellsManager::ExportViewCell(ViewCell *viewCell, ofstream &stream)
500{
501        stream << "<ViewCell id=\"" << viewCell->GetId() << "\" ";
502        stream << "pvs=\"";
503
504        ObjectPvsMap::iterator it, it_end = viewCell->GetPvs().mEntries.end();
505        if(0) // test with empty pvs
506        for (it = viewCell->GetPvs().mEntries.begin(); it != it_end; ++ it)
507        {
508                stream << (*it).first->GetId() << " ";
509        }
510
511        stream << "\" />" << endl;
512}
513
514
515/**********************************************************************/
516/*                   BspViewCellsManager implementation               */
517/**********************************************************************/
518
519
520BspViewCellsManager::BspViewCellsManager(BspTree *bspTree,
521                                                                                 int constructionSamples):
522ViewCellsManager(constructionSamples),
523mBspTree(bspTree)
524{
525}
526
527
528bool BspViewCellsManager::ViewCellsConstructed() const
529{
530        return mBspTree->GetRoot() != NULL;
531}
532
533
534ViewCell *BspViewCellsManager::GenerateViewCell(Mesh *mesh) const
535{
536        return new BspViewCell(mesh);
537}
538
539
540int BspViewCellsManager::Construct(const ObjectContainer &objects,
541                                                                   const VssRayContainer &rays)
542{
543        // if view cells were already constructed
544        if (ViewCellsConstructed())
545                return 0;
546
547        int sampleContributions = 0;
548
549        // construct view cells using the collected samples
550        RayContainer constructionRays;
551        VssRayContainer savedRays;
552
553        const int limit = min(mConstructionSamples, (int)rays.size());
554
555        VssRayContainer::const_iterator it, it_end = rays.end();
556
557        const float prop = (float)limit / ((float)rays.size() + Limits::Small);
558
559        for (it = rays.begin(); it != it_end; ++ it)
560        {
561                if (Random(1.0f) < prop)
562                        constructionRays.push_back(new Ray(*(*it)));
563                else
564                        savedRays.push_back(*it);
565        }
566
567    if (mViewCells.empty())
568        {
569                // no view cells loaded
570                mBspTree->Construct(objects, constructionRays);
571                // collect final view cells
572                mBspTree->CollectViewCells(mViewCells);
573        }
574        else
575        {
576                mBspTree->Construct(mViewCells);
577        }
578
579        // destroy rays created only for construction
580        CLEAR_CONTAINER(constructionRays);
581
582        Debug << mBspTree->GetStatistics() << endl;
583
584        //EvaluateViewCellsStats();
585        Debug << "\nView cells after construction:\n" << mViewCellsStats << endl;
586
587        // recast rest of the rays
588        ComputeSampleContributions(savedRays);
589
590
591        return sampleContributions;
592}
593
594
595void BspViewCellsManager::CollectViewCells()
596{
597        mBspTree->CollectViewCells(mViewCells);
598}
599
600
601float BspViewCellsManager::GetProbability(ViewCell *viewCell)
602{
603        // compute view cell area as subsititute for probability
604#if 0
605        return GetArea(viewCell) / GetViewSpaceBox().SurfaceArea();
606#else
607        return GetArea(viewCell) / GetAccVcArea();
608#endif
609}
610
611
612float BspViewCellsManager::GetRendercost(ViewCell *viewCell, float objRendercost) const
613{
614        return viewCell->GetPvs().GetSize() * objRendercost;
615}
616
617
618int BspViewCellsManager::CastLineSegment(const Vector3 &origin,
619                                                                                 const Vector3 &termination,
620                                                                                 ViewCellContainer &viewcells)
621{
622        return mBspTree->CastLineSegment(origin, termination, viewcells);
623}
624
625
626int BspViewCellsManager::PostProcess(const ObjectContainer &objects,
627                                                                         const VssRayContainer &rays)
628{
629        if (!ViewCellsConstructed())
630        {
631                Debug << "view cells not constructed" << endl;
632                return 0;
633        }
634
635        //-- post processing of bsp view cells
636    int vcSize = 0;
637        int pvsSize = 0;
638
639        EvaluateViewCellsStats();
640        Debug << "\noriginal view cell partition:\n" << mViewCellsStats << endl;
641
642        mRenderer->RenderScene();
643        SimulationStatistics ss;
644        dynamic_cast<RenderSimulator *>(mRenderer)->GetStatistics(ss);
645
646    Debug << ss << endl;
647
648        if (1) // export view cells
649        {
650                cout << "exporting initial view cells (=leaves) ... ";
651                Exporter *exporter = Exporter::GetExporter("view_cells.x3d");
652
653                if (exporter)
654                {
655                        //exporter->SetWireframe();
656                        exporter->SetFilled();
657                        ExportViewCellsForViz(exporter);
658
659                        if (mExportGeometry)
660                        {
661                                Material m;
662                                m.mDiffuseColor = RgbColor(0, 1, 0);
663                                exporter->SetForcedMaterial(m);
664                                exporter->SetWireframe();
665
666                                exporter->ExportGeometry(objects);
667                        }
668
669                        delete exporter;
670                }
671                cout << "finished" << endl;
672        }
673
674        cout << "starting post processing using " << mPostProcessSamples << " samples ... ";
675
676        long startTime = GetTime();
677
678
679        // $$JB we do not have connectivity information from the ray in the moment
680        // perhaps we could recast the rays or remember the cells traversed inside the
681        // vssray (which would on other hand create some overhead)
682        //-- merge or subdivide view cells
683        int merged = 0;
684
685        vector<BspIntersection>::const_iterator iit;
686        CLEAR_CONTAINER(mBspRays);
687        ConstructBspRays(rays, mPostProcessSamples);
688
689        for (int i = 0; i < (int)mBspRays.size(); ++ i)
690        {
691                BspRay *ray = mBspRays[i];
692
693                // traverse leaves stored in the rays and compare and merge consecutive
694                // leaves (i.e., the neighbors in the tree)
695                if (ray->intersections.size() < 2)
696                        continue;
697
698                iit = ray->intersections.begin();
699
700                BspLeaf *previousLeaf = (*iit).mLeaf;
701                ++ iit;
702
703                for (; iit != ray->intersections.end(); ++ iit)
704                {
705                        BspLeaf *leaf = (*iit).mLeaf;
706
707                        if (ShouldMerge(leaf, previousLeaf))
708                        {
709                                MergeBspLeafViewCells(leaf, previousLeaf);
710
711                                ++ merged;
712                        }
713
714                        previousLeaf = leaf;
715                }
716        }
717
718        //-- stats and visualizations
719        cout << "finished" << endl;
720        cout << "merged " << merged << " view cells in "
721                 << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl;
722
723        Debug << "Postprocessing: Merged " << merged << " view cells in "
724                  << TimeDiff(startTime, GetTime()) *1e-3 << " secs"
725                  << "using " << (int)mBspRays.size() << " samples" << endl << endl;
726
727        CLEAR_CONTAINER(mBspRays);
728
729        // reset view cells and stats
730        ResetViewCells();
731
732        return merged;
733}
734
735
736BspViewCellsManager::~BspViewCellsManager()
737{
738        CLEAR_CONTAINER(mBspRays);
739}
740
741
742int BspViewCellsManager::GetType() const
743{
744        return BSP;
745}
746
747
748void BspViewCellsManager::Visualize(const ObjectContainer &objects,
749                                                                        const VssRayContainer &sampleRays)
750{
751        if (!ViewCellsConstructed())
752                return;
753        CLEAR_CONTAINER(mBspRays);
754        ConstructBspRays(sampleRays, mVisualizationSamples);
755
756        if (1) // export view cells
757        {
758                cout << "exporting view cells after merge ... ";
759                Exporter *exporter = Exporter::GetExporter("merged_view_cells.x3d");
760
761                if (exporter)
762                {
763                        ExportViewCellsForViz(exporter);
764                        delete exporter;
765                }
766
767                cout << "finished" << endl;
768        }
769
770        //-- visualization of the BSP splits
771        bool exportSplits = false;
772        environment->GetBoolValue("BspTree.Visualization.exportSplits", exportSplits);
773
774        if (exportSplits)
775        {
776                cout << "exporting splits ... ";
777                ExportSplits(objects);
778                cout << "finished" << endl;
779        }
780
781        ExportBspPvs(objects);
782}
783
784
785inline bool vc_gt(ViewCell *a, ViewCell *b)
786{
787        return a->GetPvs().GetSize() > b->GetPvs().GetSize();
788}
789
790
791void BspViewCellsManager::ExportSplits(const ObjectContainer &objects)
792{
793        Exporter *exporter = Exporter::GetExporter("bsp_splits.x3d");
794
795        if (exporter)
796        {
797                Material m;
798                m.mDiffuseColor = RgbColor(1, 0, 0);
799                exporter->SetForcedMaterial(m);
800                exporter->SetWireframe();
801
802                exporter->ExportBspSplits(*mBspTree, true);
803
804                //NOTE: take forced material, else big scenes cannot be viewed
805                m.mDiffuseColor = RgbColor(0, 1, 0);
806                exporter->SetForcedMaterial(m);
807                //exporter->ResetForcedMaterial();
808
809                exporter->SetFilled();
810
811                // export rays
812                if (0)
813                {
814                        VssRayContainer outRays;
815
816                        int raysSize = min((int)mBspRays.size(), mVisualizationSamples);
817
818                        for (int i = 0; i < raysSize; ++ i)
819                                // only rays piercing geometry
820                                outRays.push_back(mBspRays[i]->vssRay);
821
822                        // export rays
823                        exporter->ExportRays(outRays, RgbColor(1, 1, 0));
824                }
825
826                if (mExportGeometry)
827                        exporter->ExportGeometry(objects);
828
829                delete exporter;
830        }
831}
832
833
834void BspViewCellsManager::ExportBspPvs(const ObjectContainer &objects)
835{
836        const int leafOut = 10;
837
838        ViewCell::NewMail();
839
840        //-- some rays for output
841        const int raysOut = min((int)mBspRays.size(), mVisualizationSamples);
842
843        cout << "visualization using " << mVisualizationSamples << " samples" << endl;
844        Debug << "\nOutput view cells: " << endl;
845
846        // sort view cells to get largest view cells
847#if 0
848        stable_sort(mViewCells.begin(), mViewCells.end(), vc_gt);
849#endif
850        int limit = min(leafOut, (int)mViewCells.size());
851
852        for (int i = 0; i < limit; ++ i)
853        {
854                cout << "creating output for view cell " << i << " ... ";
855                VssRayContainer vcRays;
856                Intersectable::NewMail();
857#if 0
858                BspViewCell *vc = dynamic_cast<BspViewCell *>(mViewCells[i]);
859#else
860                BspViewCell *vc = dynamic_cast<BspViewCell *>(mViewCells[Random((int)mViewCells.size())]);
861#endif
862                cout << "creating output for view cell " << i << " ... ";
863
864#if 0
865                // check whether we can add the current ray to the output rays
866                for (int k = 0; k < raysOut; ++ k)
867                {
868                        BspRay *ray = mBspRays[k];
869                        for     (int j = 0; j < (int)ray->intersections.size(); ++ j)
870                        {
871                                BspLeaf *leaf = ray->intersections[j].mLeaf;
872                                if (vc == leaf->GetViewCell())
873                                        vcRays.push_back(ray->vssRay);
874                        }
875                }
876#endif
877                //bspLeaves[j]->Mail();
878                char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i);
879
880                Exporter *exporter = Exporter::GetExporter(s);
881
882                exporter->SetWireframe();
883
884                Material m;//= RandomMaterial();
885                m.mDiffuseColor = RgbColor(0, 1, 0);
886                exporter->SetForcedMaterial(m);
887
888                if (vc->GetMesh())
889                        exporter->ExportViewCell(vc);
890                else
891                {
892                        BspNodeGeometry vcGeom;
893
894                        //-- export view cell
895                        mBspTree->ConstructGeometry(vc, vcGeom);
896                        exporter->ExportPolygons(vcGeom.mPolys);
897                }
898
899                Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize()
900                          << ", piercing rays=" << (int)vcRays.size()
901                          << ", leaves=" << (int)vc->mLeaves.size() << endl;
902
903
904                // export rays piercing this view cell
905#if 0
906                exporter->ExportRays(vcRays, RgbColor(0, 1, 0));
907#else
908                vector<BspLeaf *>::const_iterator lit, lit_end = vc->mLeaves.end();
909                for (lit = vc->mLeaves.begin(); lit != lit_end; ++ lit)
910                        exporter->ExportRays((*lit)->mVssRays);
911#endif
912                m.mDiffuseColor = RgbColor(1, 0, 0);
913                exporter->SetForcedMaterial(m);
914
915                ObjectPvsMap::const_iterator it,
916                        it_end = vc->GetPvs().mEntries.end();
917
918                exporter->SetFilled();
919
920                // output PVS of view cell
921                for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it)
922                {
923                        Intersectable *intersect = (*it).first;
924
925                        if (!intersect->Mailed())
926                        {
927                                Material m = RandomMaterial();
928                                exporter->SetForcedMaterial(m);
929
930                                exporter->ExportIntersectable(intersect);
931                                intersect->Mail();
932                        }
933                }
934
935                DEL_PTR(exporter);
936                cout << "finished" << endl;
937        }
938
939        Debug << endl;
940}
941
942
943bool BspViewCellsManager::MergeBspLeafViewCells(BspLeaf *front, BspLeaf *back) const
944{
945        BspViewCell *viewCell =
946                dynamic_cast<BspViewCell *>(MergeViewCells(*front->GetViewCell(),
947                                                                                                   *back->GetViewCell()));
948
949        if (!viewCell)
950                return false;
951
952        //-- change pointer to view cells of all leaves associated with the previous view cells
953        BspViewCell *fVc = front->GetViewCell();
954        BspViewCell *bVc = back->GetViewCell();
955
956        vector<BspLeaf *> fLeaves = fVc->mLeaves;
957        vector<BspLeaf *> bLeaves = bVc->mLeaves;
958
959        vector<BspLeaf *>::const_iterator it;
960
961        for (it = fLeaves.begin(); it != fLeaves.end(); ++ it)
962        {
963                (*it)->SetViewCell(viewCell);
964                viewCell->mLeaves.push_back(*it);
965        }
966        for (it = bLeaves.begin(); it != bLeaves.end(); ++ it)
967        {
968                (*it)->SetViewCell(viewCell);
969                viewCell->mLeaves.push_back(*it);
970        }
971
972        DEL_PTR(fVc);
973        DEL_PTR(bVc);
974
975        return true;
976}
977
978bool BspViewCellsManager::ShouldMerge(BspLeaf *front, BspLeaf *back) const
979{
980        ViewCell *fvc = front->GetViewCell();
981        ViewCell *bvc = back->GetViewCell();
982
983        if ((fvc == mBspTree->GetRootCell()) || (bvc == mBspTree->GetRootCell()) || (fvc == bvc))
984                return false;
985
986        int fdiff = fvc->GetPvs().Diff(bvc->GetPvs());
987
988        if (fvc->GetPvs().GetSize() + fdiff < mMaxPvs)
989        {
990                if ((fvc->GetPvs().GetSize() < mMinPvs) ||
991                        (bvc->GetPvs().GetSize() < mMinPvs) ||
992                        ((fdiff < mMinPvsDif) && (bvc->GetPvs().Diff(fvc->GetPvs()) < mMinPvsDif)))
993                {
994                        return true;
995                }
996        }
997
998        return false;
999}
1000
1001
1002void BspViewCellsManager::ConstructBspRays(const VssRayContainer &rays,
1003                                                                                   const int numSamples)
1004{
1005        VssRayContainer::const_iterator it, it_end = rays.end();
1006
1007        for (it = rays.begin(); it != rays.end() && mBspRays.size() < numSamples; ++ it)
1008        {
1009                VssRay *vssRay = *it;
1010                BspRay *ray = new BspRay(vssRay);
1011
1012                ViewCellContainer viewCells;
1013
1014                // cast line segment to get intersections with bsp leaves
1015                CastLineSegment(vssRay->mTermination, vssRay->mOrigin, viewCells);
1016
1017                ViewCellContainer::const_iterator vit, vit_end = viewCells.end();
1018                for (vit = viewCells.begin(); vit != vit_end; ++ vit)
1019                {
1020                        BspViewCell *vc = dynamic_cast<BspViewCell *>(*vit);
1021                        ray->intersections.push_back(BspIntersection(0, vc->mLeaves[0]));
1022                }
1023
1024                mBspRays.push_back(ray);
1025        }
1026}
1027
1028
1029void BspViewCellsManager::ExportColor(Exporter *exporter,
1030                                                                          ViewCell *vc) const
1031{
1032        if (mColorCode == 0) // Random color
1033        {
1034                exporter->ResetForcedMaterial();
1035                return;
1036        }
1037
1038        float importance = 0;
1039
1040        switch (mColorCode)
1041        {
1042        case 1: // pvs
1043                {
1044                        importance = (float)vc->GetPvs().GetSize() /
1045                                (float)mViewCellsStats.maxPvs;
1046                }
1047                break;
1048        case 2: // merges
1049                {
1050                        BspViewCell *bspVc = dynamic_cast<BspViewCell *>(vc);
1051
1052                        importance = (float)bspVc->mLeaves.size() /
1053                                (float)mViewCellsStats.maxLeaves;
1054                }
1055                break;
1056        case 3: // merge tree differene
1057                {
1058                        // TODO
1059                }
1060                break;
1061        default:
1062                break;
1063        }
1064
1065        Material m;
1066        m.mDiffuseColor.b = 1.0f;
1067        m.mDiffuseColor.r = importance;
1068        m.mDiffuseColor.g = 1.0f - m.mDiffuseColor.r;
1069
1070        exporter->SetForcedMaterial(m);
1071}
1072
1073void BspViewCellsManager::ExportVcGeometry(Exporter *exporter,
1074                                                                                 ViewCell *vc) const
1075{
1076        if (vc->GetMesh())
1077                exporter->ExportViewCell(vc);
1078        else
1079        {
1080                BspNodeGeometry geom;
1081                mBspTree->ConstructGeometry(
1082                        dynamic_cast<BspViewCell *>(vc), geom);
1083                exporter->ExportPolygons(geom.mPolys);
1084        }
1085}
1086
1087
1088void BspViewCellsManager::CreateMesh(ViewCell *vc)
1089{
1090}
1091
1092ViewCell *
1093BspViewCellsManager::GetViewCell(const Vector3 &point)
1094{
1095  if (!mBspTree)
1096        return NULL;
1097  return mBspTree->GetViewCell(point);
1098}
1099
1100/**********************************************************************/
1101/*                   KdViewCellsManager implementation               */
1102/**********************************************************************/
1103
1104
1105
1106KdViewCellsManager::KdViewCellsManager(KdTree *kdTree):
1107ViewCellsManager(), mKdTree(kdTree), mKdPvsDepth(100)
1108{
1109}
1110
1111float KdViewCellsManager::GetProbability(ViewCell *viewCell)
1112{
1113        // compute view cell area / volume as subsititute for probability
1114#if 0
1115        return GetArea(viewCell) / GetViewSpaceBox().SurfaceArea();
1116#endif
1117#if 1
1118        return GetArea(viewCell) / GetAccVcArea();
1119#endif
1120#if 0
1121        return GetVolume(viewCell) / GetViewSpaceBox().GetVolume();
1122#endif
1123}
1124
1125
1126float KdViewCellsManager::GetRendercost(ViewCell *viewCell, float objRendercost) const
1127{
1128        return viewCell->GetPvs().GetSize() * objRendercost;
1129}
1130
1131
1132void KdViewCellsManager::CollectViewCells()
1133{
1134        //mKdTree->CollectViewCells(mViewCells); TODO
1135}
1136
1137
1138int KdViewCellsManager::Construct(const ObjectContainer &objects,
1139                                                                  const VssRayContainer &rays)
1140{
1141        // if view cells already constructed
1142        if (ViewCellsConstructed())
1143                return 0;
1144
1145        mKdTree->Construct();
1146
1147        mTotalAreaValid = false;
1148        // create the view cells
1149        mKdTree->CreateAndCollectViewCells(mViewCells);
1150
1151        // cast rays
1152        ComputeSampleContributions(rays);
1153
1154        EvaluateViewCellsStats();
1155        Debug << "\nView cells after construction:\n" << mViewCellsStats << endl;
1156
1157        return 0;
1158}
1159
1160bool KdViewCellsManager::ViewCellsConstructed() const
1161{
1162        return mKdTree->GetRoot() != NULL;
1163}
1164
1165int KdViewCellsManager::PostProcess(const ObjectContainer &objects,
1166                                                                        const VssRayContainer &rays)
1167{
1168        return 0;
1169}
1170
1171void KdViewCellsManager::Visualize(const ObjectContainer &objects,
1172                                                                   const VssRayContainer &sampleRays)
1173{
1174        if (!ViewCellsConstructed())
1175                return;
1176
1177        // using view cells instead of the kd PVS of objects
1178        const bool useViewCells = true;
1179        bool exportRays = false;
1180
1181        int limit = min(mVisualizationSamples, (int)sampleRays.size());
1182        const int pvsOut = min((int)objects.size(), 10);
1183        VssRayContainer *rays = new VssRayContainer[pvsOut];
1184
1185        if (useViewCells)
1186        {
1187                const int leafOut = 10;
1188
1189                ViewCell::NewMail();
1190
1191                //-- some rays for output
1192                const int raysOut = min((int)sampleRays.size(), mVisualizationSamples);
1193                Debug << "visualization using " << raysOut << " samples" << endl;
1194
1195                //-- some random view cells and rays for output
1196                vector<KdLeaf *> kdLeaves;
1197
1198                for (int i = 0; i < leafOut; ++ i)
1199                        kdLeaves.push_back(dynamic_cast<KdLeaf *>(mKdTree->GetRandomLeaf()));
1200
1201                for (int i = 0; i < kdLeaves.size(); ++ i)
1202                {
1203                        KdLeaf *leaf = kdLeaves[i];
1204                        RayContainer vcRays;
1205
1206                        cout << "creating output for view cell " << i << " ... ";
1207#if 0
1208                        // check whether we can add the current ray to the output rays
1209                        for (int k = 0; k < raysOut; ++ k)
1210                        {
1211                                Ray *ray = sampleRays[k];
1212
1213                                for (int j = 0; j < (int)ray->bspIntersections.size(); ++ j)
1214                                {
1215                                        BspLeaf *leaf2 = ray->bspIntersections[j].mLeaf;
1216
1217                                        if (leaf->GetViewCell() == leaf2->GetViewCell())
1218                                        {
1219                                                vcRays.push_back(ray);
1220                                        }
1221                                }
1222                        }
1223#endif
1224                        Intersectable::NewMail();
1225
1226                        ViewCell *vc = leaf->mViewCell;
1227
1228                        //bspLeaves[j]->Mail();
1229                        char s[64]; sprintf(s, "kd-pvs%04d.x3d", i);
1230
1231                        Exporter *exporter = Exporter::GetExporter(s);
1232                        exporter->SetFilled();
1233
1234                        exporter->SetWireframe();
1235                        //exporter->SetFilled();
1236
1237                        Material m;//= RandomMaterial();
1238                        m.mDiffuseColor = RgbColor(1, 1, 0);
1239                        exporter->SetForcedMaterial(m);
1240
1241                        AxisAlignedBox3 box = mKdTree->GetBox(leaf);
1242                        exporter->ExportBox(box);
1243
1244                        Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize()
1245                                << ", piercing rays=" << (int)vcRays.size() << endl;
1246
1247                        // export rays piercing this view cell
1248                        exporter->ExportRays(vcRays, 1000, RgbColor(0, 1, 0));
1249
1250                        m.mDiffuseColor = RgbColor(1, 0, 0);
1251                        exporter->SetForcedMaterial(m);
1252
1253                        // exporter->SetWireframe();
1254                        exporter->SetFilled();
1255
1256                        ObjectPvsMap::iterator it, it_end = vc->GetPvs().mEntries.end();
1257                        // output PVS of view cell
1258                        for (it = vc->GetPvs().mEntries.begin(); it !=  it_end; ++ it)
1259                        {
1260                                Intersectable *intersect = (*it).first;
1261                                if (!intersect->Mailed())
1262                                {
1263                                        exporter->ExportIntersectable(intersect);
1264                                        intersect->Mail();
1265                                }
1266                        }
1267
1268                        DEL_PTR(exporter);
1269                        cout << "finished" << endl;
1270                }
1271
1272                DEL_PTR(rays);
1273        }
1274        else // using kd PVS of objects
1275        {
1276                for (int i = 0; i < limit; ++ i)
1277                {
1278                        VssRay *ray = sampleRays[i];
1279
1280                        // check whether we can add this to the rays
1281                        for (int j = 0; j < pvsOut; j++)
1282                        {
1283                                if (objects[j] == ray->mTerminationObject)
1284                                {
1285                                        rays[j].push_back(ray);
1286                                }
1287                        }
1288                }
1289
1290                if (exportRays)
1291                {
1292                        Exporter *exporter = NULL;
1293                        exporter = Exporter::GetExporter("sample-rays.x3d");
1294                        exporter->SetWireframe();
1295                        exporter->ExportKdTree(*mKdTree);
1296
1297                        for (i=0; i < pvsOut; i++)
1298                                exporter->ExportRays(rays[i], RgbColor(1, 0, 0));
1299
1300                        exporter->SetFilled();
1301
1302                        delete exporter;
1303                }
1304
1305                for (int k=0; k < pvsOut; k++)
1306                {
1307                        Intersectable *object = objects[k];
1308                        char s[64];
1309                        sprintf(s, "sample-pvs%04d.x3d", k);
1310
1311                        Exporter *exporter = Exporter::GetExporter(s);
1312                        exporter->SetWireframe();
1313
1314                        KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
1315                        Intersectable::NewMail();
1316
1317                        // avoid adding the object to the list
1318                        object->Mail();
1319                        ObjectContainer visibleObjects;
1320
1321                        for (; i != object->mKdPvs.mEntries.end(); i++)
1322                        {
1323                                KdNode *node = (*i).first;
1324                                exporter->ExportBox(mKdTree->GetBox(node));
1325
1326                                mKdTree->CollectObjects(node, visibleObjects);
1327                        }
1328
1329                        exporter->ExportRays(rays[k],  RgbColor(0, 1, 0));
1330                        exporter->SetFilled();
1331
1332                        for (int j = 0; j < visibleObjects.size(); j++)
1333                                exporter->ExportIntersectable(visibleObjects[j]);
1334
1335                        Material m;
1336                        m.mDiffuseColor = RgbColor(1, 0, 0);
1337                        exporter->SetForcedMaterial(m);
1338                        exporter->ExportIntersectable(object);
1339
1340                        delete exporter;
1341                }
1342        }
1343}
1344
1345
1346void KdViewCellsManager::ExportColor(Exporter *exporter,
1347                                                                         ViewCell *vc) const
1348{
1349        // TODO
1350}
1351
1352
1353void KdViewCellsManager::ExportVcGeometry(Exporter *exporter,
1354                                                                                  ViewCell *vc) const
1355{
1356        KdViewCell *kdVc = dynamic_cast<KdViewCell *>(vc);
1357        vector<KdLeaf *>::const_iterator it, it_end = kdVc->mLeaves.end();
1358
1359        for (it = kdVc->mLeaves.begin(); it != it_end; ++ it)
1360                exporter->ExportBox(mKdTree->GetBox(*it));
1361}
1362
1363
1364int KdViewCellsManager::GetType() const
1365{
1366        return ViewCellsManager::KD;
1367}
1368
1369
1370
1371KdNode *KdViewCellsManager::GetNodeForPvs(KdLeaf *leaf)
1372{
1373        KdNode *node = leaf;
1374
1375        while (node->mParent && node->mDepth > mKdPvsDepth)
1376                node = node->mParent;
1377        return node;
1378}
1379
1380int KdViewCellsManager::CastLineSegment(const Vector3 &origin,
1381                                                                                const Vector3 &termination,
1382                                                                                ViewCellContainer &viewcells)
1383{
1384        return mKdTree->CastLineSegment(origin, termination, viewcells);
1385}
1386
1387
1388void KdViewCellsManager::CreateMesh(ViewCell *vc)
1389{
1390}
1391
1392/**********************************************************************/
1393/*                   VspKdViewCellsManager implementation             */
1394/**********************************************************************/
1395
1396
1397VspKdViewCellsManager::VspKdViewCellsManager(VspKdTree *vspKdTree,
1398                                                                                         int constructionSamples):
1399ViewCellsManager(constructionSamples),
1400mVspKdTree(vspKdTree)
1401{
1402        mVspKdTree->SetViewCellsManager(this);
1403}
1404
1405float VspKdViewCellsManager::GetProbability(ViewCell *viewCell)
1406{
1407        // volume or area substitutes for view point probability
1408#if 0
1409        return GetArea(viewCell) / GetViewSpaceBox().SurfaceArea();
1410#else
1411        return GetArea(viewCell) / GetAccVcArea();
1412#endif
1413}
1414
1415
1416float VspKdViewCellsManager::GetRendercost(ViewCell *viewCell, float objRendercost) const
1417{
1418        return viewCell->GetPvs().GetSize() * objRendercost;
1419}
1420
1421
1422void VspKdViewCellsManager::CollectViewCells()
1423{
1424        mVspKdTree->CollectViewCells(mViewCells);
1425}
1426
1427int VspKdViewCellsManager::Construct(const ObjectContainer &objects,
1428                                                                         const VssRayContainer &rays)
1429{
1430        // if view cells already constructed
1431        if (ViewCellsConstructed())
1432                return 0;
1433
1434        VssRayContainer constructionRays;
1435        VssRayContainer savedRays;
1436
1437        GetRaySets(rays,
1438                           mConstructionSamples,
1439                           constructionRays,
1440                           &savedRays);
1441
1442        Debug << "constructing vsp kd tree using "
1443                  << (int)constructionRays.size() << " samples" << endl;
1444
1445        mVspKdTree->Construct(constructionRays, &mSceneBox);
1446        Debug << mVspKdTree->GetStatistics() << endl;
1447
1448        // export leaf building blocks
1449        ExportLeaves(objects, rays);
1450
1451        // finally merge kd leaf building blocks to view cells
1452        const int merged = mVspKdTree->MergeViewCells(rays);
1453
1454        // collapse siblings belonging to the same view cell
1455        mVspKdTree->RefineViewCells(rays);
1456
1457                // collapse siblings belonging to the same view cell
1458        mVspKdTree->CollapseTree();
1459
1460        // evaluale view cell stats
1461        ResetViewCells();
1462
1463        Debug << "\nView cells after construction:\n" << mViewCellsStats << endl;
1464
1465        long startTime = GetTime();
1466        // recast rest of rays
1467        ComputeSampleContributions(savedRays);
1468
1469        Debug << "Computed remaining ray contribution in " << TimeDiff(startTime, GetTime()) * 1e-3
1470                  << " secs" << endl;
1471
1472        return merged;
1473}
1474
1475bool VspKdViewCellsManager::ViewCellsConstructed() const
1476{
1477        return mVspKdTree->GetRoot() != NULL;
1478}
1479
1480
1481ViewCell *VspKdViewCellsManager::GenerateViewCell(Mesh *mesh) const
1482{
1483        return new VspKdViewCell(mesh);
1484}
1485
1486int VspKdViewCellsManager::PostProcess(const ObjectContainer &objects,
1487                                                                           const VssRayContainer &rays)
1488{
1489        if (!ViewCellsConstructed())
1490                return 0;
1491
1492        // recalculate stats
1493        EvaluateViewCellsStats();
1494
1495        return 0;
1496}
1497
1498
1499void VspKdViewCellsManager::ExportLeaves(const ObjectContainer &objects,
1500                                                                                 const VssRayContainer &sampleRays)
1501{
1502        if (!ViewCellsConstructed())
1503                return;
1504
1505        //-- export leaf building blocks
1506        Exporter *exporter = Exporter::GetExporter("vspkdtree.x3d");
1507        if (!exporter)
1508                return;
1509
1510        //exporter->SetWireframe();
1511        //exporter->ExportVspKdTree(*mVspKdTree, mVspKdTree->GetStatistics().maxPvsSize);
1512        exporter->ExportVspKdTree(*mVspKdTree);
1513
1514        if (mExportGeometry)
1515                exporter->ExportGeometry(objects);
1516
1517        if (mExportRays)
1518        {
1519                const float prob = (float)mVisualizationSamples
1520                        / ((float)sampleRays.size() + Limits::Small);
1521
1522                exporter->SetWireframe();
1523
1524                //-- collect uniformly distributed rays
1525                VssRayContainer rays;
1526
1527                for (int i = 0; i < sampleRays.size(); ++ i)
1528                {
1529                        if (RandomValue(0,1) < prob)
1530                                rays.push_back(sampleRays[i]);
1531                }
1532                exporter->ExportRays(rays, RgbColor(1, 0, 0));
1533        }
1534
1535        delete exporter;
1536}
1537
1538void VspKdViewCellsManager::Visualize(const ObjectContainer &objects,
1539                                                                          const VssRayContainer &sampleRays)
1540{
1541        if (!ViewCellsConstructed())
1542                return;
1543
1544        //-- export single view cells
1545        for (int i = 0; i < 10; ++ i)
1546        {
1547                char s[64];
1548                sprintf(s, "vsp_viewcell%04d.x3d", i);
1549                Exporter *exporter = Exporter::GetExporter(s);
1550                const int idx =
1551                        (int)RandomValue(0.0, (Real)((int)mViewCells.size() - 1));
1552
1553                VspKdViewCell *vc = dynamic_cast<VspKdViewCell *>(mViewCells[idx]);
1554
1555                cout << "Output view cell " << i << " with pvs size " << vc->GetPvs().GetSize() << endl;
1556                Debug << "Output view cell " << i << " with pvs size " << vc->GetPvs().GetSize() << endl;
1557                //-- export geometry
1558                Material m;
1559                m.mDiffuseColor = RgbColor(0, 1, 1);
1560
1561                exporter->SetForcedMaterial(m);
1562                exporter->SetWireframe();
1563
1564                ExportVcGeometry(exporter, vc);
1565
1566                //-- export stored rays
1567                if (mExportRays)
1568                {
1569                        vector<VspKdLeaf *>::const_iterator it,
1570                                it_end = vc->mLeaves.end();
1571
1572                        for (it = vc->mLeaves.begin(); it != it_end; ++ it)
1573                        {
1574                                VspKdLeaf *leaf = *it;
1575                                AxisAlignedBox3 box = mVspKdTree->GetBBox(leaf);
1576
1577                                VssRayContainer vssRays;
1578
1579                                VssRayContainer castRays;
1580                                VssRayContainer initRays;
1581
1582                                leaf->GetRays(vssRays);
1583
1584                                VssRayContainer::const_iterator it, it_end = vssRays.end();
1585                                const float prop = 200.0f / (float)vssRays.size();
1586
1587                                for (it = vssRays.begin(); it != it_end; ++ it)
1588                                {
1589                                        if (Random(1) < prop)
1590                                                if ((*it)->mTerminationObject == NULL)
1591                                                        castRays.push_back(*it);
1592                                                else
1593                                                        initRays.push_back(*it);
1594                                }
1595
1596                                exporter->ExportRays(castRays, RgbColor(1, 0, 0));
1597                                exporter->ExportRays(initRays, RgbColor(0, 1, 0));
1598                        }
1599                }
1600
1601                //-- output PVS of view cell
1602                m.mDiffuseColor = RgbColor(1, 0, 0);
1603                exporter->SetForcedMaterial(m);
1604
1605                Intersectable::NewMail();
1606
1607                ObjectPvsMap::const_iterator it,
1608                        it_end = vc->GetPvs().mEntries.end();
1609
1610                exporter->SetFilled();
1611
1612                for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it)
1613                {
1614                        Intersectable *intersect = (*it).first;
1615
1616                        if (!intersect->Mailed())
1617                        {
1618                                Material m = RandomMaterial();
1619                                exporter->SetForcedMaterial(m);
1620
1621                                exporter->ExportIntersectable(intersect);
1622                                intersect->Mail();
1623                        }
1624                }
1625
1626                delete exporter;
1627        }
1628
1629        //-- export final view cells
1630        Exporter *exporter = Exporter::GetExporter("vspkdtree_merged.x3d");
1631
1632        //if (exportGeometry) exporter->SetWireframe();
1633        //else exporter->SetFilled();
1634
1635        ExportViewCellsForViz(exporter);
1636
1637        if (mExportGeometry)
1638        {
1639                exporter->SetFilled();
1640                exporter->ExportGeometry(objects);
1641        }
1642
1643        if (mExportRays)
1644        {
1645                const float prob = (float)mVisualizationSamples
1646                        / ((float)sampleRays.size() + Limits::Small);
1647
1648                exporter->SetWireframe();
1649
1650                VssRayContainer rays;
1651
1652                for (int i = 0; i < sampleRays.size(); ++ i)
1653                {
1654                  if (RandomValue(0,1) < prob)
1655                        rays.push_back(sampleRays[i]);
1656                }
1657                exporter->ExportRays(rays, RgbColor(1, 0, 0));
1658        }
1659
1660        delete exporter;
1661}
1662
1663int VspKdViewCellsManager::GetType() const
1664{
1665        return VSP_KD;
1666}
1667
1668
1669int VspKdViewCellsManager::CastLineSegment(const Vector3 &origin,
1670                                                                                   const Vector3 &termination,
1671                                                                                   ViewCellContainer &viewcells)
1672{
1673        return mVspKdTree->CastLineSegment(origin, termination, viewcells);
1674}
1675
1676
1677void VspKdViewCellsManager::ExportColor(Exporter *exporter,
1678                                                                                ViewCell *vc) const
1679{
1680        if (mColorCode == 0) // Random color
1681                return;
1682
1683        float importance = 0;
1684
1685        switch (mColorCode)
1686        {
1687        case 1: // pvs
1688                {
1689                        importance = (float)vc->GetPvs().GetSize() /
1690                                (float)mViewCellsStats.maxPvs;
1691                }
1692                break;
1693        case 2: // merges
1694                {
1695            VspKdViewCell *vspKdVc = dynamic_cast<VspKdViewCell *>(vc);
1696
1697                        importance = (float)vspKdVc->mLeaves.size() /
1698                                (float)mViewCellsStats.maxLeaves;
1699                }
1700                break;
1701        case 3: // merged tree depth difference
1702                {
1703                        //importance = (float)GetMaxTreeDiff(vc) /
1704                        //      (float)(mVspBspTree->GetStatistics().maxDepth * 2);
1705                }
1706                break;
1707        default:
1708                break;
1709        }
1710
1711        Material m;
1712        m.mDiffuseColor.b = 1.0f;
1713        m.mDiffuseColor.r = importance;
1714        m.mDiffuseColor.g = 1.0f - m.mDiffuseColor.r;
1715        //Debug << "importance: " << importance << endl;
1716        exporter->SetForcedMaterial(m);
1717}
1718
1719
1720void VspKdViewCellsManager::ExportVcGeometry(Exporter *exporter,
1721                                                                                   ViewCell *vc) const
1722{
1723        VspKdViewCell *kdVc = dynamic_cast<VspKdViewCell *>(vc);
1724        vector<VspKdLeaf *>::const_iterator it, it_end = kdVc->mLeaves.end();
1725
1726        Mesh m;
1727        for (it = kdVc->mLeaves.begin(); it != it_end; ++ it)
1728        {
1729                mVspKdTree->GetBBox(*it).AddBoxToMesh(&m);
1730        }
1731
1732        exporter->ExportMesh(&m);
1733}
1734
1735
1736void VspKdViewCellsManager::CreateMesh(ViewCell *vc)
1737{
1738}
1739
1740/**************************************************************************/
1741/*                   VspBspViewCellsManager implementation                */
1742/**************************************************************************/
1743
1744
1745VspBspViewCellsManager::VspBspViewCellsManager(VspBspTree *vspBspTree,
1746                                                                                           int constructionSamples):
1747ViewCellsManager(constructionSamples),
1748mVspBspTree(vspBspTree)
1749{
1750        mVspBspTree->SetViewCellsManager(this);
1751}
1752
1753
1754VspBspViewCellsManager::~VspBspViewCellsManager()
1755{
1756}
1757
1758
1759float VspBspViewCellsManager::GetProbability(ViewCell *viewCell)
1760{
1761#if 0
1762        return GetArea(viewCell) / GetViewSpaceBox().SurfaceArea();
1763#else
1764        return GetArea(viewCell) / GetAccVcArea();
1765#endif
1766}
1767
1768
1769void VspBspViewCellsManager::CollectViewCells()
1770{
1771        mVspBspTree->CollectViewCells(mViewCells);
1772}
1773
1774
1775float VspBspViewCellsManager::GetRendercost(ViewCell *viewCell,
1776                                                                                        float objRendercost) const
1777{
1778        return viewCell->GetPvs().GetSize() * objRendercost;
1779}
1780
1781
1782bool VspBspViewCellsManager::ViewCellsConstructed() const
1783{
1784        return mVspBspTree->GetRoot() != NULL;
1785}
1786
1787
1788ViewCell *VspBspViewCellsManager::GenerateViewCell(Mesh *mesh) const
1789{
1790        return new BspViewCell(mesh);
1791}
1792
1793int VspBspViewCellsManager::Construct(const ObjectContainer &objects,
1794                                                                          const VssRayContainer &rays)
1795{
1796        // if view cells were already constructed
1797        if (ViewCellsConstructed())
1798                return 0;
1799
1800        Debug << "Constructing bsp view cells" << endl;
1801
1802        int sampleContributions = 0;
1803
1804        VssRayContainer sampleRays;
1805
1806        int limit = min (mConstructionSamples, (int)rays.size());
1807
1808        VssRayContainer constructionRays;
1809        VssRayContainer savedRays;
1810
1811        GetRaySets(rays, mConstructionSamples, constructionRays, &savedRays);
1812
1813        Debug << "construction rays: " << (int)constructionRays.size() << endl;
1814        Debug << "saved rays: " << (int)savedRays.size() << endl;
1815
1816        mVspBspTree->Construct(constructionRays, &mSceneBox);
1817
1818        Debug << mVspBspTree->GetStatistics() << endl;
1819
1820        // collapse invalid regions
1821        cout << "collapsing invalid tree regions ... ";
1822        long startTime = GetTime();
1823        int collapsedLeaves = mVspBspTree->CollapseTree();
1824        Debug << "collapsed in " << TimeDiff(startTime, GetTime()) * 1e-3 << " seconds" << endl;
1825    cout << "finished" << endl;
1826
1827        cout << "reseting view cell stats ... ";
1828        ResetViewCells();
1829        cout << "finished" << endl;
1830
1831        Debug << "\nView cells after construction:\n" << mViewCellsStats << endl;
1832
1833        if (1) // export initial view cells
1834        {
1835                cout << "exporting initial view cells (=leaves) ... ";
1836                Exporter *exporter = Exporter::GetExporter("view_cells.x3d");
1837
1838                if (exporter)
1839                {
1840                        //exporter->SetWireframe();
1841                        exporter->SetFilled();
1842                        ExportViewCellsForViz(exporter);
1843
1844                        if (0 && mExportRays)
1845                                exporter->ExportRays(rays, RgbColor(1, 1, 1));
1846
1847                        if (mExportGeometry)
1848                                exporter->ExportGeometry(objects);
1849
1850                        delete exporter;
1851                }
1852                cout << "finished" << endl;
1853        }
1854
1855        startTime = GetTime();
1856
1857        // reset view cells and stats
1858        ResetViewCells();
1859
1860        cout << "Computing remaining ray contributions ... ";
1861        // recast rest of rays
1862        ComputeSampleContributions(savedRays);
1863        cout << "finished" << endl;
1864
1865        Debug << "Computed remaining ray contribution in " << TimeDiff(startTime, GetTime()) * 1e-3
1866                  << " secs" << endl;
1867
1868        cout << "construction finished" << endl;
1869
1870        return sampleContributions;
1871}
1872
1873
1874void VspBspViewCellsManager::MergeViewCells(const VssRayContainer &rays,
1875                                                                                        const ObjectContainer &objects)
1876{
1877        //-- post processing of bsp view cells
1878    int vcSize = 0;
1879        int pvsSize = 0;
1880
1881        mRenderer->RenderScene();
1882        SimulationStatistics ss;
1883        dynamic_cast<RenderSimulator *>(mRenderer)->GetStatistics(ss);
1884    Debug << ss << endl;
1885
1886        //-- merge or subdivide view cells
1887        int merged = 0;
1888
1889        cout << "starting merge using " << mPostProcessSamples << " samples ... ";
1890        long startTime = GetTime();
1891
1892        // TODO: should be done BEFORE the ray casting
1893        merged = mVspBspTree->MergeViewCells(rays);
1894
1895        //-- stats and visualizations
1896        cout << "finished" << endl;
1897        cout << "merged " << merged << " view cells in "
1898                 << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl;
1899
1900        Debug << "Postprocessing: Merged " << merged << " view cells in "
1901                  << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl << endl;
1902
1903        cout << "reseting view cell stats ... ";
1904        ResetViewCells();
1905        cout << "finished" << endl;
1906
1907        //BspLeaf::NewMail();
1908        if (1) // export merged view cells
1909        {
1910                Exporter *exporter = Exporter::GetExporter("merged_view_cells.x3d");
1911                Debug << "\nView cells after merge:\n" << mViewCellsStats << endl;
1912
1913                cout << "exporting view cells after merge ... ";
1914
1915                if (exporter)
1916                {
1917                        //exporter->SetWireframe();
1918                        exporter->SetFilled();
1919                        ExportViewCellsForViz(exporter);
1920
1921                        if (mExportGeometry)
1922                        {
1923                                Material m;
1924                                m.mDiffuseColor = RgbColor(0, 1, 0);
1925                                exporter->SetForcedMaterial(m);
1926                                exporter->SetFilled();
1927
1928                                exporter->ExportGeometry(objects);
1929                        }
1930
1931                        delete exporter;
1932                }
1933                cout << "finished" << endl;
1934        }
1935}
1936
1937
1938void VspBspViewCellsManager::RefineViewCells(const VssRayContainer &rays)
1939{
1940        Debug << "render time before refine:" << endl;
1941        mRenderer->RenderScene();
1942        SimulationStatistics ss;
1943        dynamic_cast<RenderSimulator *>(mRenderer)->GetStatistics(ss);
1944    Debug << ss << endl;
1945
1946        cout << "Refining the merged view cells ... ";
1947        long startTime = GetTime();
1948
1949        // refining the merged view cells
1950        const int refined = mVspBspTree->RefineViewCells(rays);
1951
1952        //-- stats and visualizations
1953        cout << "finished" << endl;
1954        cout << "refined " << refined << " view cells in "
1955                 << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl;
1956
1957        Debug << "Postprocessing: refined " << refined << " view cells in "
1958                  << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl << endl;
1959}
1960
1961
1962int VspBspViewCellsManager::PostProcess(const ObjectContainer &objects,
1963                                                                                const VssRayContainer &rays)
1964{
1965        if (!ViewCellsConstructed())
1966        {
1967                Debug << "postprocess error: no view cells constructed" << endl;
1968                return 0;
1969        }
1970
1971        EvaluateViewCellsStats();
1972
1973        // view cells already finished post processing step
1974        if (mViewCellsFinished)
1975                return 0;
1976
1977        VssRayContainer postProcessRays;
1978        GetRaySets(rays, mPostProcessSamples, postProcessRays);
1979
1980        Debug << "post processing using " << (int)postProcessRays.size() << " samples" << endl;
1981       
1982        Debug << "\nview cell partition after sampling:\n" << mViewCellsStats << endl << endl;
1983
1984
1985        //-- merge the individual view cells: Should be done here because it makes
1986        MergeViewCells(postProcessRays, objects);
1987        //-- refines the merged view cells
1988        RefineViewCells(postProcessRays);
1989        // collapse sibling leaves that share the same view cell
1990        mVspBspTree->CollapseTree();
1991
1992        ResetViewCells();
1993
1994        // real meshes are only contructed only at this stage
1995        CreateViewCellMeshes();
1996
1997        // write view cells to disc
1998        if (mExportViewCells)
1999        {
2000                char buff[100];
2001                environment->GetStringValue("ViewCells.filename", buff);
2002                string vcFilename(buff);
2003
2004                ExportViewCells(buff);
2005        }
2006
2007        return 0;
2008}
2009
2010
2011int VspBspViewCellsManager::GetType() const
2012{
2013        return VSP_BSP;
2014}
2015
2016
2017bool VspBspViewCellsManager::GetViewPoint(Vector3 &viewPoint) const
2018{
2019        if (!ViewCellsConstructed())
2020                return ViewCellsManager::GetViewPoint(viewPoint);
2021
2022        // TODO: set reasonable limit
2023        const int limit = 20;
2024
2025        for (int i = 0; i < limit; ++ i)
2026        {
2027                viewPoint = mSceneBox.GetRandomPoint();
2028                if (mVspBspTree->ViewPointValid(viewPoint))
2029                {
2030                        return true;
2031                }
2032        }
2033        Debug << "failed to find valid view point, taking " << viewPoint << endl;
2034        return false;
2035}
2036
2037
2038bool VspBspViewCellsManager::ViewPointValid(const Vector3 &viewPoint) const
2039{
2040        return mSceneBox.IsInside(viewPoint) &&
2041                   mVspBspTree->ViewPointValid(viewPoint);
2042}
2043
2044
2045void VspBspViewCellsManager::Visualize(const ObjectContainer &objects,
2046                                                                           const VssRayContainer &sampleRays)
2047{
2048        if (!ViewCellsConstructed())
2049                return;
2050
2051        VssRayContainer visRays;
2052        GetRaySets(sampleRays, mVisualizationSamples, visRays);
2053
2054        if (1) // export view cells
2055        {
2056                cout << "exporting view cells after post process ... ";
2057                Exporter *exporter = Exporter::GetExporter("final_view_cells.x3d");
2058
2059                if (exporter)
2060                {
2061                        if (mExportGeometry)
2062                                exporter->ExportGeometry(objects);
2063
2064                        // export rays
2065                        if (mExportRays)
2066                        {
2067                                exporter->ExportRays(visRays, RgbColor(0, 1, 0));
2068                        }
2069
2070                        ExportViewCellsForViz(exporter);
2071                        delete exporter;
2072                }
2073
2074                cout << "finished" << endl;
2075        }
2076
2077        //-- visualization of the BSP splits
2078        bool exportSplits = false;
2079        environment->GetBoolValue("VspBspTree.Visualization.exportSplits", exportSplits);
2080
2081        if (exportSplits)
2082        {
2083                cout << "exporting splits ... ";
2084                ExportSplits(objects, visRays);
2085                cout << "finished" << endl;
2086        }
2087
2088        // export single view cells
2089        ExportBspPvs(objects, visRays);
2090}
2091
2092
2093void VspBspViewCellsManager::ExportSplits(const ObjectContainer &objects,
2094                                                                                  const VssRayContainer &rays)
2095{
2096        Exporter *exporter = Exporter::GetExporter("bsp_splits.x3d");
2097
2098        if (exporter)
2099        {
2100                Material m;
2101                m.mDiffuseColor = RgbColor(1, 0, 0);
2102                exporter->SetForcedMaterial(m);
2103                exporter->SetWireframe();
2104
2105                exporter->ExportBspSplits(*mVspBspTree, true);
2106
2107                // take forced material, else big scenes cannot be viewed
2108                m.mDiffuseColor = RgbColor(0, 1, 0);
2109                exporter->SetForcedMaterial(m);
2110                exporter->SetFilled();
2111
2112                exporter->ResetForcedMaterial();
2113
2114                // export rays
2115                if (mExportRays)
2116                        exporter->ExportRays(rays, RgbColor(1, 1, 0));
2117
2118                if (mExportGeometry)
2119                        exporter->ExportGeometry(objects);
2120
2121                delete exporter;
2122        }
2123}
2124
2125
2126void VspBspViewCellsManager::ExportBspPvs(const ObjectContainer &objects,
2127                                                                                  const VssRayContainer &rays)
2128{
2129        const int leafOut = 10;
2130
2131        ViewCell::NewMail();
2132
2133        cout << "visualization using " << mVisualizationSamples << " samples" << endl;
2134        Debug << "\nOutput view cells: " << endl;
2135
2136        // sort view cells to visualize the largest view cells
2137#if 0
2138        stable_sort(mViewCells.begin(), mViewCells.end(), vc_gt);
2139#endif
2140        int limit = min(leafOut, (int)mViewCells.size());
2141
2142#if 1
2143        //-- some rays for output
2144        vector<BspRay *> bspRays;
2145        mVspBspTree->ConstructBspRays(bspRays, rays);
2146
2147        const int raysOut = min((int)bspRays.size(), mVisualizationSamples);
2148#endif
2149
2150        for (int i = 0; i < limit; ++ i)
2151        {
2152                cout << "creating output for view cell " << i << " ... ";
2153
2154                VssRayContainer vcRays;
2155                Intersectable::NewMail();
2156#if 0
2157                BspViewCell *vc = dynamic_cast<BspViewCell *>(mViewCells[i]);
2158#else
2159                BspViewCell *vc = dynamic_cast<BspViewCell *>
2160                        (mViewCells[Random((int)mViewCells.size())]);
2161#endif
2162
2163#if 1
2164                // check whether we can add the current ray to the output rays
2165                for (int k = 0; k < raysOut; ++ k)
2166                {
2167                        BspRay *ray = bspRays[k];
2168                        for     (int j = 0; j < (int)ray->intersections.size(); ++ j)
2169                        {
2170                                BspLeaf *leaf = ray->intersections[j].mLeaf;
2171                                if (vc == leaf->GetViewCell())
2172                                        vcRays.push_back(ray->vssRay);
2173                        }
2174                }
2175#endif
2176                //bspLeaves[j]->Mail();
2177                char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i);
2178                Exporter *exporter = Exporter::GetExporter(s);
2179                exporter->SetWireframe();
2180
2181                Material m;//= RandomMaterial();
2182                m.mDiffuseColor = RgbColor(0, 1, 0);
2183                exporter->SetForcedMaterial(m);
2184
2185                ExportVcGeometry(exporter, vc);
2186
2187
2188                Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize()
2189                          << ", piercing rays=" << (int)vcRays.size()
2190                          << ", leaves=" << (int)vc->mLeaves.size() << endl;
2191
2192                //-- export rays piercing this view cell
2193#if 1
2194                exporter->ExportRays(vcRays, RgbColor(1, 1, 1));
2195#endif
2196#if 0
2197                vector<BspLeaf *>::const_iterator lit, lit_end = vc->mLeaves.end();
2198
2199                for (lit = vc->mLeaves.begin(); lit != lit_end; ++ lit)
2200                        exporter->ExportRays((*lit)->mVssRays);
2201#endif
2202                m.mDiffuseColor = RgbColor(1, 0, 0);
2203                exporter->SetForcedMaterial(m);
2204
2205                ObjectPvsMap::const_iterator it,
2206                        it_end = vc->GetPvs().mEntries.end();
2207
2208                exporter->SetFilled();
2209
2210                // output PVS of view cell
2211                for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it)
2212                {
2213                        Intersectable *intersect = (*it).first;
2214
2215                        if (!intersect->Mailed())
2216                        {
2217                                Material m = RandomMaterial();
2218                                exporter->SetForcedMaterial(m);
2219
2220                                exporter->ExportIntersectable(intersect);
2221                                intersect->Mail();
2222                        }
2223                }
2224
2225                DEL_PTR(exporter);
2226                cout << "finished" << endl;
2227        }
2228
2229#if 1
2230        CLEAR_CONTAINER(bspRays);
2231#endif
2232        Debug << endl;
2233}
2234
2235
2236int VspBspViewCellsManager::CastLineSegment(const Vector3 &origin,
2237                                                                                        const Vector3 &termination,
2238                                                                                        ViewCellContainer &viewcells)
2239{
2240        return mVspBspTree->CastLineSegment(origin, termination, viewcells);
2241}
2242
2243
2244void VspBspViewCellsManager::ExportColor(Exporter *exporter,
2245                                                                                 ViewCell *vc) const
2246{
2247        if (mColorCode == 0) // Random color
2248                return;
2249
2250        float importance = 0;
2251
2252        switch (mColorCode)
2253        {
2254        case 1: // pvs
2255                {
2256                        importance = (float)vc->GetPvs().GetSize() /
2257                                (float)mViewCellsStats.maxPvs;
2258                }
2259                break;
2260        case 2: // merges
2261                {
2262            BspViewCell *bspVc = dynamic_cast<BspViewCell *>(vc);
2263
2264                        importance = (float)bspVc->mLeaves.size() /
2265                                (float)mViewCellsStats.maxLeaves;
2266                }
2267                break;
2268        case 3: // merge tree differene
2269                {
2270                        importance = (float)GetMaxTreeDiff(vc) /
2271                                (float)(mVspBspTree->GetStatistics().maxDepth * 2);
2272                }
2273                break;
2274        default:
2275                break;
2276        }
2277
2278        Material m;
2279        m.mDiffuseColor.b = 1.0f;
2280        m.mDiffuseColor.r = importance;
2281        m.mDiffuseColor.g = 1.0f - m.mDiffuseColor.r;
2282        //Debug << "importance: " << importance << endl;
2283        exporter->SetForcedMaterial(m);
2284}
2285
2286
2287void VspBspViewCellsManager::ExportVcGeometry(Exporter *exporter,
2288                                                                                          ViewCell *vc) const
2289{
2290#if 1
2291    if (vc->GetMesh())
2292        {
2293                exporter->ExportMesh(vc->GetMesh());
2294                return;
2295        }
2296
2297        BspNodeGeometry geom;
2298        mVspBspTree->
2299                ConstructGeometry(dynamic_cast<BspViewCell *>(vc), geom);
2300        exporter->ExportPolygons(geom.mPolys);
2301#else
2302
2303        Material m2;
2304        m2.mDiffuseColor.b = 0.3f + Random(0.7f);
2305        m2.mDiffuseColor.r = 0.0f;//0.3f + Random(0.7f);
2306        m2.mDiffuseColor.g = 0.3f + Random(0.7f);
2307        Material m;
2308        m.mDiffuseColor.b = 0.0f;
2309        m.mDiffuseColor.r = 1.0f;
2310        m.mDiffuseColor.g = 0.0f;
2311
2312        BspViewCell *bspVc = dynamic_cast<BspViewCell *>(vc);
2313        vector<BspLeaf *>::const_iterator it, it_end = bspVc->mLeaves.end();
2314
2315        for (it = bspVc->mLeaves.begin(); it != it_end; ++ it)
2316        {
2317                if ((*it)->Mailed())
2318                        exporter->SetForcedMaterial(m);
2319                else
2320                        exporter->SetForcedMaterial(m2);
2321                        //exporter->ResetForcedMaterial();
2322                BspNodeGeometry geom;
2323                mVspBspTree->ConstructGeometry(*it, geom);
2324                exporter->ExportPolygons(geom.mPolys);
2325        }
2326#endif
2327}
2328
2329
2330int VspBspViewCellsManager::GetMaxTreeDiff(ViewCell *vc) const
2331{
2332        BspViewCell *bspVc = dynamic_cast<BspViewCell *>(vc);
2333
2334        int maxDist = 0;
2335        // compute max height difference
2336        for (int i = 0; i < (int)bspVc->mLeaves.size(); ++ i)
2337                for (int j = 0; j < (int)bspVc->mLeaves.size(); ++ j)
2338        {
2339                BspLeaf *leaf = bspVc->mLeaves[i];
2340
2341                if (i != j)
2342                {
2343                        BspLeaf *leaf2 = bspVc->mLeaves[j];
2344                        int dist = mVspBspTree->TreeDistance(leaf, leaf2);
2345                        if (dist > maxDist)
2346                                maxDist = dist;
2347                }
2348        }
2349        return maxDist;
2350}
2351
2352
2353ViewCell *VspBspViewCellsManager::GetViewCell(const Vector3 &point)
2354{
2355        if (!mVspBspTree)
2356                return NULL;
2357        return mVspBspTree->GetViewCell(point);
2358}
2359
2360
2361void VspBspViewCellsManager::CreateMesh(ViewCell *vc)
2362{
2363        BspNodeGeometry geom;
2364        BspViewCell *bspVc = dynamic_cast<BspViewCell *>(vc);
2365        mVspBspTree->ConstructGeometry(bspVc, geom);
2366
2367        Mesh *mesh = new Mesh();
2368        geom.AddToMesh(*mesh);
2369        vc->SetMesh(mesh);
2370        mMeshContainer.push_back(mesh);
2371}
2372
2373
2374bool VspBspViewCellsManager::LoadViewCells(const string filename, ObjectContainer *objects)
2375{
2376        ViewCellsParser parser;
2377       
2378        DEL_PTR(mVspBspTree);
2379        mVspBspTree = new VspBspTree();
2380       
2381        bool success = parser.ParseFile(filename, mVspBspTree, this, objects);
2382        mVspBspTree->RepairViewCellsLeafLists();
2383        mVspBspTree->mBox = GetViewSpaceBox();
2384        ResetViewCells();
2385        CreateViewCellMeshes();
2386
2387        Debug << (int)mViewCells.size() << " view cells loaded" << endl;
2388
2389        mViewCellsFinished = true;
2390
2391        return success;
2392}
2393
2394
2395inline bool ilt(Intersectable *obj1, Intersectable *obj2)
2396{
2397        return obj1->mId < obj2->mId;
2398}
2399
2400
2401bool VspBspViewCellsManager::ExportViewCells(const string filename)
2402{
2403        cout << "exporting view cells to xml ... ";
2404        std::ofstream stream;
2405
2406        // for output we need unique ids
2407        CreateUniqueViewCellIds();
2408
2409        stream.open(filename.c_str());
2410        stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"<<endl;
2411        stream << "<Visibility_Solution>" << endl;
2412       
2413        //-- load the view cells itself, i.e., the ids and the pvs
2414        stream << "<ViewCells>" << endl;
2415        ViewCellContainer::const_iterator it, it_end = mViewCells.end();
2416        for (it = mViewCells.begin(); it != it_end; ++ it)
2417                ExportViewCell(*it, stream);
2418   
2419        stream << "</ViewCells>" << endl;
2420       
2421        //-- load the hierarchy
2422        stream << "<BspTree>" << endl;
2423        mVspBspTree->Export(stream);
2424        stream << endl << "</BspTree>" << endl;
2425       
2426        stream << "</Visibility_Solution>" << endl;
2427        stream.close();
2428
2429        cout << "finished" << endl;
2430
2431        return true;
2432}
Note: See TracBrowser for help on using the repository browser.