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

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