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

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