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

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