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

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