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

Revision 467, 41.3 KB checked in by bittner, 19 years ago (diff)

rsstree statistics

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