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

Revision 466, 40.3 KB checked in by bittner, 19 years ago (diff)

changed the viewcellsmanager interface to use vssrays - some functionality like the bsp merging is now restricted

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
14
15ViewCellsManager::ViewCellsManager():
16mRenderSimulator(NULL),
17mConstructionSamples(0),
18mPostProcessSamples(0),
19mVisualizationSamples(0)
20{
21        // post processing stuff
22        environment->GetIntValue("ViewCells.PostProcessing.minPvsDif", mMinPvsDif);
23        environment->GetIntValue("ViewCells.PostProcessing.minPvs", mMinPvs);
24        environment->GetIntValue("ViewCells.PostProcessing.maxPvs", mMaxPvs);
25}
26
27ViewCellsManager::ViewCellsManager(int constructionSamples):
28mConstructionSamples(constructionSamples),
29mRenderSimulator(NULL),
30mPostProcessSamples(0),
31mVisualizationSamples(0)
32{
33        // post processing stuff
34        environment->GetIntValue("ViewCells.PostProcessing.minPvsDif", mMinPvsDif);
35        environment->GetIntValue("ViewCells.PostProcessing.minPvs", mMinPvs);
36        environment->GetIntValue("ViewCells.PostProcessing.maxPvs", mMaxPvs);
37}
38
39ViewCellsManager::~ViewCellsManager()
40{
41        DEL_PTR(mRenderSimulator);
42}
43
44void ViewCellsManager::InitRenderSimulator()
45{
46        float objRenderCost = 0, vcOverhead = 0, moveSpeed = 0;
47
48        environment->GetFloatValue("Simulation.objRenderCost",objRenderCost);
49        environment->GetFloatValue("Simulation.vcOverhead", vcOverhead);
50        environment->GetFloatValue("Simulation.moveSpeed", moveSpeed);
51
52        mRenderSimulator->SetObjectRenderCost(objRenderCost);
53        mRenderSimulator->SetVcOverhead(vcOverhead);
54        mRenderSimulator->SetMoveSpeed(moveSpeed);
55}
56
57bool ViewCellsManager::LoadViewCells(const string filename)
58{
59        X3dParser parser;
60       
61        environment->GetFloatValue("ViewCells.height", parser.mViewCellHeight);
62       
63        bool success = parser.ParseFile(filename, *this);
64        Debug << (int)mViewCells.size() << " view cells loaded" << endl;
65
66        return success;
67}
68
69void
70ViewCellsManager::ComputeSampleContributions(const VssRayContainer &rays
71                                                                                         )
72{
73  // view cells not yet constructed
74  if (!ViewCellsConstructed())
75        return;
76 
77  VssRayContainer::const_iterator it, it_end = rays.end();
78  for (it = rays.begin(); it != it_end; ++ it) {
79        ComputeSampleContributions(*(*it));
80  }
81}
82
83void ViewCellsManager::AddViewCell(ViewCell *viewCell)
84{
85        mViewCells.push_back(viewCell);
86}
87
88void ViewCellsManager::DeriveViewCells(const ObjectContainer &objects,
89                                                                           ViewCellContainer &viewCells,
90                                                                           const int maxViewCells) const
91{
92        // maximal max viewcells
93        int limit = maxViewCells > 0 ?
94                Min((int)objects.size(), maxViewCells) : (int)objects.size();
95
96        for (int i = 0; i < limit; ++ i)
97        {
98                Intersectable *object = objects[i];
99               
100                // extract the mesh instances
101                if (object->Type() == Intersectable::MESH_INSTANCE)
102                {
103                        MeshInstance *inst = dynamic_cast<MeshInstance *>(object);
104
105                        ViewCell *viewCell = GenerateViewCell(inst->GetMesh());
106                        viewCells.push_back(viewCell);
107                }
108                //TODO: transformed meshes
109        }
110}
111
112ViewCell *ViewCellsManager::ExtrudeViewCell(const Triangle3 &baseTri,
113                                                                                        const float height) const
114{
115        // one mesh per view cell
116        Mesh *mesh = new Mesh();
117       
118        //-- construct prism
119
120        // bottom
121        mesh->mFaces.push_back(new Face(2,1,0));
122        // top
123    mesh->mFaces.push_back(new Face(3,4,5));
124        // sides
125        mesh->mFaces.push_back(new Face(1, 4, 3, 0));
126        mesh->mFaces.push_back(new Face(2, 5, 4, 1));
127        mesh->mFaces.push_back(new Face(3, 5, 2, 0));
128
129        //--- extrude new vertices for top of prism
130        Vector3 triNorm = baseTri.GetNormal();
131
132        Triangle3 topTri;       
133
134        // add base vertices and calculate top vertices
135        for (int i = 0; i < 3; ++ i)
136                mesh->mVertices.push_back(baseTri.mVertices[i]);
137       
138        // add top vertices     
139        for (int i = 0; i < 3; ++ i)
140                mesh->mVertices.push_back(baseTri.mVertices[i] + height * triNorm);
141       
142        mesh->Preprocess();
143
144        return GenerateViewCell(mesh);
145}
146
147ViewCell *ViewCellsManager::MergeViewCells(ViewCell &front, ViewCell &back) const
148{
149        // generate merged view cell
150        ViewCell *vc = GenerateViewCell();
151
152        // merge pvs
153        vc->GetPvs().Merge(front.GetPvs(), back.GetPvs());
154
155        //-- merge ray sets
156        stable_sort(front.mPiercingRays.begin(), front.mPiercingRays.end());
157        stable_sort(back.mPiercingRays.begin(), back.mPiercingRays.end());
158
159        std::merge(front.mPiercingRays.begin(), front.mPiercingRays.end(),
160                           back.mPiercingRays.begin(), back.mPiercingRays.end(),
161                           vc->mPiercingRays.begin());
162
163        return vc;
164}
165
166SimulationStatistics ViewCellsManager::SimulateRendering() const
167{
168        if (!ViewCellsConstructed() || !mRenderSimulator)
169                return SimulationStatistics();
170
171        return mRenderSimulator->SimulateRendering();
172}
173
174ViewCell *ViewCellsManager::GenerateViewCell(Mesh *mesh) const
175{
176        return new ViewCell(mesh);
177}
178
179
180void ViewCellsManager::SetVisualizationSamples(const int visSamples)
181{
182        mVisualizationSamples = visSamples;
183}
184
185void ViewCellsManager::SetConstructionSamples(const int constructionSamples)
186{
187        mConstructionSamples = constructionSamples;
188}
189
190void ViewCellsManager::SetPostProcessSamples(const int postProcessSamples)
191{
192        mPostProcessSamples = postProcessSamples;
193}
194
195int ViewCellsManager::GetVisualizationSamples() const
196{
197        return mVisualizationSamples;
198}
199
200int ViewCellsManager::GetConstructionSamples() const
201{
202        return mConstructionSamples;
203}
204
205int ViewCellsManager::GetPostProcessSamples() const
206{
207        return mPostProcessSamples;
208}
209
210/**********************************************************************/
211/*                   BspViewCellsManager implementation               */
212/**********************************************************************/
213
214BspViewCellsManager::BspViewCellsManager(BspTree *bspTree, int constructionSamples):
215ViewCellsManager(constructionSamples),
216mBspTree(bspTree)
217{
218   mRenderSimulator = new BspRenderSimulator(bspTree);
219   InitRenderSimulator();
220}
221
222
223BspViewCellsManager::~BspViewCellsManager()
224{
225        ViewCellContainer vc;
226        mBspTree->CollectViewCells(vc);
227
228        CLEAR_CONTAINER(vc);
229}
230
231bool BspViewCellsManager::ViewCellsConstructed() const
232{
233        return mBspTree->GetRoot() != NULL;
234}
235
236ViewCell *BspViewCellsManager::GenerateViewCell(Mesh *mesh) const
237{
238        return new BspViewCell(mesh);
239}
240
241int BspViewCellsManager::Construct(const ObjectContainer &objects,
242                                                                   const VssRayContainer &rays,
243                                                                   AxisAlignedBox3 *sceneBbox)
244{
245        // if view cells were already constructed
246        if (ViewCellsConstructed())
247                return 0;
248
249        int sampleContributions = 0;
250       
251        RayContainer sampleRays;
252
253        int limit = min (mConstructionSamples, (int)rays.size());
254
255        // construct view cells using the collected samples
256        Debug << "construcing bsp view cells from "
257                  << limit << " samples " << endl;
258
259    for (int i = 0; i < limit; ++ i)
260                sampleRays.push_back(new Ray(*rays[i]));
261
262        if (mViewCells.empty()) // no view cells loaded
263                mBspTree->Construct(objects, sampleRays);
264        else
265                mBspTree->Construct(mViewCells);
266
267        Debug << mBspTree->GetStatistics() << endl;
268       
269        return sampleContributions;
270}
271
272void
273ViewCellsManager::ComputeSampleContributions(VssRay &ray)
274{
275
276  ViewCellContainer viewcells;
277 
278  CastLineSegment(ray.mOrigin,
279                                  ray.mTermination,
280                                  viewcells
281                                  );
282 
283  ViewCellContainer::const_iterator it = viewcells.begin();
284  for (; it != viewcells.end(); ++it) {         
285        ViewCell *viewcell = *it;
286       
287        // if ray not outside of view space
288        float contribution;
289        bool added =
290          viewcell->GetPvs().AddSample(ray.mTerminationObject,
291                                                                   contribution
292                                                                   );
293        if (added)
294          ray.mPvsContribution++;
295       
296        ray.mRelativePvsContribution += contribution;
297  }
298 
299}
300
301int
302BspViewCellsManager::CastLineSegment(const Vector3 &origin,
303                                                                         const Vector3 &termination,
304                                                                         ViewCellContainer &viewcells
305                                                                         )
306{
307  return mBspTree->CastLineSegment(origin, termination, viewcells);
308}
309
310int
311BspViewCellsManager::PostProcess(const ObjectContainer &objects,
312                                                                 const VssRayContainer &rays)
313{
314  if (!ViewCellsConstructed())
315        {
316                Debug << "view cells not constructed" << endl;
317                return 0;
318        }
319
320        //-- post processing of bsp view cells
321    int vcSize = 0;
322        int pvsSize = 0;
323
324        ViewCellsStatistics vcStats;
325        mBspTree->EvaluateViewCellsStats(vcStats);
326        Debug << "original view cell partition:\n" << vcStats << endl;
327               
328        if (1) // export view cells before merge
329        {
330                cout << "exporting initial view cells (=leaves) ... ";
331                Exporter *exporter = Exporter::GetExporter("view_cells.x3d");
332       
333                if (exporter)
334                {
335                        exporter->SetWireframe();
336                        exporter->ExportBspLeaves(*mBspTree, vcStats.maxPvs);
337                        //exporter->ExportBspViewCellPartition(*mBspTree, 0);
338                               
339                        if (0)
340                        {
341                                Material m;//= RandomMaterial();
342                                m.mDiffuseColor = RgbColor(0, 1, 0);
343                                exporter->SetForcedMaterial(m);
344                                exporter->SetWireframe();
345
346                                exporter->ExportGeometry(objects);
347                        }
348
349                        delete exporter;
350                }
351                cout << "finished" << endl;
352
353                //-- render simulation
354                cout << "\nevaluating bsp view cells render time before merge ... ";
355                 
356                const SimulationStatistics ss = SimulateRendering();
357                         
358                cout << " finished" << endl;
359                cout << ss << endl;
360                Debug << ss << endl;
361        }
362
363
364        cout << "starting post processing using " << mPostProcessSamples << " samples ... ";
365
366        long startTime = GetTime();
367
368        // $$JB we do not have connectivity information from the ray in the moment
369        // perhaps we could recast the rays or rember the cells traversed inside the
370        // vssray (which would on other hand create some overhead)
371        //-- merge or subdivide view cells
372        int merged = 0;
373#if 0
374
375        RayContainer::const_iterator rit, rit_end = rays.end();
376        vector<Ray::BspIntersection>::const_iterator iit;
377
378        int limit = min((int)rays.size(), mPostProcessSamples);
379
380        for (int i = 0; i < limit; ++ i)
381        { 
382                Ray *ray = rays[i];
383
384                // traverse leaves stored in the rays and compare and merge consecutive
385                // leaves (i.e., the neighbors in the tree)
386                if (ray->bspIntersections.size() < 2)
387                        continue;
388
389                iit = ray->bspIntersections.begin();
390
391                BspLeaf *previousLeaf = (*iit).mLeaf;
392                ++ iit;
393               
394                for (; iit != ray->bspIntersections.end(); ++ iit)
395                {
396                        BspLeaf *leaf = (*iit).mLeaf;
397
398                        if (ShouldMerge(leaf, previousLeaf))
399                        {                       
400                                MergeBspLeafViewCells(leaf, previousLeaf);
401
402                                ++ merged;
403                        }
404               
405                        previousLeaf = leaf;
406                }
407        }
408#endif
409        //-- stats and visualizations
410        cout << "finished" << endl;
411        cout << "merged " << merged << " view cells in "
412                 << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl;
413
414        return merged;
415}
416
417int BspViewCellsManager::GetType() const
418{
419        return BSP;
420}
421
422
423void BspViewCellsManager::Visualize(const ObjectContainer &objects,
424                                                                        const VssRayContainer &sampleRays)
425{
426  if (!ViewCellsConstructed())
427        return;
428 
429  //-- recount pvs
430  ViewCellsStatistics vcStats;
431  mBspTree->EvaluateViewCellsStats(vcStats);
432 
433  if (1) // export view cells
434        {
435          cout << "exporting view cells after merge ... ";
436          Exporter *exporter = Exporter::GetExporter("merged_view_cells.x3d");
437         
438          if (exporter)
439                {
440                  exporter->ExportBspViewCellPartition(*mBspTree, vcStats.maxPvs);
441                  //exporter->ExportBspViewCellPartition(*mBspTree, 0);
442                  delete exporter;
443                }
444         
445          cout << "finished" << endl;
446        }       
447 
448  //-- visualization of the BSP splits
449  bool exportSplits = false;
450  environment->GetBoolValue("BspTree.Visualization.exportSplits", exportSplits);
451 
452  if (exportSplits)
453        {
454          cout << "exporting splits ... ";
455          ExportSplits(objects, sampleRays);
456          cout << "finished" << endl;
457        }
458 
459  ExportBspPvs(objects, sampleRays);
460}
461
462
463inline bool vc_gt(ViewCell *a, ViewCell *b)
464{
465        return a->GetPvs().GetSize() > b->GetPvs().GetSize();
466}
467
468void BspViewCellsManager::ExportSplits(const ObjectContainer &objects,
469                                                                           const VssRayContainer &sampleRays)
470{
471        Exporter *exporter = Exporter::GetExporter("bsp_splits.x3d");
472
473        if (exporter)
474        {       
475                Material m;
476                m.mDiffuseColor = RgbColor(1, 0, 0);
477                exporter->SetForcedMaterial(m);
478                exporter->SetWireframe();
479                exporter->ExportBspSplits(*mBspTree, true);
480
481                // take forced material, else big scenes cannot be viewed
482                m.mDiffuseColor = RgbColor(0, 1, 0);
483                exporter->SetForcedMaterial(m);
484                exporter->SetFilled();
485
486                exporter->ResetForcedMaterial();
487               
488                // export rays
489                if (0)
490                {
491                  VssRayContainer outRays;
492                 
493                  int raysSize = min((int)sampleRays.size(), mVisualizationSamples);
494                 
495                  for (int i = 0; i < raysSize; ++ i)
496                        {
497                          // only rays piercing geometry
498                          outRays.push_back(sampleRays[i]);
499                        }
500                 
501                  // export rays
502                  exporter->ExportRays(outRays, RgbColor(1, 1, 0));
503                }
504               
505                if (0)
506                  exporter->ExportGeometry(objects);
507               
508                delete exporter;
509        }
510}
511
512void BspViewCellsManager::ExportBspPvs(const ObjectContainer &objects,
513                                                                           const VssRayContainer &sampleRays)
514{
515  const int leafOut = 10;
516 
517  ViewCell::NewMail();
518 
519  //-- some rays for output
520  const int raysOut = min((int)sampleRays.size(), mVisualizationSamples);
521  Debug << "visualization using " << raysOut << " samples" << endl;
522
523  //$$ JB
524#if 0
525
526  if (1)
527        {
528          //-- some random view cells and rays for output
529          vector<BspLeaf *> bspLeaves;
530         
531          for (int i = 0; i < leafOut; ++ i)
532                bspLeaves.push_back(mBspTree->GetRandomLeaf());
533
534         
535          for (int i = 0; i < bspLeaves.size(); ++ i)
536                {
537                  BspLeaf *leaf = bspLeaves[i];
538                 
539                  RayContainer vcRays;
540                 
541                  cout << "creating output for view cell " << i << " ... ";
542                 
543                  // check whether we can add the current ray to the output rays
544                  for (int k = 0; k < raysOut; ++ k)
545                        {
546                          Ray *ray = sampleRays[k];
547                         
548                          for   (int j = 0; j < (int)ray->bspIntersections.size(); ++ j)
549                                {
550                                  BspLeaf *leaf2 = ray->bspIntersections[j].mLeaf;
551                                 
552                                  if (leaf->GetViewCell() == leaf2->GetViewCell())
553                                        {
554                                          vcRays.push_back(ray);
555                                        }
556                                }
557                        }
558                 
559                  Intersectable::NewMail();
560                 
561                  BspViewCell *vc = dynamic_cast<BspViewCell *>(leaf->GetViewCell());
562                 
563                  //bspLeaves[j]->Mail();
564                  char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i);
565                 
566                  Exporter *exporter = Exporter::GetExporter(s);
567                  exporter->SetFilled();
568
569                  exporter->SetWireframe();
570                  //exporter->SetFilled();
571                 
572                  Material m;//= RandomMaterial();
573                  m.mDiffuseColor = RgbColor(1, 1, 0);
574                  exporter->SetForcedMaterial(m);
575                 
576                  if (vc->GetMesh())
577                        exporter->ExportViewCell(vc);
578                  else
579                        {
580                          PolygonContainer vcGeom;
581                          // export view cell geometry
582                          mBspTree->ConstructGeometry(vc, vcGeom);
583                          exporter->ExportPolygons(vcGeom);
584                                CLEAR_CONTAINER(vcGeom);
585                        }
586                 
587                  Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize()
588                                << ", piercing rays=" << (int)vcRays.size() << endl;
589                 
590                  // export rays piercing this view cell
591                  exporter->ExportRays(vcRays, 1000, RgbColor(0, 1, 0));       
592                 
593                  m.mDiffuseColor = RgbColor(1, 0, 0);
594                  exporter->SetForcedMaterial(m);
595                 
596                  // exporter->SetWireframe();
597                  exporter->SetFilled();
598                 
599                  ViewCellPvsMap::iterator it, it_end = vc->GetPvs().mEntries.end();
600                  // output PVS of view cell
601                  for (it = vc->GetPvs().mEntries.begin(); it !=  it_end; ++ it)
602                        {
603                          Intersectable *intersect = (*it).first;
604                          if (!intersect->Mailed())
605                                {
606                                  exporter->ExportIntersectable(intersect);
607                                  intersect->Mail();
608                                }                       
609                        }
610                 
611                  DEL_PTR(exporter);
612                  cout << "finished" << endl;
613                }
614        }
615  else
616        {
617          ViewCellContainer viewCells;
618          RayContainer vcRays;
619         
620          mBspTree->CollectViewCells(viewCells);
621          stable_sort(viewCells.begin(), viewCells.end(), vc_gt);
622         
623          int limit = min(leafOut, (int)viewCells.size());
624         
625          for (int i = 0; i < limit; ++ i)
626                {
627                  cout << "creating output for view cell " << i << " ... ";
628                       
629            Intersectable::NewMail();
630                        BspViewCell *vc = dynamic_cast<BspViewCell *>(viewCells[i]);
631
632                        cout << "creating output for view cell " << i << " ... ";
633                        // check whether we can add the current ray to the output rays
634                        for (int k = 0; k < raysOut; ++ k)
635                        {
636                                Ray *ray = sampleRays[k];
637
638                                for     (int j = 0; j < (int)ray->bspIntersections.size(); ++ j)
639                                {
640                                        BspLeaf *leaf = ray->bspIntersections[j].mLeaf;
641
642                                        if (vc == leaf->GetViewCell())
643                                        {
644                                                vcRays.push_back(ray);
645                                        }
646                                }
647                        }
648
649                        //bspLeaves[j]->Mail();
650                        char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i);
651
652                        Exporter *exporter = Exporter::GetExporter(s);
653                       
654                        exporter->SetWireframe();
655
656                        Material m;//= RandomMaterial();
657                        m.mDiffuseColor = RgbColor(0, 1, 0);
658                        exporter->SetForcedMaterial(m);
659
660                        if (vc->GetMesh())
661                                exporter->ExportViewCell(vc);
662                        else
663                        {
664                                PolygonContainer cell;
665                                // export view cell
666                                mBspTree->ConstructGeometry(vc, cell);
667                                exporter->ExportPolygons(cell);
668                                CLEAR_CONTAINER(cell);
669                        }
670
671                       
672                        Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize()
673                                  << ", piercing rays=" << (int)vcRays.size() << endl;
674
675                       
676                        // export rays piercing this view cell
677                        exporter->ExportRays(vcRays, 1000, RgbColor(0, 1, 0));
678       
679                        m.mDiffuseColor = RgbColor(1, 0, 0);
680                        exporter->SetForcedMaterial(m);
681
682                        ViewCellPvsMap::const_iterator it,
683                                it_end = vc->GetPvs().mEntries.end();
684
685                        // output PVS of view cell
686                        for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it)
687                        {
688                                Intersectable *intersect = (*it).first;
689                                if (!intersect->Mailed())
690                                {
691                                        Material m = RandomMaterial();
692                       
693                                        exporter->SetForcedMaterial(m);
694
695                                        exporter->ExportIntersectable(intersect);
696                                        intersect->Mail();
697                                }                       
698                        }
699                               
700                        DEL_PTR(exporter);
701                        cout << "finished" << endl;
702                }
703        }
704#endif
705}
706
707
708bool BspViewCellsManager::MergeBspLeafViewCells(BspLeaf *front, BspLeaf *back) const
709{
710        BspViewCell *viewCell =
711                dynamic_cast<BspViewCell *>(MergeViewCells(*front->GetViewCell(), *back->GetViewCell()));
712       
713        if (!viewCell)
714                return false;
715
716        //-- change pointer to view cells of all leaves associated with the previous view cells
717        BspViewCell *fVc = front->GetViewCell();
718        BspViewCell *bVc = back->GetViewCell();
719
720        vector<BspLeaf *> fLeaves = fVc->mBspLeaves;
721        vector<BspLeaf *> bLeaves = bVc->mBspLeaves;
722
723        vector<BspLeaf *>::const_iterator it;
724       
725        for (it = fLeaves.begin(); it != fLeaves.end(); ++ it)
726        {
727                (*it)->SetViewCell(viewCell);
728                viewCell->mBspLeaves.push_back(*it);
729        }
730        for (it = bLeaves.begin(); it != bLeaves.end(); ++ it)
731        {
732                (*it)->SetViewCell(viewCell);
733                viewCell->mBspLeaves.push_back(*it);
734        }
735       
736        DEL_PTR(fVc);
737        DEL_PTR(bVc);
738
739        return true;
740}
741
742bool BspViewCellsManager::ShouldMerge(BspLeaf *front, BspLeaf *back) const
743{
744        ViewCell *fvc = front->GetViewCell();
745        ViewCell *bvc = back->GetViewCell();
746
747        if ((fvc == mBspTree->GetRootCell()) || (bvc == mBspTree->GetRootCell()) || (fvc == bvc))
748                return false;
749
750        int fdiff = fvc->GetPvs().Diff(bvc->GetPvs());
751
752        if (fvc->GetPvs().GetSize() + fdiff < mMaxPvs)
753        {
754                if ((fvc->GetPvs().GetSize() < mMinPvs) ||     
755                        (bvc->GetPvs().GetSize() < mMinPvs) ||
756                        ((fdiff < mMinPvsDif) && (bvc->GetPvs().Diff(fvc->GetPvs()) < mMinPvsDif)))
757                {
758                        return true;
759                }
760        }
761       
762        return false;
763}
764
765void BspViewCellsManager::PrintStatistics(ostream &s) const
766{
767        ViewCellsStatistics vcStats;
768        mBspTree->EvaluateViewCellsStats(vcStats);
769        s << vcStats << endl;
770}
771
772/**********************************************************************/
773/*                   KdViewCellsManager implementation               */
774/**********************************************************************/
775
776KdViewCellsManager::KdViewCellsManager(KdTree *kdTree):
777ViewCellsManager(),
778mKdTree(kdTree),
779mKdPvsDepth(100)
780{
781   mRenderSimulator = new KdRenderSimulator(mKdTree);
782   InitRenderSimulator();
783}
784
785int KdViewCellsManager::Construct(const ObjectContainer &objects,
786                                                                  const VssRayContainer &rays,
787                                                                  AxisAlignedBox3 *sceneBbox)
788{
789        // if view cells already constructed
790        if (ViewCellsConstructed())
791                return 0;
792
793        Debug << "Constructing bsp view cells" << endl;
794       
795        mKdTree->Construct();
796
797        return 0;
798}
799
800bool KdViewCellsManager::ViewCellsConstructed() const
801{
802        return mKdTree->GetRoot() != NULL;
803}
804
805int KdViewCellsManager::PostProcess(const ObjectContainer &objects,
806                                                                        const VssRayContainer &rays)
807{
808        return 0;
809}
810
811void KdViewCellsManager::Visualize(const ObjectContainer &objects,
812                                                                   const VssRayContainer &sampleRays)
813{
814        if (!ViewCellsConstructed())
815                return;
816
817        const int pvsOut = min((int)objects.size(), 10);
818
819        int limit = min(mVisualizationSamples, (int)sampleRays.size());
820
821        VssRayContainer *rays = new VssRayContainer[pvsOut];
822
823        for  (int i = 0; i < limit; ++ i)
824        {
825          VssRay *ray = sampleRays[i];
826         
827          // check whether we can add this to the rays
828          for (int j = 0; j < pvsOut; j++)
829                {
830                  if (objects[j] == ray->mTerminationObject)
831                        {
832                          rays[j].push_back(ray);
833                        }
834                }
835        }
836       
837
838        bool exportRays = false;
839        if (exportRays) {
840          Exporter *exporter = NULL;
841                exporter = Exporter::GetExporter("sample-rays.x3d");
842                exporter->SetWireframe();
843                exporter->ExportKdTree(*mKdTree);
844               
845                for (i=0; i < pvsOut; i++)
846                        exporter->ExportRays(rays[i], RgbColor(1, 0, 0));
847                exporter->SetFilled();
848               
849                delete exporter;
850        }
851
852        for (int k=0; k < pvsOut; k++)
853        {
854                Intersectable *object = objects[k];
855                char s[64];     
856                sprintf(s, "sample-pvs%04d.x3d", k);
857
858                Exporter *exporter = Exporter::GetExporter(s);
859                exporter->SetWireframe();
860         
861        KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
862                Intersectable::NewMail();
863                       
864                // avoid adding the object to the list
865                object->Mail();
866                ObjectContainer visibleObjects;
867           
868                for (; i != object->mKdPvs.mEntries.end(); i++)
869                {
870                         KdNode *node = (*i).first;
871                         exporter->ExportBox(mKdTree->GetBox(node));
872                         mKdTree->CollectObjects(node, visibleObjects);
873                }
874
875                exporter->ExportRays(rays[k],  RgbColor(0, 1, 0));
876                exporter->SetFilled();
877                 
878                for (int j = 0; j < visibleObjects.size(); j++)
879                        exporter->ExportIntersectable(visibleObjects[j]);
880                 
881                Material m;
882                m.mDiffuseColor = RgbColor(1, 0, 0);
883                exporter->SetForcedMaterial(m);
884                exporter->ExportIntersectable(object);
885         
886                delete exporter;
887        }
888        DEL_PTR(rays);
889}
890
891int KdViewCellsManager::GetType() const
892{
893        return ViewCellsManager::KD;
894}
895
896
897
898KdNode *KdViewCellsManager::GetNodeForPvs(KdLeaf *leaf)
899{
900        KdNode *node = leaf;
901
902        while (node->mParent && node->mDepth > mKdPvsDepth)
903                node = node->mParent;
904        return node;
905}
906
907
908void KdViewCellsManager::PrintStatistics(ostream &s) const
909{
910}
911
912
913int
914KdViewCellsManager::CastLineSegment(const Vector3 &origin,
915                                                                        const Vector3 &termination,
916                                                                        ViewCellContainer &viewcells
917                                                                        )
918{
919
920  return 0;
921}
922
923/**********************************************************************/
924/*                   VspKdViewCellsManager implementation             */
925/**********************************************************************/
926
927VspKdViewCellsManager::VspKdViewCellsManager(VspKdTree *vspKdTree,
928                                                                                         int constructionSamples):
929ViewCellsManager(constructionSamples),
930mVspKdTree(vspKdTree)
931{
932   mRenderSimulator = new VspKdRenderSimulator(vspKdTree);
933   mVspKdTree->SetViewCellsManager(this);
934
935   InitRenderSimulator();
936}
937
938
939VspKdViewCellsManager::~VspKdViewCellsManager()
940{
941        ViewCellContainer vc;
942        mVspKdTree->CollectViewCells(vc);
943
944        CLEAR_CONTAINER(vc);
945}
946
947
948int VspKdViewCellsManager::Construct(const ObjectContainer &objects,
949                                                                         const VssRayContainer &rays,
950                                                                         AxisAlignedBox3 *sceneBbox)
951{
952        // if view cells already constructed
953        if (ViewCellsConstructed())
954                return 0;
955               
956        VssRayContainer sampleRays;
957
958        int limit = min (mConstructionSamples, (int)rays.size());
959
960    for (int i = 0; i < limit; ++ i)
961                sampleRays.push_back(rays[i]);
962
963        Debug << "constructing vsp kd tree using " << (int)sampleRays.size() << " samples" << endl;
964        mVspKdTree->Construct(rays, sceneBbox);
965
966        Debug << mVspKdTree->GetStatistics() << endl;
967
968        return 0;
969}
970
971bool VspKdViewCellsManager::ViewCellsConstructed() const
972{
973        return mVspKdTree->GetRoot() != NULL;
974}
975
976
977ViewCell *VspKdViewCellsManager::GenerateViewCell(Mesh *mesh) const
978{
979        return new VspKdViewCell(mesh);
980}
981
982int VspKdViewCellsManager::PostProcess(const ObjectContainer &objects,
983                                                                           const VssRayContainer &rays)
984{
985        if (!ViewCellsConstructed())
986                return 0;
987
988        return mVspKdTree->MergeLeaves();
989}
990
991void VspKdViewCellsManager::Visualize(const ObjectContainer &objects,
992                                                                          const VssRayContainer &sampleRays)
993{
994        if (!ViewCellsConstructed())
995                return;
996
997        bool exportRays = true;
998
999        //-- export tree leaves
1000        if (1)
1001        {
1002                Exporter *exporter = Exporter::GetExporter("vspkdtree.x3d");
1003                //exporter->SetWireframe();
1004                //exporter->ExportVspKdTree(*mVspKdTree, mVspKdTree->GetStatistics().maxPvsSize);
1005                exporter->ExportVspKdTree(*mVspKdTree);
1006
1007                if (1)
1008                        exporter->ExportGeometry(objects);
1009
1010                if (exportRays)
1011                  {
1012                        int raysSize = 2000;
1013                        float prob = raysSize / (float)sampleRays.size();
1014               
1015                        exporter->SetWireframe();
1016                       
1017                        VssRayContainer rays;
1018               
1019                        for (int i = 0; i < sampleRays.size(); ++ i)
1020                        {
1021                                if (RandomValue(0,1) < prob)
1022                                        rays.push_back(sampleRays[i]);
1023                        }
1024
1025                        exporter->ExportRays(rays, RgbColor(1, 0, 0));
1026                }
1027
1028                delete exporter;
1029        }
1030
1031        //-- export single leaves
1032        if (1)
1033        {
1034                vector<VspKdLeaf *> leafContainer;
1035                mVspKdTree->CollectLeaves(leafContainer);
1036
1037                for (int i = 0; i < 10; ++ i)
1038                {
1039                        char s[64];
1040                        sprintf(s, "vsp_leaves%04d.x3d", i);
1041                        Exporter *exporter = Exporter::GetExporter(s);
1042
1043                        // export geometry
1044                        VspKdLeaf *leaf = leafContainer[Random((int)leafContainer.size())];
1045                        AxisAlignedBox3 box = mVspKdTree->GetBBox(leaf);
1046
1047                        Material m;
1048                        m.mDiffuseColor = RgbColor(0, 1, 1);
1049                        exporter->SetForcedMaterial(m);
1050                        exporter->SetWireframe();
1051                        exporter->ExportBox(box);
1052
1053                        //-- export stored rays
1054                        VssRayContainer vssRays;
1055                        leaf->GetRays(vssRays);
1056
1057                        VssRayContainer rays;
1058                        VssRayContainer::const_iterator it, it_end = vssRays.end();
1059
1060                        for (it = vssRays.begin(); it != it_end; ++ it)
1061                                rays.push_back(*it);
1062                       
1063                        exporter->ExportRays(rays, RgbColor(1, 0, 0));
1064
1065                        //-- export stored PVS
1066                        ObjectContainer pvsObj;
1067                        leaf->ExtractPvs(pvsObj);
1068                               
1069                        exporter->ExportGeometry(pvsObj);
1070
1071                        delete exporter;
1072                }                       
1073        }
1074
1075        // evaluate maximal pvs
1076        ViewCellsStatistics vcStats;
1077        mVspKdTree->EvaluateViewCellsStats(vcStats);
1078       
1079        //-- export final view cells
1080        Exporter *exporter = Exporter::GetExporter("vspkdtree_merged.x3d");
1081        exporter->SetWireframe();
1082        //exporter->ExportVspKdTreeViewCells(*mVspKdTree, vcStats.maxPvs);
1083        exporter->ExportVspKdTreeViewCells(*mVspKdTree);
1084
1085        if (1)
1086        {
1087                exporter->SetFilled();
1088                exporter->ExportGeometry(objects);
1089        }
1090        if (exportRays)
1091        {
1092                int raysSize = 2000;
1093                float prob = raysSize / (float)sampleRays.size();
1094               
1095                exporter->SetWireframe();
1096                       
1097                VssRayContainer rays;
1098               
1099                for (int i = 0; i < sampleRays.size(); ++ i)
1100                {
1101                  if (RandomValue(0,1) < prob)
1102                        rays.push_back(sampleRays[i]);
1103                }
1104                exporter->ExportRays(rays, RgbColor(1, 0, 0));
1105        }
1106
1107        delete exporter;
1108}
1109
1110int VspKdViewCellsManager::GetType() const
1111{
1112        return VSP_KD;
1113}
1114
1115void VspKdViewCellsManager::PrintStatistics(ostream &s) const
1116{
1117        ViewCellsStatistics vcStats;
1118
1119        mVspKdTree->EvaluateViewCellsStats(vcStats);
1120        Debug << vcStats << endl;
1121}
1122
1123
1124int
1125VspKdViewCellsManager::CastLineSegment(const Vector3 &origin,
1126                                                                           const Vector3 &termination,
1127                                                                           ViewCellContainer &viewcells
1128                                                                           )
1129{
1130 
1131  return 0;
1132}
1133
1134/**********************************************************************/
1135/*                 VspBspViewCellsManager implementation              */
1136/**********************************************************************/
1137
1138VspBspViewCellsManager::VspBspViewCellsManager(VspBspTree *vspBspTree,
1139                                                                                           int constructionSamples):
1140ViewCellsManager(constructionSamples),
1141mVspBspTree(vspBspTree)
1142{
1143        mRenderSimulator = new VspBspRenderSimulator(vspBspTree);
1144        InitRenderSimulator();
1145}
1146
1147
1148
1149VspBspViewCellsManager::~VspBspViewCellsManager()
1150{
1151        ViewCellContainer vc;
1152        mVspBspTree->CollectViewCells(vc);
1153
1154        CLEAR_CONTAINER(vc);
1155}
1156
1157bool VspBspViewCellsManager::ViewCellsConstructed() const
1158{
1159        return mVspBspTree->GetRoot() != NULL;
1160}
1161
1162
1163ViewCell *VspBspViewCellsManager::GenerateViewCell(Mesh *mesh) const
1164{
1165        return new BspViewCell(mesh);
1166}
1167
1168int VspBspViewCellsManager::Construct(const ObjectContainer &objects,
1169                                                                          const VssRayContainer &rays,
1170                                                                          AxisAlignedBox3 *sceneBbox)
1171{
1172        // if view cells were already constructed
1173        if (ViewCellsConstructed())
1174                return 0;
1175
1176        Debug << "Constructing bsp view cells" << endl;
1177
1178        int sampleContributions = 0;
1179       
1180        VssRayContainer sampleRays;
1181
1182        int limit = min (mConstructionSamples, (int)rays.size());
1183
1184    for (int i = 0; i < limit; ++ i)
1185                sampleRays.push_back(rays[i]);
1186
1187        mVspBspTree->Construct(sampleRays);
1188       
1189        Debug << mVspBspTree->GetStatistics() << endl;
1190
1191        return sampleContributions;
1192}
1193
1194
1195int VspBspViewCellsManager::PostProcess(const ObjectContainer &objects,
1196                                                                                const VssRayContainer &rays)
1197{
1198        if (!ViewCellsConstructed())
1199        {
1200                Debug << "view cells not constructed" << endl;
1201                return 0;
1202        }
1203
1204
1205        //-- post processing of bsp view cells
1206    int vcSize = 0;
1207        int pvsSize = 0;
1208
1209       
1210        ViewCellsStatistics vcStats;
1211        mVspBspTree->EvaluateViewCellsStats(vcStats);
1212        Debug << "original view cell partition:\n" << vcStats << endl;
1213               
1214        if (1) // export view cells
1215        {
1216                cout << "exporting initial view cells (=leaves) ... ";
1217                Exporter *exporter = Exporter::GetExporter("view_cells.x3d");
1218       
1219                if (exporter)
1220                {
1221                        exporter->SetWireframe();
1222                        exporter->ExportBspViewCellPartition(*mVspBspTree, vcStats.maxPvs);
1223                               
1224                        if (0)
1225                        {
1226                                Material m;
1227                                m.mDiffuseColor = RgbColor(0, 1, 0);
1228                                exporter->SetForcedMaterial(m);
1229                                exporter->SetWireframe();
1230
1231                                exporter->ExportGeometry(objects);
1232                        }
1233
1234                        delete exporter;
1235                }
1236                cout << "finished" << endl;
1237        }
1238
1239        cout << "starting post processing using " << mPostProcessSamples << " samples ... ";
1240               
1241        long startTime = GetTime();
1242
1243
1244        // $$JB we do not have connectivity information from the ray in the moment
1245        // perhaps we could recast the rays or rember the cells traversed inside the
1246        // vssray (which would on other hand create some overhead)
1247        //-- merge or subdivide view cells
1248        int merged = 0;
1249#if 0
1250
1251        RayContainer::const_iterator rit, rit_end = rays.end();
1252        vector<Ray::BspIntersection>::const_iterator iit;
1253
1254        int limit = min((int)rays.size(), mPostProcessSamples);
1255
1256        for (int i = 0; i < limit; ++ i)
1257        { 
1258          VssRay *ray = rays[i];
1259         
1260          // traverse leaves stored in the rays and compare and merge consecutive
1261          // leaves (i.e., the neighbors in the tree)
1262          if (ray->bspIntersections.size() < 2)
1263                continue;
1264         
1265          iit = ray->bspIntersections.begin();
1266
1267                BspLeaf *previousLeaf = (*iit).mLeaf;
1268                ++ iit;
1269               
1270                for (; iit != ray->bspIntersections.end(); ++ iit)
1271                {
1272                        BspLeaf *leaf = (*iit).mLeaf;
1273
1274                        if (ShouldMerge(leaf, previousLeaf))
1275                        {                       
1276                                MergeVspBspLeafViewCells(leaf, previousLeaf);
1277
1278                                ++ merged;
1279                        }
1280               
1281                        previousLeaf = leaf;
1282                }
1283        }
1284#endif
1285        //-- stats and visualizations
1286        cout << "finished" << endl;
1287        cout << "merged " << merged << " view cells in "
1288                 << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl;
1289
1290
1291        return merged;
1292}
1293
1294int VspBspViewCellsManager::GetType() const
1295{
1296        return VSP_BSP;
1297}
1298
1299
1300void VspBspViewCellsManager::Visualize(const ObjectContainer &objects,
1301                                                                           const VssRayContainer &sampleRays)
1302{
1303        if (!ViewCellsConstructed())
1304                return;
1305
1306        //-- recount pvs
1307        ViewCellsStatistics vcStats;
1308        mVspBspTree->EvaluateViewCellsStats(vcStats);
1309
1310        if (1) // export view cells
1311        {
1312                cout << "exporting view cells after merge ... ";
1313                Exporter *exporter = Exporter::GetExporter("merged_view_cells.x3d");
1314
1315                if (exporter)
1316                {
1317                        exporter->ExportBspViewCellPartition(*mVspBspTree, vcStats.maxPvs);
1318                        delete exporter;
1319                }
1320               
1321                cout << "finished" << endl;
1322        }       
1323
1324        //-- visualization of the BSP splits
1325        bool exportSplits = false;
1326        environment->GetBoolValue("BspTree.Visualization.exportSplits", exportSplits);
1327       
1328        if (exportSplits)
1329        {
1330                cout << "exporting splits ... ";
1331                ExportSplits(objects, sampleRays);
1332                cout << "finished" << endl;
1333        }
1334
1335        ExportBspPvs(objects, sampleRays);
1336}
1337
1338
1339void VspBspViewCellsManager::ExportSplits(const ObjectContainer &objects,
1340                                                                                  const VssRayContainer &sampleRays)
1341{
1342        Exporter *exporter = Exporter::GetExporter("bsp_splits.x3d");
1343
1344        if (exporter)
1345        {       
1346                Material m;
1347                m.mDiffuseColor = RgbColor(1, 0, 0);
1348                exporter->SetForcedMaterial(m);
1349                exporter->SetWireframe();
1350               
1351                exporter->ExportBspSplits(*mVspBspTree, true);
1352
1353                // take forced material, else big scenes cannot be viewed
1354                m.mDiffuseColor = RgbColor(0, 1, 0);
1355                exporter->SetForcedMaterial(m);
1356                exporter->SetFilled();
1357
1358                exporter->ResetForcedMaterial();
1359               
1360                // export rays
1361                if (0)
1362                {
1363                  VssRayContainer outRays;
1364               
1365                        int raysSize = min((int)sampleRays.size(), mVisualizationSamples);
1366
1367                        for (int i = 0; i < raysSize; ++ i)
1368                        {
1369                                // only rays piercing geometry
1370                          outRays.push_back(sampleRays[i]);
1371                        }
1372                       
1373                        // export rays
1374                        exporter->ExportRays(outRays, RgbColor(1, 1, 0));
1375                }
1376
1377                if (0)
1378                        exporter->ExportGeometry(objects);
1379
1380                delete exporter;
1381        }
1382}
1383
1384void VspBspViewCellsManager::ExportBspPvs(const ObjectContainer &objects,
1385                                                                                  const VssRayContainer &sampleRays)
1386{
1387        const int leafOut = 10;
1388       
1389        ViewCell::NewMail();
1390
1391        //-- some rays for output
1392        const int raysOut = min((int)sampleRays.size(), mVisualizationSamples);
1393        cout << "visualization using " << mVisualizationSamples << " samples" << endl;
1394       
1395        if (1)
1396        {
1397                //-- some random view cells and rays for output
1398                vector<BspLeaf *> vspBspLeaves;
1399
1400                for (int i = 0; i < leafOut; ++ i)
1401                        vspBspLeaves.push_back(mVspBspTree->GetRandomLeaf());   
1402               
1403                for (int i = 0; i < (int)vspBspLeaves.size(); ++ i)
1404                {
1405                  VssRayContainer vcRays;
1406                  cout << "creating output for view cell " << i << " ... ";
1407
1408                  //$$JB
1409#if 0
1410                        // check whether we can add the current ray to the output rays
1411                        for (int k = 0; k < raysOut; ++ k)
1412                        {
1413                          VssRay *ray = sampleRays[k];
1414
1415                                for     (int j = 0; j < (int)ray->bspIntersections.size(); ++ j)
1416                                {
1417                                        BspLeaf *leaf = ray->bspIntersections[j].mLeaf;
1418
1419                                        if (vspBspLeaves[i]->GetViewCell() == leaf->GetViewCell())
1420                                        {
1421                                                vcRays.push_back(ray);
1422                                        }
1423                                }
1424                        }
1425#endif
1426
1427                        Intersectable::NewMail();
1428
1429                        BspViewCell *vc = dynamic_cast<BspViewCell *>
1430                                (vspBspLeaves[i]->GetViewCell());
1431
1432                        //bspLeaves[j]->Mail();
1433                        char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i);
1434
1435                        Exporter *exporter = Exporter::GetExporter(s);
1436                        exporter->SetFilled();
1437
1438                        ViewCellPvsMap::iterator it = vc->GetPvs().mEntries.begin();
1439
1440                        exporter->SetWireframe();
1441                        //exporter->SetFilled();
1442
1443                        Material m;//= RandomMaterial();
1444                        m.mDiffuseColor = RgbColor(0, 1, 0);
1445                        exporter->SetForcedMaterial(m);
1446
1447                        if (vc->GetMesh())
1448                                exporter->ExportViewCell(vc);
1449                        else
1450                        {
1451                                PolygonContainer vcGeom;
1452
1453                                // export view cell geometry
1454                                mVspBspTree->ConstructGeometry(vc, vcGeom);
1455                                exporter->ExportPolygons(vcGeom);
1456                                CLEAR_CONTAINER(vcGeom);
1457                        }
1458
1459                        Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize()
1460                                        << ", piercing rays=" << (int)vcRays.size() << endl;
1461
1462                        // export rays piercing this view cell
1463                        exporter->ExportRays(vcRays, RgbColor(1, 0, 0));
1464                        exporter->ExportRays(vspBspLeaves[i]->mVssRays, RgbColor(1, 1, 1));
1465                       
1466                        m.mDiffuseColor = RgbColor(0, 1, 1);
1467                        exporter->SetForcedMaterial(m);
1468
1469                        exporter->SetWireframe();
1470                        //exporter->SetFilled();
1471
1472                        // output PVS of view cell
1473                        for (; it != vc->GetPvs().mEntries.end(); ++ it)
1474                        {
1475                                Intersectable *intersect = (*it).first;
1476                                if (!intersect->Mailed())
1477                                {
1478                                        exporter->ExportIntersectable(intersect);
1479                                        intersect->Mail();
1480                                }                       
1481                        }
1482                               
1483                        // output rest of the objects
1484                        if (0)
1485                        {
1486                                Material m;//= RandomMaterial();
1487                                m.mDiffuseColor = RgbColor(0, 0, 1);
1488                                exporter->SetForcedMaterial(m);
1489
1490                                for (int j = 0; j < objects.size(); ++ j)
1491                                        if (!objects[j]->Mailed())
1492                                        {
1493                                                exporter->SetForcedMaterial(m);
1494                                                exporter->ExportIntersectable(objects[j]);
1495                                                objects[j]->Mail();
1496                                        }
1497                        }
1498                        DEL_PTR(exporter);
1499                        cout << "finished" << endl;
1500                }
1501        }
1502        else
1503        {
1504                ViewCellContainer viewCells;
1505
1506                mVspBspTree->CollectViewCells(viewCells);
1507                stable_sort(viewCells.begin(), viewCells.end(), vc_gt);
1508
1509                int limit = min(leafOut, (int)viewCells.size());
1510               
1511                for (int i = 0; i < limit; ++ i)
1512                {
1513                        cout << "creating output for view cell " << i << " ... ";
1514                        VssRayContainer vcRays;
1515            Intersectable::NewMail();
1516                        BspViewCell *vc = dynamic_cast<BspViewCell *>(viewCells[i]);
1517
1518                        cout << "creating output for view cell " << i << " ... ";
1519                        //$$ JB
1520#if 0
1521                        // check whether we can add the current ray to the output rays
1522                        for (int k = 0; k < raysOut; ++ k)
1523                        {
1524                          Ray *ray = sampleRays[k];
1525
1526                                for     (int j = 0; j < (int)ray->bspIntersections.size(); ++ j)
1527                                {
1528                                        BspLeaf *leaf = ray->bspIntersections[j].mLeaf;
1529
1530                                        if (vc == leaf->GetViewCell())
1531                                        {
1532                                                vcRays.push_back(ray);
1533                                        }
1534                                }
1535                        }
1536#endif
1537                        //bspLeaves[j]->Mail();
1538                        char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i);
1539
1540                        Exporter *exporter = Exporter::GetExporter(s);
1541                       
1542                        exporter->SetWireframe();
1543
1544                        Material m;//= RandomMaterial();
1545                        m.mDiffuseColor = RgbColor(0, 1, 0);
1546                        exporter->SetForcedMaterial(m);
1547
1548                        if (vc->GetMesh())
1549                                exporter->ExportViewCell(vc);
1550                        else
1551                        {
1552                                PolygonContainer vcGeom;
1553                                // export view cell
1554                                mVspBspTree->ConstructGeometry(vc, vcGeom);
1555                                exporter->ExportPolygons(vcGeom);
1556                                CLEAR_CONTAINER(vcGeom);
1557                        }
1558
1559                       
1560                        Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize()
1561                                        << ", piercing rays=" << (int)vcRays.size() << endl;
1562
1563                       
1564                        // export rays piercing this view cell
1565                        exporter->ExportRays(vcRays, RgbColor(0, 1, 0));
1566       
1567                        m.mDiffuseColor = RgbColor(1, 0, 0);
1568                        exporter->SetForcedMaterial(m);
1569
1570                        ViewCellPvsMap::const_iterator it,
1571                                it_end = vc->GetPvs().mEntries.end();
1572
1573                        // output PVS of view cell
1574                        for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it)
1575                        {
1576                                Intersectable *intersect = (*it).first;
1577
1578                                if (!intersect->Mailed())
1579                                {
1580                                        Material m = RandomMaterial();
1581                       
1582                                        exporter->SetForcedMaterial(m);
1583
1584                                        exporter->ExportIntersectable(intersect);
1585                                        intersect->Mail();
1586                                }                       
1587                        }
1588                               
1589                        DEL_PTR(exporter);
1590                        cout << "finished" << endl;
1591                }
1592        }
1593}
1594
1595
1596void VspBspViewCellsManager::PrintStatistics(ostream &s) const
1597{
1598        ViewCellsStatistics vcStats;
1599        mVspBspTree->EvaluateViewCellsStats(vcStats);
1600        s << vcStats << endl;
1601}
1602
1603bool VspBspViewCellsManager::MergeVspBspLeafViewCells(BspLeaf *front,
1604                                                                                                          BspLeaf *back) const
1605{
1606        BspViewCell *viewCell =
1607                dynamic_cast<BspViewCell *>(MergeViewCells(*front->GetViewCell(),
1608                                                                                                   *back->GetViewCell()));
1609       
1610        if (!viewCell)
1611                return false;
1612
1613        // change view cells of all leaves associated with the
1614        // previous view cells
1615
1616        BspViewCell *fVc = front->GetViewCell();
1617        BspViewCell *bVc = back->GetViewCell();
1618
1619        vector<BspLeaf *> fLeaves = fVc->mBspLeaves;
1620        vector<BspLeaf *> bLeaves = bVc->mBspLeaves;
1621
1622        vector<BspLeaf *>::const_iterator it;
1623       
1624        for (it = fLeaves.begin(); it != fLeaves.end(); ++ it)
1625        {
1626                (*it)->SetViewCell(viewCell);
1627                viewCell->mBspLeaves.push_back(*it);
1628        }
1629        for (it = bLeaves.begin(); it != bLeaves.end(); ++ it)
1630        {
1631                (*it)->SetViewCell(viewCell);
1632                viewCell->mBspLeaves.push_back(*it);
1633        }
1634       
1635        DEL_PTR(fVc);
1636        DEL_PTR(bVc);
1637
1638        return true;
1639}
1640
1641bool VspBspViewCellsManager::ShouldMerge(BspLeaf *front, BspLeaf *back) const
1642{
1643        ViewCell *fvc = front->GetViewCell();
1644        ViewCell *bvc = back->GetViewCell();
1645
1646        if ((fvc == mVspBspTree->GetRootCell()) ||
1647                (bvc == mVspBspTree->GetRootCell()) ||
1648                (fvc == bvc))
1649                return false;
1650
1651        const int fdiff = fvc->GetPvs().Diff(bvc->GetPvs());
1652
1653        if (fvc->GetPvs().GetSize() + fdiff < mMaxPvs)
1654        {
1655                if ((fvc->GetPvs().GetSize() < mMinPvs) ||     
1656                        (bvc->GetPvs().GetSize() < mMinPvs) ||
1657                        ((fdiff < mMinPvsDif) && (bvc->GetPvs().Diff(fvc->GetPvs()) < mMinPvsDif)))
1658                {
1659                        return true;
1660                }
1661        }
1662       
1663        return false;
1664}
1665
1666
1667int
1668VspBspViewCellsManager::CastLineSegment(const Vector3 &origin,
1669                                                                                const Vector3 &termination,
1670                                                                                ViewCellContainer &viewcells
1671                                                                                )
1672{
1673  return mVspBspTree->CastLineSegment(origin, termination, viewcells);
1674}
Note: See TracBrowser for help on using the repository browser.