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

Revision 468, 42.7 KB checked in by mattausch, 19 years ago (diff)

updated rendersimulator

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