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

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