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

Revision 495, 54.9 KB checked in by mattausch, 19 years ago (diff)

fixed bug in tree collapse

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